/* * $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); } }