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 panel.
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: validate();
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: /**
157: Removes the selected node or edge.
158: */
159: public void removeSelected()
160: {
161: if (selected instanceof Node)
162: {
163: graph.removeNode((Node) selected);
164: }
165: else if (selected instanceof Edge)
166: {
167: graph.removeEdge((Edge) selected);
168: }
169: selected = null;
170: repaint();
171: }
172:
173: /**
174: Draws a single "grabber", a filled square
175: @param g2 the graphics context
176: @param x the x coordinate of the center of the grabber
177: @param y the y coordinate of the center of the grabber
178: */
179: public static void drawGrabber(Graphics2D g2, double x, double y)
180: {
181: final int SIZE = 5;
182: Color oldColor = g2.getColor();
183: g2.setColor(PURPLE);
184: g2.fill(new Rectangle2D.Double(x - SIZE / 2,
185: y - SIZE / 2, SIZE, SIZE));
186: g2.setColor(oldColor);
187: }
188:
189: public Dimension getPreferredSize()
190: {
191: Rectangle2D bounds
192: = graph.getBounds((Graphics2D) getGraphics());
193: return new Dimension(
194: (int) bounds.getMaxX(),
195: (int) bounds.getMaxY());
196: }
197:
198: private Graph graph;
199: private ToolBar toolBar;
200: private Point2D lastMousePoint;
201: private Point2D rubberBandStart;
202: private Point2D dragStartPoint;
203: private Rectangle2D dragStartBounds;
204: private Object selected;
205: private static final Color PURPLE = new Color(0.7f, 0.4f, 0.7f);
206: }