1  import java.awt.*;
  2  import java.awt.geom.*;
  3  import java.io.*;
  4  import java.util.*;
  5  import java.util.List;
  6  
  7  /**
  8     A graph consisting of selectable nodes and edges.
  9  */
 10  public abstract class Graph implements Serializable
 11  {
 12     /**
 13        Constructs a graph with no nodes or edges.
 14     */
 15     public Graph()
 16     {
 17        nodes = new ArrayList<>();
 18        edges = new ArrayList<>();
 19     }
 20  
 21     /**
 22        Adds an edge to the graph that joins the nodes containing
 23        the given points. If the points aren't both inside nodes,
 24        then no edge is added.
 25        @param e the edge to add
 26        @param p1 a point in the starting node
 27        @param p2 a point in the ending node
 28     */
 29     public boolean connect(Edge e, Point2D p1, Point2D p2)
 30     {
 31        Node n1 = findNode(p1);
 32        Node n2 = findNode(p2);
 33        if (n1 != null && n2 != null)
 34        {
 35           e.connect(n1, n2);
 36           edges.add(e);
 37           return true;
 38        }
 39        return false;
 40     }
 41  
 42     /**
 43        Adds a node to the graph so that the top left corner of
 44        the bounding rectangle is at the given point.
 45        @param n the node to add
 46        @param p the desired location
 47     */
 48     public boolean add(Node n, Point2D p)
 49     {
 50        Rectangle2D bounds = n.getBounds();
 51        n.translate(p.getX() - bounds.getX(),
 52           p.getY() - bounds.getY());
 53        nodes.add(n);
 54        return true;
 55     }
 56  
 57     /**
 58        Finds a node containing the given point.
 59        @param p a point
 60        @return a node containing p or null if no nodes contain p
 61     */
 62     public Node findNode(Point2D p)
 63     {
 64        for (int i = nodes.size() - 1; i >= 0; i--)
 65        {
 66           Node n = nodes.get(i);
 67           if (n.contains(p)) return n;
 68        }
 69        return null;
 70     }
 71  
 72     /**
 73        Finds an edge containing the given point.
 74        @param p a point
 75        @return an edge containing p or null if no edges contain p
 76     */
 77     public Edge findEdge(Point2D p)
 78     {
 79        for (int i = edges.size() - 1; i >= 0; i--)
 80        {
 81           Edge e = edges.get(i);
 82           if (e.contains(p)) return e;
 83        }
 84        return null;
 85     }
 86  
 87     /**
 88        Draws the graph
 89        @param g2 the graphics context
 90     */
 91     public void draw(Graphics2D g2)
 92     {
 93        for (Node n : nodes)
 94           n.draw(g2);
 95  
 96        for (Edge e : edges)
 97           e.draw(g2);
 98  
 99     }
100  
101     /**
102        Removes a node and all edges that start or end with that node
103        @param n the node to remove
104     */
105     public void removeNode(Node n)
106     {
107        for (int i = edges.size() - 1; i >= 0; i--)
108        {
109           Edge e = edges.get(i);
110           if (e.getStart() == n || e.getEnd() == n)
111              edges.remove(e);
112        }
113        nodes.remove(n);
114     }
115  
116     /**
117        Removes an edge from the graph.
118        @param e the edge to remove
119     */
120     public void removeEdge(Edge e)
121     {
122        edges.remove(e);
123     }
124  
125     /**
126        Gets the smallest rectangle enclosing the graph
127        @param g2 the graphics context
128        @return the bounding rectangle
129     */
130     public Rectangle2D getBounds(Graphics2D g2)
131     {
132        Rectangle2D r = null;
133        for (Node n : nodes)
134        {
135           Rectangle2D b = n.getBounds();
136           if (r == null) r = b;
137           else r.add(b);
138        }
139        for (Edge e : edges)
140           r.add(e.getBounds(g2));
141        return r == null ? new Rectangle2D.Double() : r;
142     }
143  
144     /**
145        Gets the node types of a particular graph type.
146        @return an array of node prototypes
147     */
148     public abstract Node[] getNodePrototypes();
149  
150     /**
151        Gets the edge types of a particular graph type.
152        @return an array of edge prototypes
153     */
154     public abstract Edge[] getEdgePrototypes();
155  
156     /**
157        Gets the nodes of this graph.
158        @return an unmodifiable list of the nodes
159     */
160     public List<Node> getNodes()
161     {
162        return Collections.unmodifiableList(nodes); }
163  
164     /**
165        Gets the edges of this graph.
166        @return an unmodifiable list of the edges
167     */
168     public List<Edge> getEdges()
169     {
170        return Collections.unmodifiableList(edges);
171     }
172  
173     private ArrayList<Node> nodes;
174     private ArrayList<Edge> edges;
175  }
176  
177  
178  
179  
180