Files
secondo/Javagui/viewer/hoese/QueryResult.java
2026-01-23 17:03:45 +08:00

583 lines
15 KiB
Java

//This file is part of SECONDO.
//Copyright (C) 2004, University in Hagen, Department of Computer Science,
//Database Systems for New Applications.
//SECONDO is free software; you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation; either version 2 of the License, or
//(at your option) any later version.
//SECONDO is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//You should have received a copy of the GNU General Public License
//along with SECONDO; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package viewer.hoese;
import gui.SecondoObject;
import gui.idmanager.ID;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.JList;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import sj.lang.ListExpr;
import tools.Reporter;
import viewer.HoeseViewer;
import viewer.hoese.algebras.continuousupdate.RunnableUpdate;
/**
* This class enhances JList. A list is generated dependant to the types given
* back and formatted by the query.
*/
public class QueryResult extends JList {
/** The query command */
public String command;
/** The result given back by the query command as a Listexpr */
public ListExpr LEResult;
/** A list of the ggraphic objects of this query */
private Vector GraphObjects;
/** No. of tuples, no. of attributes of a tuple */
private int TupelCount, AttrCount;
/** FileChosser for storing a file **/
private JFileChooser filechooser = new JFileChooser();
/** The id of the stored Secondo-Object */
private ID id;
/** Last element of LEResult; */
private ListExpr lastElement;
/** return the Id for this QueryResult **/
public ID getId() {
return id;
}
/** the QueryRepresentations for this QueryResult */
// private ViewConfig myViewConfig = null;
private Vector ViewConfigs = new Vector(2);
/**
* stores the interval where Time dependent objects are defined
**/
private Interval interval;
private Layer resultLayer;
private void setLastElement() {
ListExpr last = LEResult.second();
while (!last.endOfList()) {
last = last.rest();
}
lastElement = last;
}
/**
* Add tuples which are received by a continuous update
*
* @param hoese
* The Viewer this QR belongs to
* @param tuple
* The Tuple which was received
* @param modelLimit
* The maximum Size of the used ListModel
*/
public void addTuples(HoeseViewer hoese, ListExpr tuple, Integer tupleLimit) {
// For performance reasons, save the last element of the nested-list
if (lastElement == null) {
setLastElement();
}
// Create a temporary QueryResult
QueryResult tmp_qr = new QueryResult(new SecondoObject("dummy",
LEResult));
// Loop through the provided nested List, and add all tuples
while (tuple != null & !tuple.isEmpty()) {
ListExpr current = tuple.first();
tuple = tuple.rest();
lastElement = ListExpr.append(lastElement, current);
TupelCount++;
tmp_qr.addEntry("---------");
LEUtils.analyse(LEResult.first().toString(), 0, 0,
LEResult.first(), ListExpr.oneElemList(current), tmp_qr);
}
// Reduce the NestedList
if (tupleLimit > 0) {
ListExpr tuples = LEResult.second();
for (int i = tuples.listLength(); i > tupleLimit; i--) {
tuples = tuples.rest();
TupelCount--;
}
LEResult.second().setValueTo(tuples);
}
// Update the ListModel on the GUI thread
SwingUtilities.invokeLater(new RunnableUpdate(this, tmp_qr, hoese,
tupleLimit));
}
/**
* Creates a QueryResult with a command and a result of a query
*
* @param String
* acommand
* @param ListExpr
* aLEResult
*/
public QueryResult(SecondoObject so) {
super();
String acommand = so.getName();
ListExpr aLEResult = so.toListExpr();
this.id = so.getID();
interval = null;
setFont(new Font("Monospaced", Font.PLAIN, 12));
// processing double clicks
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1
&& e.getClickCount() == 1) {
int index = QueryResult.this.locationToIndex(e.getPoint());
if (index < 0) {
return;
}
Object o = QueryResult.this.getModel().getElementAt(index);
if (o != null && (o instanceof Writable)) {
if (filechooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
File F = filechooser.getSelectedFile();
if (F.exists()) {
if (Reporter.showQuestion("File " + F
+ " already exists,\n Overwrite It?") != Reporter.YES) {
return;
}
}
boolean ok = false;
try {
ok = ((Writable) o).writeTo(F);
} catch (Exception e4) {
Reporter.debug(e4);
}
if (ok) {
Reporter.showInfo("File " + F
+ " has been written");
} else {
Reporter.showError("error in writing file " + F);
}
}
}
}
if (e.getClickCount() != 2) {
return;
}
Object o = QueryResult.this.getSelectedValue();
if ((o instanceof DsplBase)
&& (((DsplBase) o).getFrame() != null)) {
((DsplBase) o).getFrame().select(o);
((DsplBase) o).getFrame().show(true);
}
if ((o instanceof ExternDisplay)) {
ExternDisplay BG = (ExternDisplay) o;
if (!BG.isExternDisplayed()) {
BG.displayExtern();
}
}
}
});
setModel(new DefaultListModel());
setCellRenderer(new QueryRenderer());
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
setBackground(Color.lightGray);
command = acommand;
LEResult = aLEResult;
TupelCount = LEResult.second().listLength();
if (LEResult.first().isAtom()) {
AttrCount = 0;
} else {
try {
AttrCount = LEResult.first().second().second().listLength();
} catch (Exception e) {
AttrCount = 0;
}
}
GraphObjects = new Vector(50);
}
/**
* Creates a QueryResult for Collections with a command and a result of a
* query
*
* @param String
* acommand
* @param ListExpr
* aLEResult
* @param boolean isColl
*/
public QueryResult(SecondoObject so, boolean isColl) {
super();
interval = null;
setFont(new Font("Monospaced", Font.PLAIN, 12));
String acommand = so.getName();
ListExpr aLEResult = so.toListExpr();
this.id = so.getID();
// processing double clicks
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1
&& e.getClickCount() == 1) {
int index = QueryResult.this.locationToIndex(e.getPoint());
if (index < 0) {
return;
}
Object o = QueryResult.this.getModel().getElementAt(index);
if (o != null && (o instanceof Writable)) {
if (filechooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
File F = filechooser.getSelectedFile();
if (F.exists()) {
if (Reporter.showQuestion("File " + F
+ " already exists,\n Overwrite It?") != Reporter.YES) {
return;
}
}
boolean ok = false;
try {
ok = ((Writable) o).writeTo(F);
} catch (Exception e4) {
Reporter.debug(e4);
}
if (ok) {
Reporter.showInfo("File " + F
+ " has been written");
} else {
Reporter.showError("error in writing file " + F);
}
}
}
}
if (e.getClickCount() != 2) {
return;
}
Object o = QueryResult.this.getSelectedValue();
if ((o instanceof DsplBase)
&& (((DsplBase) o).getFrame() != null)) {
((DsplBase) o).getFrame().select(o);
((DsplBase) o).getFrame().show(true);
}
if ((o instanceof ExternDisplay)) {
ExternDisplay BG = (ExternDisplay) o;
if (!BG.isExternDisplayed()) {
BG.displayExtern();
}
}
}
});
setModel(new DefaultListModel());
setCellRenderer(new QueryRenderer());
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
setBackground(Color.lightGray);
command = acommand;
LEResult = aLEResult;
GraphObjects = new Vector(50);
}
public boolean hasId(ID id) {
return this.id.equals(id);
}
/** get the ViewConfigs for this query */
public ViewConfig[] getViewConfigs() {
ViewConfig[] Cfgs = new ViewConfig[ViewConfigs.size()];
for (int i = 0; i < Cfgs.length; i++)
Cfgs[i] = (ViewConfig) ViewConfigs.get(i);
return Cfgs;
}
/** get the ViewConfig with specific index */
public ViewConfig getViewConfigAt(int index) {
if (index < 0 || index >= ViewConfigs.size())
return null;
else
return (ViewConfig) ViewConfigs.get(index);
}
/** set the ViewConfig for this query */
public void addViewConfig(ViewConfig VCfg) {
ViewConfigs.add(VCfg);
}
/**
* get the Pos of the ViewConfig with specific AttrName if not exists a
* ViewConfig with AttrName -1 is returned
*/
public int getViewConfigIndex(String AttrName) {
int pos = -1;
boolean found = false;
for (int i = 0; i < ViewConfigs.size() && !found; i++)
if (((ViewConfig) ViewConfigs.get(i)).AttrName.equals(AttrName)) {
pos = i;
found = true;
}
return pos;
}
/**
*
* @return The ListExpr of the picked (selected) list-entry
*/
public ListExpr getPick() {
if (AttrCount == 0) {
return LEResult;
}
int selind = getSelectedIndex();
int TupelNr = (selind / (AttrCount + 1));
int AttrNr = (selind % (AttrCount + 1));
if (AttrNr == AttrCount)
return null; // Separator
ListExpr TupelList = LEResult.second();
for (int i = 0; i < TupelNr; i++)
TupelList = TupelList.rest();
ListExpr AttrList = TupelList.first();
for (int i = 0; i < AttrNr; i++)
AttrList = AttrList.rest();
ListExpr TypeList = LEResult.first().second().second();
for (int i = 0; i < AttrNr; i++)
TypeList = TypeList.rest();
return ListExpr
.twoElemList(TypeList.first().second(), AttrList.first());
}
/**
*
* @return graphical objects of this query-result
*/
public Vector getGraphObjects() {
return GraphObjects;
}
/**
* Adds an object to the end of the result list
*
* @param entry
* The entry object
*/
public void addEntry(Object entry) {
if (entry != null) {
if (entry instanceof DsplBase) {
if (entry instanceof DsplGraph) {
GraphObjects.add(entry);
}
if (((DsplBase) entry).getFrame() != null) {
((DsplBase) entry).getFrame().addObject(entry);
}
}
}
((DefaultListModel) getModel()).addElement(entry);
}
/**
* Adds a ListModel to the end of the result list
*
* @param entries
* Collection
*/
public void addEntries(ListModel entries) {
if (entries.getSize() == 0) {
return;
}
for (int i = 0; i < entries.getSize(); i++) {
Object entry = entries.getElementAt(i);
if (entry != null) {
if (entry instanceof DsplBase) {
if (entry instanceof DsplGraph) {
GraphObjects.add(entry);
}
if (((DsplBase) entry).getFrame() != null) {
((DsplBase) entry).getFrame().addObject(entry);
}
}
}
((DefaultListModel) getModel()).addElement(entry);
}
}
/**
* Removes entries from the used models to retain the maximum size Entries
* will be removed from the front, it maxSize is greater than zero
*
* @param maxSize
* Maximum Size of the Model
* @param hoese
* Hoese Viewer
*/
public void reduceModels(Integer tupleLimit, HoeseViewer hoese) {
DefaultListModel model = ((DefaultListModel) getModel());
while (tupleLimit > 0 && model.size() > (tupleLimit * (AttrCount + 1))) {
for (int i = 0; i < AttrCount + 1; i++) {
Object o = model.remove(0);
if (o instanceof DsplGraph) {
GraphObjects.remove(o);
resultLayer.removeGO((DsplGraph)o);
}
}
}
}
/**
* search the given String in this list and returns the index, the search is
* started with offset and go to the end of the list. if the given string is
* not containing between offset and end -1 is returned
*/
public int find(String S, boolean CaseSensitiv, int Offset) {
ListModel LM = getModel();
if (LM == null)
return -1;
String UCS = S.toUpperCase();
boolean found = false;
int pos = -1;
for (int i = Offset; i < LM.getSize() && !found; i++) {
if (CaseSensitiv && LM.getElementAt(i).toString().indexOf(S) >= 0) {
pos = i;
found = true;
}
if (!CaseSensitiv
&& LM.getElementAt(i).toString().toUpperCase().indexOf(UCS) >= 0) {
pos = i;
found = true;
}
}
return pos;
}
public boolean equals(Object o) {
if (!(o instanceof QueryResult))
return false;
else {
QueryResult qr = (QueryResult) o;
return this.id == qr.id;
}
}
/**
* return the command
*/
public String getCommand() {
return command;
}
/**
* Sets the command
**/
public void setCommand(String command) {
this.command = command;
}
/** return the ListExpr */
public ListExpr getListExpr() {
return LEResult;
}
/**
* computes the TimeBounds from the contained objects.
**/
public void computeTimeBounds() {
ListModel listModel = getModel();
int size = listModel.getSize();
this.interval = null;
for (int i = 0; i < size; i++) {
Object o = listModel.getElementAt(i);
if (o instanceof Timed) {
Interval oInterval = ((Timed) o).getBoundingInterval();
if (oInterval != null) {
if (this.interval == null) {
this.interval = oInterval.copy();
} else {
this.interval.unionInternal(oInterval);
}
}
}
}
}
/**
* Returns the interval containing all definition times of object instances
* of Timed. If no such time exist, the result is null.
**/
public Interval getBoundingInterval() {
return interval;
}
/**
*
* @return The command of the query as string representation for the query
* combobox
*/
public String toString() {
return command;
}
/**
* A class for special rendering of datatypes in the list
*/
private class QueryRenderer extends DefaultListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
// if (value instanceof DsplGraph)
// setIcon(new ImageIcon("images/labdlg.gif"));
setForeground(Color.BLACK);
if ((value instanceof DsplGraph) && (value instanceof Timed))
setForeground(Color.magenta);
else if (value instanceof DsplGraph)
setForeground(Color.red);
else if (value instanceof Timed)
setForeground(Color.blue);
else if (value instanceof DsplBase)
setForeground(new Color(0, 100, 0));
if (value instanceof DsplBase)
if (!((DsplBase) value).getVisible())
setForeground(Color.gray);
if (value instanceof ExternDisplay) {
setForeground(new Color(255, 0, 0));
}
return this;
}
}
public void setResultLayer(Layer lay) {
resultLayer = lay;
}
public Layer getResultLayer() {
return resultLayer;
}
}