Source of GraphPanel.java


  1: import java.awt.*;
  2: import java.awt.geom.*;
  3: import java.awt.event.*;
  4: import javax.swing.*;
  5: import javax.swing.event.*;

  7: /**
  8:    A panel to draw a graph
  9: */
 10: public class GraphPanel extends JComponent
 11: {
 12:    /**
 13:       Constructs a graph.
 14:       @param aToolBar the tool bar with the node and edge tools
 15:       @param aGraph the graph to be displayed and edited
 16:    */
 17:    public GraphPanel(ToolBar aToolBar, Graph aGraph)
 18:    {
 19:       toolBar = aToolBar;
 20:       graph = aGraph;
 21:       setBackground(Color.WHITE);

 23:       addMouseListener(new
 24:          MouseAdapter()
 25:          {
 26:             public void mousePressed(MouseEvent event)
 27:             {
 28:                Point2D mousePoint = event.getPoint();
 29:                Node n = graph.findNode(mousePoint); 
 30:                Edge e = graph.findEdge(mousePoint);
 31:                Object tool = toolBar.getSelectedTool();
 32:                if (tool == null) // select
 33:                {
 34:                   if (e != null)
 35:                   {
 36:                      selected = e;
 37:                   }
 38:                   else if (n != null)
 39:                   {
 40:                      selected = n;
 41:                      dragStartPoint = mousePoint;
 42:                      dragStartBounds = n.getBounds();
 43:                   }
 44:                   else 
 45:                   {
 46:                      selected = null;
 47:                   }
 48:                }
 49:                else if (tool instanceof Node)
 50:                {
 51:                   Node prototype = (Node) tool;
 52:                   Node newNode = (Node) prototype.clone();
 53:                   boolean added = graph.add(newNode, mousePoint);
 54:                   if (added)
 55:                   {
 56:                      selected = newNode;
 57:                      dragStartPoint = mousePoint;
 58:                      dragStartBounds = newNode.getBounds();
 59:                   }
 60:                   else if (n != null)
 61:                   {
 62:                      selected = n;
 63:                      dragStartPoint = mousePoint;
 64:                      dragStartBounds = n.getBounds();
 65:                   }
 66:                }
 67:                else if (tool instanceof Edge)
 68:                {
 69:                   if (n != null) rubberBandStart = mousePoint;
 70:                }
 71:                lastMousePoint = mousePoint;
 72:                repaint();
 73:             }

 75:             public void mouseReleased(MouseEvent event)
 76:             {
 77:                Object tool = toolBar.getSelectedTool();
 78:                if (rubberBandStart != null)
 79:                {
 80:                   Point2D mousePoint = event.getPoint();
 81:                   Edge prototype = (Edge) tool;
 82:                   Edge newEdge = (Edge) prototype.clone(); 
 83:                   if (graph.connect(newEdge, 
 84:                          rubberBandStart, mousePoint))
 85:                      selected = newEdge;
 86:                }

 88:                revalidate();
 89:                repaint();

 91:                lastMousePoint = null;
 92:                dragStartBounds = null;
 93:                rubberBandStart = null;
 94:             }
 95:          });

 97:       addMouseMotionListener(new
 98:          MouseMotionAdapter()
 99:          {
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:    }

122:    public void paintComponent(Graphics g)
123:    {
124:       Graphics2D g2 = (Graphics2D) g;
125:       Rectangle2D bounds = getBounds();
126:       Rectangle2D graphBounds = graph.getBounds(g2);
127:       graph.draw(g2);

129:       if (selected instanceof Node)
130:       {
131:          Rectangle2D grabberBounds = ((Node) selected).getBounds();
132:          drawGrabber(g2, grabberBounds.getMinX(), grabberBounds.getMinY());
133:          drawGrabber(g2, grabberBounds.getMinX(), grabberBounds.getMaxY());
134:          drawGrabber(g2, grabberBounds.getMaxX(), grabberBounds.getMinY());
135:          drawGrabber(g2, grabberBounds.getMaxX(), grabberBounds.getMaxY());
136:       }

138:       if (selected instanceof Edge)
139:       {
140:          Line2D line = ((Edge) selected).getConnectionPoints();
141:          drawGrabber(g2, line.getX1(), line.getY1());
142:          drawGrabber(g2, line.getX2(), line.getY2());
143:       }

145:       if (rubberBandStart != null)
146:       {
147:          Color oldColor = g2.getColor();
148:          g2.setColor(PURPLE);
149:          g2.draw(new Line2D.Double(rubberBandStart, lastMousePoint));
150:          g2.setColor(oldColor);
151:       }
152:    }

154:    /**
155:       Removes the selected node or edge.
156:    */
157:    public void removeSelected()
158:    {
159:       if (selected instanceof Node)
160:       {
161:          graph.removeNode((Node) selected);
162:       }
163:       else if (selected instanceof Edge)
164:       {
165:          graph.removeEdge((Edge) selected);
166:       }          
167:       selected = null;
168:       repaint();               
169:    }

171:    /**
172:       Edits the properties of the selected graph element.
173:    */
174:    public void editSelected()
175:    {
176:       PropertySheet sheet = new PropertySheet(selected);
177:       sheet.addChangeListener(new
178:          ChangeListener()
179:          {
180:             public void stateChanged(ChangeEvent event)
181:             {
182:                repaint();
183:             }
184:          });
185:       JOptionPane.showMessageDialog(null, 
186:          sheet, 
187:          "Properties", 
188:          JOptionPane.QUESTION_MESSAGE);        
189:    }

191:    /**
192:       Draws a single "grabber", a filled square
193:       @param g2 the graphics context
194:       @param x the x coordinate of the center of the grabber
195:       @param y the y coordinate of the center of the grabber
196:    */
197:    public static void drawGrabber(Graphics2D g2, double x, double y)
198:    {
199:       final int SIZE = 5;
200:       Color oldColor = g2.getColor();
201:       g2.setColor(PURPLE);
202:       g2.fill(new Rectangle2D.Double(x - SIZE / 2,
203:          y - SIZE / 2, SIZE, SIZE));      
204:       g2.setColor(oldColor);
205:    }

207:    public Dimension getPreferredSize()
208:    {
209:       Rectangle2D bounds 
210:          = graph.getBounds((Graphics2D) getGraphics());
211:       return new Dimension(
212:          (int) bounds.getMaxX(), 
213:          (int) bounds.getMaxY());
214:    }

216:    private Graph graph;
217:    private ToolBar toolBar;
218:    private Point2D lastMousePoint;
219:    private Point2D rubberBandStart;
220:    private Point2D dragStartPoint;
221:    private Rectangle2D dragStartBounds;
222:    private Object selected;
223:    private static final Color PURPLE = new Color(0.7f, 0.4f, 0.7f);   
224: }