/*
* $Id: JGraphSQLQueryPane.java,v 1.2 2007/08/18 10:20:11 david Exp $
*
* Copyright (c) 2001-2005, Gaudenz Alder
*
* See LICENSE file in distribution for licensing details of this source file
*/
package com.jgraph.example.adapter;
import java.awt.BorderLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import org.jgraph.JGraph;
import org.jgraph.graph.ConnectionSet;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.GraphConstants;
import org.jgraph.graph.ParentMap;
/**
* A quick and dirty implementation of a query pane. This allows to enter
* keywords to search for property values of entities. Results may then be
* dragged from the result list to the diagram. If the cells are already in the
* diagram then they should be moved and selected, otherwise a new cell should
* be created and inserted into the graph model.
*/
public class JGraphSQLQueryPane extends JPanel {
public JGraphSQLQueryPane(final JGraphAdapterExample adapter,
final JGraph graph) {
super(new BorderLayout());
final JGraphSQLBusinessModel businessModel = (JGraphSQLBusinessModel) graph
.getModel();
final JTextField input = new JTextField("[Type Query + Press Enter]");
add(input, BorderLayout.NORTH);
final DefaultTreeModel treeModel = new DefaultTreeModel(
new DefaultMutableTreeNode("root"));
final JTree tree = new JTree(treeModel);
tree.setRootVisible(false);
tree.setAutoscrolls(true);
tree.setShowsRootHandles(true);
tree.setEditable(false);
add(new JScrollPane(tree), BorderLayout.CENTER);
// Update the result set on ENTER
input.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
String query = input.getText();
if (businessModel != null) {
// TODO: Move into a method
try {
if (query.startsWith(":")) {
query = query.substring(1);
((JGraphSQLBackend) businessModel.getBackend())
.query(query);
} else if (query.startsWith(">")) {
query = query.substring(1);
((JGraphSQLBackend) businessModel.getBackend())
.update(query);
} else {
DefaultMutableTreeNode root = new DefaultMutableTreeNode(
"root");
treeModel.setRoot(root);
Iterator it = businessModel.findVertices(query,
null).iterator();
while (it.hasNext()) {
Object source = it.next();
DefaultMutableTreeNode node = new DefaultMutableTreeNode(
source);
treeModel.insertNodeInto(node, root,
treeModel.getChildCount(root));
Iterator it2 = businessModel.findEdges("",
null, source, null, false)
.iterator();
while (it2.hasNext()) {
// Create the tree node for the edge
treeModel.insertNodeInto(
new DefaultMutableTreeNode(it2
.next()), node,
treeModel.getChildCount(node));
}
}
tree.expandPath(new TreePath(root));
}
} catch (Exception e1) {
e1.printStackTrace();
}
} else {
println("No backend found.");
}
}
}
});
// React to double clicks
tree.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (tree.isSelectionEmpty())
return;
// Result objects are wrapped in treenodes
DefaultGraphCell cell = (DefaultGraphCell) businessModel
.getValue(tree.getSelectionPath()
.getLastPathComponent());
if (cell != null) {
if (e.getClickCount() == 2) {
if (graph != null
&& graph.getModel() instanceof JGraphAdapterModel) {
JGraphAdapterModel bm = (JGraphAdapterModel) graph
.getModel();
// Check if already in model
Object modelCell = bm.getMapping(cell
.getUserObject());
if (modelCell == null) {
// TODO: Move into a method
Map nested = new Hashtable();
println("Inserting " + cell.getClass());
List newCells = new ArrayList(3);
newCells.add(cell);
// TODO: Parent is only used if already in
// model.
ParentMap pm = new ParentMap();
Object parent = ((JGraphSQLBackend) bm
.getBackend()).getParent(cell
.getUserObject());
if (parent != null) {
Object parentCell = bm.getMapping(parent);
if (parentCell != null)
pm.addEntry(cell, parentCell);
}
// Source and target are used or inserted.
ConnectionSet cs = new ConnectionSet();
if (bm.isEdge(cell)) {
// Create source vertex if required
Object source = (((JGraphSQLBackend) bm
.getBackend()).getSource(cell
.getUserObject()));
if (source != null) {
Object sourceCell = bm
.getMapping(source);
if (sourceCell == null
&& source instanceof JGraphSQLEntity) {
try {
sourceCell = ((JGraphSQLBackend) bm
.getBackend())
.createCell(
bm,
(JGraphSQLEntity) source);
nested
.put(
sourceCell,
adapter
.createCellAttributes(new Point2D.Double(
10,
10)));
} catch (SQLException e1) {
// TODO Auto-generated catch
// block
e1.printStackTrace();
}
newCells.add(sourceCell);
}
cs.connect(cell, bm.getChild(
sourceCell, 0), true);
}
// Create target vertex if required
Object target = (((JGraphSQLBackend) bm
.getBackend()).getTarget(cell
.getUserObject()));
if (target != null) {
Object targetCell = bm
.getMapping(target);
if (targetCell == null
&& target instanceof JGraphSQLEntity) {
try {
targetCell = ((JGraphSQLBackend) bm
.getBackend())
.createCell(
bm,
(JGraphSQLEntity) target);
nested
.put(
targetCell,
adapter
.createCellAttributes(new Point2D.Double(
100,
100)));
} catch (SQLException e1) {
// TODO Auto-generated catch
// block
e1.printStackTrace();
}
newCells.add(targetCell);
}
cs.connect(cell, bm.getChild(
targetCell, 0), false);
}
nested.put(cell, adapter
.createEdgeAttributes());
} else {
nested
.put(
cell,
adapter
.createCellAttributes(new Point2D.Double(
10, 10)));
}
// TODO: For all new cells
GraphConstants.setResize(cell.getAttributes(),
true);
println("nested: " + nested);
// Inserts the double clicked node into the
// model
graph.getGraphLayoutCache().insert(
newCells.toArray(), nested, cs, pm);
} else {
// TODO: Move into a method
println("Updating userobject");
// TODO: Maybe add tcn to entity?
JGraphBusinessObject bo = (JGraphBusinessObject) businessModel
.getValue(modelCell);
JGraphBusinessObject other = (JGraphBusinessObject) cell
.getUserObject();
if (bo != other) {
bo.getProperties().clear();
bo.getProperties().putAll(
other.getProperties());
bm.cellsChanged(new Object[] { cell });
}
if (graph.getGraphLayoutCache().getMapping(
modelCell, false) == null) {
graph.getGraphLayoutCache().setVisible(
new Object[] { modelCell }, null);
} else {
ParentMap pm = new ParentMap();
Object parent = bm
.getMapping(((JGraphSQLBackend) bm
.getBackend())
.getParent(cell
.getUserObject()));
if (parent != null) {
pm.addEntry(modelCell, parent);
graph.getGraphLayoutCache().edit(null,
null, pm, null);
}
// TODO: Update source and target?
}
graph.setSelectionCell(modelCell);
}
}
} else if (cell.getUserObject() instanceof JGraphBusinessObject
&& SwingUtilities.isRightMouseButton(e)) { // eg. right
// click
println("Properties: "
+ ((JGraphBusinessObject) cell.getUserObject())
.getProperties());
}
}
}
});
}
protected static void println(String msg) {
JGraphAdapterExample.println(msg);
}
}