001: import java.awt.*; 002: import java.awt.geom.*; 003: import java.awt.event.*; 004: import javax.swing.*; 005: import javax.swing.event.*; 006: 007: /** 008: A panel to draw a graph 009: */ 010: public class GraphPanel extends JPanel 011: { 012: /** 013: Constructs a graph. 014: @param aToolBar the tool bar with the node and edge tools 015: @param aGraph the graph to be displayed and edited 016: */ 017: public GraphPanel(ToolBar aToolBar, Graph aGraph) 018: { 019: toolBar = aToolBar; 020: graph = aGraph; 021: setBackground(Color.WHITE); 022: 023: addMouseListener(new 024: MouseAdapter() 025: { 026: public void mousePressed(MouseEvent event) 027: { 028: Point2D mousePoint = event.getPoint(); 029: Node n = graph.findNode(mousePoint); 030: Edge e = graph.findEdge(mousePoint); 031: Object tool = toolBar.getSelectedTool(); 032: if (tool == null) // select 033: { 034: if (e != null) 035: { 036: selected = e; 037: } 038: else if (n != null) 039: { 040: selected = n; 041: dragStartPoint = mousePoint; 042: dragStartBounds = n.getBounds(); 043: } 044: else 045: { 046: selected = null; 047: } 048: } 049: else if (tool instanceof Node) 050: { 051: Node prototype = (Node) tool; 052: Node newNode = (Node) prototype.clone(); 053: boolean added = graph.add(newNode, mousePoint); 054: if (added) 055: { 056: selected = newNode; 057: dragStartPoint = mousePoint; 058: dragStartBounds = newNode.getBounds(); 059: } 060: else if (n != null) 061: { 062: selected = n; 063: dragStartPoint = mousePoint; 064: dragStartBounds = n.getBounds(); 065: } 066: } 067: else if (tool instanceof Edge) 068: { 069: if (n != null) rubberBandStart = mousePoint; 070: } 071: lastMousePoint = mousePoint; 072: repaint(); 073: } 074: 075: public void mouseReleased(MouseEvent event) 076: { 077: Object tool = toolBar.getSelectedTool(); 078: if (rubberBandStart != null) 079: { 080: Point2D mousePoint = event.getPoint(); 081: Edge prototype = (Edge) tool; 082: Edge newEdge = (Edge) prototype.clone(); 083: if (graph.connect(newEdge, 084: rubberBandStart, mousePoint)) 085: selected = newEdge; 086: } 087: 088: revalidate(); 089: repaint(); 090: 091: lastMousePoint = null; 092: dragStartBounds = null; 093: rubberBandStart = null; 094: } 095: }); 096: 097: addMouseMotionListener(new 098: MouseMotionAdapter() 099: { 100: public void mouseDragged(MouseEvent event) 101: { 102: Point2D mousePoint = event.getPoint(); 103: if (dragStartBounds != null) 104: { 105: if (selected instanceof Node) 106: { 107: Node n = (Node) selected; 108: Rectangle2D bounds = n.getBounds(); 109: n.translate( 110: dragStartBounds.getX() - bounds.getX() 111: + mousePoint.getX() - dragStartPoint.getX(), 112: dragStartBounds.getY() - bounds.getY() 113: + mousePoint.getY() - dragStartPoint.getY()); 114: } 115: } 116: lastMousePoint = mousePoint; 117: repaint(); 118: } 119: }); 120: } 121: 122: public void paintComponent(Graphics g) 123: { 124: super.paintComponent(g); 125: Graphics2D g2 = (Graphics2D) g; 126: Rectangle2D bounds = getBounds(); 127: Rectangle2D graphBounds = graph.getBounds(g2); 128: graph.draw(g2); 129: 130: if (selected instanceof Node) 131: { 132: Rectangle2D grabberBounds = ((Node) selected).getBounds(); 133: drawGrabber(g2, grabberBounds.getMinX(), grabberBounds.getMinY()); 134: drawGrabber(g2, grabberBounds.getMinX(), grabberBounds.getMaxY()); 135: drawGrabber(g2, grabberBounds.getMaxX(), grabberBounds.getMinY()); 136: drawGrabber(g2, grabberBounds.getMaxX(), grabberBounds.getMaxY()); 137: } 138: 139: if (selected instanceof Edge) 140: { 141: Line2D line = ((Edge) selected).getConnectionPoints(); 142: drawGrabber(g2, line.getX1(), line.getY1()); 143: drawGrabber(g2, line.getX2(), line.getY2()); 144: } 145: 146: if (rubberBandStart != null) 147: { 148: Color oldColor = g2.getColor(); 149: g2.setColor(PURPLE); 150: g2.draw(new Line2D.Double(rubberBandStart, lastMousePoint)); 151: g2.setColor(oldColor); 152: } 153: } 154: 155: /** 156: Removes the selected node or edge. 157: */ 158: public void removeSelected() 159: { 160: if (selected instanceof Node) 161: { 162: graph.removeNode((Node) selected); 163: } 164: else if (selected instanceof Edge) 165: { 166: graph.removeEdge((Edge) selected); 167: } 168: selected = null; 169: repaint(); 170: } 171: 172: /** 173: Edits the properties of the selected graph element. 174: */ 175: public void editSelected() 176: { 177: PropertySheet sheet = new PropertySheet(selected); 178: sheet.addChangeListener(new 179: ChangeListener() 180: { 181: public void stateChanged(ChangeEvent event) 182: { 183: repaint(); 184: } 185: }); 186: JOptionPane.showMessageDialog(null, 187: sheet, 188: "Properties", 189: JOptionPane.QUESTION_MESSAGE); 190: } 191: 192: /** 193: Draws a single "grabber", a filled square 194: @param g2 the graphics context 195: @param x the x coordinate of the center of the grabber 196: @param y the y coordinate of the center of the grabber 197: */ 198: public static void drawGrabber(Graphics2D g2, double x, double y) 199: { 200: final int SIZE = 5; 201: Color oldColor = g2.getColor(); 202: g2.setColor(PURPLE); 203: g2.fill(new Rectangle2D.Double(x - SIZE / 2, 204: y - SIZE / 2, SIZE, SIZE)); 205: g2.setColor(oldColor); 206: } 207: 208: public Dimension getPreferredSize() 209: { 210: Rectangle2D bounds 211: = graph.getBounds((Graphics2D) getGraphics()); 212: return new Dimension( 213: (int) bounds.getMaxX(), 214: (int) bounds.getMaxY()); 215: } 216: 217: private Graph graph; 218: private ToolBar toolBar; 219: private Point2D lastMousePoint; 220: private Point2D rubberBandStart; 221: private Point2D dragStartPoint; 222: private Rectangle2D dragStartBounds; 223: private Object selected; 224: private static final Color PURPLE = new Color(0.7f, 0.4f, 0.7f); 225: }