package com.c2kernel.graph.model; import java.awt.Point; import java.awt.Polygon; import java.io.Serializable; import java.util.Hashtable; import java.util.Vector; import com.c2kernel.graph.event.ClearedEvent; import com.c2kernel.graph.event.EdgeRemovedEvent; import com.c2kernel.graph.event.EdgesChangedEvent; import com.c2kernel.graph.event.ElasticBandResizedEvent; import com.c2kernel.graph.event.ElasticBandSetEvent; import com.c2kernel.graph.event.ForcedNotifyEvent; import com.c2kernel.graph.event.GraphModelEvent; import com.c2kernel.graph.event.GraphModelResizedEvent; import com.c2kernel.graph.event.NewEdgeEndPointChangedEvent; import com.c2kernel.graph.event.SelectionChangedEvent; import com.c2kernel.graph.event.SelectionMovedEvent; import com.c2kernel.graph.event.StartVertexIdChangedEvent; import com.c2kernel.graph.event.VertexAddedEvent; import com.c2kernel.graph.event.VertexCreatedEvent; import com.c2kernel.graph.event.VertexMovedEvent; import com.c2kernel.graph.event.VertexRemovedEvent; import com.c2kernel.graph.event.VerticesChangedEvent; import com.c2kernel.utils.Logger; public class GraphModel implements Serializable{ /* Persistant data */ private int mWidth = 0; private int mHeight = 0; private int mNextId = 0; protected int mStartVertexId = -1; protected Hashtable mVertexHashtable = new Hashtable(); protected Hashtable mEdgeHashtable = new Hashtable(); private GraphableVertex mContainingVertex; /* Transient data */ // There should always be a Selection object protected Selection mSelection = new Selection(null, null, 0, 0, 0, 0); protected Vertex mNewEdgeOriginVertex = null; protected Point mNewEdgeEndPoint = null; private ElasticBand mElasticBand = null; private GraphModelManager mManager = null; /* External factories */ private VertexFactory mExternalVertexFactory = null; private EdgeFactory mExternalEdgeFactory = null; /* Vertex outline creator */ private VertexOutlineCreator mVertexOutlineCreator = null; /* Notification Events */ private final ClearedEvent mClearedEvent = new ClearedEvent(); private final EdgeRemovedEvent mEdgeRemovedEvent = new EdgeRemovedEvent(); private final EdgesChangedEvent mEdgesChangedEvent = new EdgesChangedEvent(); private final ForcedNotifyEvent mForcedNotifyEvent = new ForcedNotifyEvent(); private final NewEdgeEndPointChangedEvent mNewEdgeEndPointChangedEvent = new NewEdgeEndPointChangedEvent(); private final SelectionChangedEvent mSelectionChangedEvent = new SelectionChangedEvent(); private final StartVertexIdChangedEvent mStartVertexIdChangedEvent = new StartVertexIdChangedEvent(); private final VertexAddedEvent mVertexAddedEvent = new VertexAddedEvent(); private final VertexCreatedEvent mVertexCreatedEvent = new VertexCreatedEvent(); private final VertexMovedEvent mVertexMovedEvent = new VertexMovedEvent(); private final SelectionMovedEvent mSelectionMovedEvent = new SelectionMovedEvent(); private final VertexRemovedEvent mVertexRemovedEvent = new VertexRemovedEvent(); private final VerticesChangedEvent mVerticesChangedEvent = new VerticesChangedEvent(); private final ElasticBandSetEvent mElasticBandSetEvent = new ElasticBandSetEvent(); private final ElasticBandResizedEvent mElasticBandResizedEvent = new ElasticBandResizedEvent(); private final GraphModelResizedEvent mGraphModelResizedEvent = new GraphModelResizedEvent(); // Calling this constructor does not create a vertex outline creator // which is required by the method addVertexAndCreateId() private static int count=0; // count instances for debugging private int number; public GraphModel() { number=++count; } public int getNumber() { return number; } private void setChanged() { if (mManager != null) mManager.setChanged(); } private void notifyObservers(GraphModelEvent ev) { if (mManager != null) mManager.notifyObservers(ev); } public void setNextId(int id) { mNextId = id; } public int getNextId() { return mNextId; } public void setManager(GraphModelManager mgr) { mManager = mgr; } public GraphModelManager getManager() { return mManager; } public GraphModel(VertexOutlineCreator vertexOutlineCreator) { mVertexOutlineCreator = vertexOutlineCreator; } public void setWidth(int width) { mWidth = width; } public int getWidth() { return mWidth; } public void setHeight(int height) { mHeight = height; } public int getHeight() { return mHeight; } public void checkSize(Vertex v) { boolean resized = false; GraphPoint centre = v.getCentrePoint(); if (getWidth() < centre.x + v.getWidth()/2 +10 ) { setWidth( centre.x + v.getWidth()/2 +10 ); resized = true; } if (getHeight() < centre.y + v.getHeight()/2 +10 ) { setHeight(centre.y + v.getHeight()/2 +10 ); resized = true; } if (resized) { setChanged(); notifyObservers(mGraphModelResizedEvent); } } public void setStartVertexId(int id) { mStartVertexId = id; } public int getStartVertexId() { return mStartVertexId; } public Vertex getStartVertex() { return resolveVertex(getStartVertexId()); } /** * @return Returns the mParentVertex. */ public GraphableVertex getContainingVertex() { return mContainingVertex; } /** * @param parentVertex The mParentVertex to set. */ public void setContainingVertex(GraphableVertex vertex) { mContainingVertex = vertex; } public void setVertices(Vertex[] vertices) { mVertexHashtable = new Hashtable(); for (Vertex vertice : vertices) { mVertexHashtable.put(String.valueOf(vertice.getID()), vertice); checkSize(vertice); } setChanged(); notifyObservers(mVerticesChangedEvent); } public Vertex[] getVertices() { Object[] vertexObjs = mVertexHashtable.values().toArray(); Vertex[] vertices = new Vertex[vertexObjs.length]; int i = 0; for (i = 0; i < vertices.length; i++) { vertices[i] = (Vertex)vertexObjs[i]; } return vertices; } public void setEdges(DirectedEdge[] edges) { mEdgeHashtable = new Hashtable(); for (DirectedEdge edge : edges) { mEdgeHashtable.put(String.valueOf(edge.getID()), edge); } setChanged(); notifyObservers(mEdgesChangedEvent); } public DirectedEdge[] getEdges() { Object[] edgeObjs = mEdgeHashtable.values().toArray(); DirectedEdge[] edges = new DirectedEdge[edgeObjs.length]; int i = 0; for (i = 0; i < edges.length; i++) { edges[i] = (DirectedEdge)edgeObjs[i]; } return edges; } // If the specified point is within more than one vertex, // then the smallest vertex is returned. public Vertex getVertex(GraphPoint p) { Object[] vertexObjs = mVertexHashtable.values().toArray(); Vertex vertex = null; Vector vertexVector = new Vector(10, 10); int numVerticesFound = 0; Vertex smallestVertex = null; int sizeOfSmallestVertex = 0; int sizeOfVertex = 0; int i = 0; for (i = 0; i < vertexObjs.length; i++) { vertex = (Vertex)vertexObjs[i]; if (vertex.containsPoint(p)) { vertexVector.add(vertex); } } numVerticesFound = vertexVector.size(); if (numVerticesFound == 0) { return null; } else { smallestVertex = vertexVector.elementAt(0); sizeOfSmallestVertex = smallestVertex.getHeight() * smallestVertex.getWidth(); // Determine the smallest vertex for (i = 1; i < numVerticesFound; i++) { vertex = vertexVector.elementAt(i); sizeOfVertex = vertex.getHeight() * vertex.getWidth(); if (sizeOfVertex < sizeOfSmallestVertex) { smallestVertex = vertex; sizeOfSmallestVertex = sizeOfVertex; } } return smallestVertex; } } public Vertex getVertexById(int id) { return mVertexHashtable.get(String.valueOf(id)); } public DirectedEdge getEdge(GraphPoint p) { Object[] edgeObjs = mEdgeHashtable.values().toArray(); DirectedEdge edge = null; int i = 0; for (i = 0; i < edgeObjs.length; i++) { edge = (DirectedEdge)edgeObjs[i]; if (edge.containsPoint(p)) { return edge; } } return null; } public int addEdgeAndCreateId(DirectedEdge e, int originId, int terminusId) { return addEdgeAndCreateId(e, resolveVertex(originId), resolveVertex(terminusId)); } public int addEdgeAndCreateId(DirectedEdge e, Vertex origin, Vertex terminus) { e.setID(mNextId); e.setOriginVertexId(origin.getID()); e.setOriginPoint(origin.getCentrePoint()); e.setTerminusVertexId(terminus.getID()); e.setTerminusPoint(terminus.getCentrePoint()); origin.addOutEdgeId(mNextId); terminus.addInEdgeId(mNextId); mEdgeHashtable.put(String.valueOf(mNextId), e); mNextId++; return mNextId - 1; } // Removes an edge, but does not modify the selection public void removeEdge(DirectedEdge e) { Vertex origin = getOrigin(e); Vertex terminus = getTerminus(e); int edgeId = e.getID(); // Remove the id of the edge from the origin and terminus vertices origin.removeOutEdgeId(edgeId); terminus.removeInEdgeId(edgeId); // Remove the edge mEdgeHashtable.remove(String.valueOf(e.getID())); setChanged(); notifyObservers(mEdgeRemovedEvent); } public int addVertexAndCreateId(Vertex v, Point location) { return addVertexAndCreateId(v, new GraphPoint(location.x, location.y)); } public int addVertexAndCreateId(Vertex v, GraphPoint location) { if (location!= null) { if (mVertexOutlineCreator == null) { Logger.msg(1,"You cannot add a vertex with no outline creator"); return -1; } mVertexHashtable.put(String.valueOf(mNextId), v); placeVertex(v, location); } v.setID(mNextId); return mNextId++; } public void placeVertex(Vertex v, GraphPoint location) { v.setCentrePoint(location); if (mVertexOutlineCreator != null) { mVertexOutlineCreator.setOutline(v); } setChanged(); notifyObservers(mVertexAddedEvent); checkSize(v); } // Removes a vertex, but does not modify the selection public void removeVertex(Vertex v) { DirectedEdge[] inEdges = getInEdges(v); DirectedEdge[] outEdges = getOutEdges(v); Vertex origin = null; Vertex terminus = null; int edgeId = -1; int i = 0; // For each in edge for (i = 0; i < inEdges.length; i++) { edgeId = inEdges[i].getID(); origin = getOrigin(inEdges[i]); // Remove the id of the edge from the origin vertex origin.removeOutEdgeId(edgeId); // Remove the edge mEdgeHashtable.remove(String.valueOf(edgeId)); } // Remove all the out edges for (i = 0; i < outEdges.length; i++) { edgeId = outEdges[i].getID(); terminus = getTerminus(outEdges[i]); // Remove the id of the edge from the terminus vertex terminus.removeInEdgeId(edgeId); // Remove the edge mEdgeHashtable.remove(String.valueOf(edgeId)); } // Remove the vertex mVertexHashtable.remove(String.valueOf(v.getID())); setChanged(); notifyObservers(mVertexRemovedEvent); } public void moveAbsoluteVertex(Vertex v, GraphPoint p) { // Make sure the new position stays within the graph if (p.x < 0) p.x = 0; if (p.y < 0) p.y = 0; if (p.x > mWidth) p.x = mWidth; if (p.y > mHeight) p.y = mHeight; moveAbsoluteVertexAndConnectingEdges(v, p); setChanged(); notifyObservers(mVertexMovedEvent); } private void moveAbsoluteVertexAndConnectingEdges(Vertex v, GraphPoint p) { DirectedEdge[] inEdges = getInEdges(v); DirectedEdge[] outEdges = getOutEdges(v); int i = 0; // Move the vertex to the new position v.moveAbsolute(p); // Move the ends of the incoming edges to the new position for (i = 0; i < inEdges.length; i++) { inEdges[i].setTerminusPoint(p); } // Move the ends of the outgoing edges to the new position for (i = 0; i < outEdges.length; i++) { outEdges[i].setOriginPoint(p); } checkSize(v); } public void moveAbsoluteSelection(int newTopLeftX, int newTopLeftY) { int selectionHeight = mSelection.mBottomRightY - mSelection.mTopLeftY; int selectionWidth = mSelection.mBottomRightX - mSelection.mTopLeftX; int bottomRightX = newTopLeftX + selectionWidth; int bottomRightY = newTopLeftY + selectionHeight; GraphPoint oldCentrePoint = null; GraphPoint newCentrePoint = null; int distXFromTopLeft = 0; int distYFromTopLeft = 0; int i = 0; // Make sure the selection does not move // outside the boundaries of the graph if (newTopLeftX < 0) newTopLeftX = 0; if (newTopLeftY < 0) newTopLeftY = 0; if (bottomRightX > mWidth) newTopLeftX = mWidth - selectionWidth; if (bottomRightY > mHeight) newTopLeftY = mHeight - selectionHeight; // For each selected vertex for (i = 0; i < mSelection.mVertices.length; i++) { // Calculate the new centre point of the vertex. // First calculate the distance of the centre point // from the old top left hand corner of the selection, // then move the point to the new top left hand // corner plus the distance. oldCentrePoint = mSelection.mVertices[i].getCentrePoint(); distXFromTopLeft = oldCentrePoint.x - mSelection.mTopLeftX; distYFromTopLeft = oldCentrePoint.y - mSelection.mTopLeftY; newCentrePoint = new GraphPoint(newTopLeftX + distXFromTopLeft, newTopLeftY + distYFromTopLeft); moveAbsoluteVertexAndConnectingEdges(mSelection.mVertices[i], newCentrePoint); } // Update the top left and bottom right corners mSelection.mTopLeftX = newTopLeftX; mSelection.mTopLeftY = newTopLeftY; mSelection.mBottomRightX = newTopLeftX + selectionWidth; mSelection.mBottomRightY = newTopLeftY + selectionHeight; setChanged(); notifyObservers(mSelectionMovedEvent); } public Vertex resolveVertex(int id) { return mVertexHashtable.get(String.valueOf(id)); } public DirectedEdge resolveEdge(int id) { return mEdgeHashtable.get(String.valueOf(id)); } public DirectedEdge[] getInEdges(Vertex v) { int[] ids = v.getInEdgeIds(); return resolveEdges(ids); } public DirectedEdge[] getOutEdges(Vertex v) { int[] ids = v.getOutEdgeIds(); return resolveEdges(ids); } private DirectedEdge[] resolveEdges(int[] ids) { DirectedEdge[] edges = new DirectedEdge[ids.length]; int i = 0; for (i = 0; i < ids.length; i++) { edges[i] = resolveEdge(ids[i]); } return edges; } public Vertex getOrigin(DirectedEdge e) { return resolveVertex(e.getOriginVertexId()); } public Vertex getTerminus(DirectedEdge e) { return resolveVertex(e.getTerminusVertexId()); } public Vertex[] getInVertices(Vertex v) { DirectedEdge[] inEdges = getInEdges(v); Vertex[] inVertices = new Vertex[inEdges.length]; int i = 0; for (i = 0; i < inEdges.length; i++) { inVertices[i] = getOrigin(inEdges[i]); } return inVertices; } public Vertex[] getOutVertices(Vertex v) { DirectedEdge[] outEdges = getOutEdges(v); Vertex[] outVertices = new Vertex[outEdges.length]; int i = 0; for (i = 0; i < outEdges.length; i++) { outVertices[i] = getTerminus(outEdges[i]); } return outVertices; } public DirectedEdge[] getConnectingEdges(int originVertexId, int terminusVertexId) { Vertex origin = resolveVertex(originVertexId); DirectedEdge[] outEdges = null; int numEdgesFound = 0; DirectedEdge[] edgesFound = null; int i = 0; int j = 0; if (origin == null) return null; outEdges = getOutEdges(origin); for (i = 0; i < outEdges.length; i++) { if (outEdges[i].getTerminusVertexId() == terminusVertexId) { numEdgesFound++; } } edgesFound = new DirectedEdge[numEdgesFound]; for (i = 0; i < outEdges.length; i++) { if (outEdges[i].getTerminusVertexId() == terminusVertexId) { edgesFound[j] = outEdges[i]; j++; } } return edgesFound; } public void clearTags(Object tag) { Vertex vertex = null; Object[] vertexObjs = mVertexHashtable.values().toArray(); int i = 0; for (i = 0; i < vertexObjs.length; i++) { vertex = (Vertex)vertexObjs[i]; vertex.clearTag(tag); } } public void forceNotify() { setChanged(); notifyObservers(mForcedNotifyEvent); } public void clear() { mVertexHashtable = new Hashtable(); mEdgeHashtable = new Hashtable(); mStartVertexId = -1; setChanged(); notifyObservers(mClearedEvent); } public void setSelection(Selection s) { // If the there is a change if (selectionChanged(s)) { mSelection = s; mSelectionChangedEvent.mSelection = s; setChanged(); notifyObservers(mSelectionChangedEvent); } } private boolean selectionChanged(Selection newValue) { int i = 0; if (mSelection.mEdge != newValue.mEdge) { return true; } if (mSelection.mVertices == null) { if (newValue.mVertices == null) { return false; } else { return true; } } else { if (newValue.mVertices == null) { return true; } else { if (mSelection.mVertices.length != newValue.mVertices.length) { return true; } for (i = 0; i < mSelection.mVertices.length; i++) { if (mSelection.mVertices[i] != newValue.mVertices[i]) { return true; } } return false; } } } public Selection getSelection() { return mSelection; } public void setNewEdgeOriginVertex(Vertex v) { mNewEdgeOriginVertex = v; } public Vertex getNewEdgeOriginVertex() { return mNewEdgeOriginVertex; } public void setNewEdgeEndPoint(Point p) { mNewEdgeEndPoint = p; setChanged(); notifyObservers(mNewEdgeEndPointChangedEvent); } public Point getNewEdgeEndPoint() { return mNewEdgeEndPoint; } public void setExternalVertexFactory(VertexFactory factory) { mExternalVertexFactory = factory; } public void createVertex(Point location, TypeNameAndConstructionInfo typeNameAndConstructionInfo) throws Exception { if (mExternalVertexFactory != null) { mExternalVertexFactory.create(mManager, location, typeNameAndConstructionInfo); setChanged(); notifyObservers(mVertexCreatedEvent); } } public void setExternalEdgeFactory(EdgeFactory factory) { mExternalEdgeFactory = factory; } public void setVertexOutlineCreator(VertexOutlineCreator outlineCreator) { mVertexOutlineCreator = outlineCreator; } public void createDirectedEdge(Vertex origin, Vertex terminus, TypeNameAndConstructionInfo typeNameAndConstructionInfo) { if (mExternalEdgeFactory != null) { mExternalEdgeFactory.create(mManager, origin, terminus, typeNameAndConstructionInfo); } } public void selectAll() { Vertex[] allVertices = getVertices(); if (allVertices.length > 0) { mSelection.mEdge = null; mSelection.mVertices = allVertices; updateSelectionCorners(); mSelectionChangedEvent.mSelection = mSelection; setChanged(); notifyObservers(mSelectionChangedEvent); } } public void selectContentsOfElasticBand() { if (mElasticBand == null) return; Polygon bandPolygon = new Polygon(); Vertex[] allVertices = getVertices(); GraphPoint centrePoint = null; Vector verticesInside = new Vector(10, 10); int i = 0; // Create a polygon representing the elastic band bandPolygon.addPoint(mElasticBand.mFixedCorner.x, mElasticBand.mFixedCorner.y); bandPolygon.addPoint(mElasticBand.mMovingCorner.x, mElasticBand.mFixedCorner.y); bandPolygon.addPoint(mElasticBand.mMovingCorner.x, mElasticBand.mMovingCorner.y); bandPolygon.addPoint(mElasticBand.mFixedCorner.x, mElasticBand.mMovingCorner.y); // Create a vector of all of the vertices within the elastic band polygon for (i = 0; i < allVertices.length; i++) { centrePoint = allVertices[i].getCentrePoint(); if (bandPolygon.contains(centrePoint.x, centrePoint.y)) { verticesInside.add(allVertices[i]); } } // Select the vertices found within the elastic band polygon if (verticesInside.size() == 0) { mSelection.mTopLeftX = 0; mSelection.mTopLeftY = 0; mSelection.mBottomRightX = 0; mSelection.mBottomRightY = 0; mSelection.mEdge = null; if (mContainingVertex != null) verticesInside.add(mContainingVertex); else mSelection.mVertices = null; } if (verticesInside.size() > 0) { mSelection.mEdge = null; mSelection.mVertices = new Vertex[verticesInside.size()]; for (i = 0; i < verticesInside.size(); i++) { mSelection.mVertices[i] = verticesInside.elementAt(i); } updateSelectionCorners(); } // Remove the elastic band mElasticBand = null; mSelectionChangedEvent.mSelection = mSelection; setChanged(); notifyObservers(mSelectionChangedEvent); } // Updates the top left and bottom right corners of the selection private void updateSelectionCorners() { Vertex vertex = mSelection.mVertices[0]; GraphPoint centrePoint = vertex.getCentrePoint(); if (centrePoint == null) return; mSelection.mTopLeftX = centrePoint.x; mSelection.mTopLeftY = centrePoint.y; mSelection.mBottomRightX = centrePoint.x; mSelection.mBottomRightY = centrePoint.y; for (Vertex mVertice : mSelection.mVertices) { vertex = mVertice; centrePoint = vertex.getCentrePoint(); if (centrePoint.x < mSelection.mTopLeftX) { mSelection.mTopLeftX = centrePoint.x; } if (centrePoint.y < mSelection.mTopLeftY) { mSelection.mTopLeftY = centrePoint.y; } if (centrePoint.x > mSelection.mBottomRightX) { mSelection.mBottomRightX = centrePoint.x; } if (centrePoint.y > mSelection.mBottomRightY) { mSelection.mBottomRightY = centrePoint.y; } } } public void deleteSelection() { int i = 0; if (mSelection.mVertices != null) { for (i = 0; i < mSelection.mVertices.length; i++) { removeVertex(mSelection.mVertices[i]); } } else if (mSelection.mEdge != null) { removeEdge(mSelection.mEdge); } // Make sure nothing is selected if ((mSelection.mEdge != null) || (mSelection.mVertices != null)) { mSelection.mEdge = null; mSelection.mVertices = null; mSelectionChangedEvent.mSelection = mSelection; setChanged(); notifyObservers(mSelectionChangedEvent); } } public void setSelectedVertexToBeStart() { if (mSelection.mVertices != null) { if (mSelection.mVertices.length == 1) { setStartVertexId(mSelection.mVertices[0].getID()); setChanged(); notifyObservers(mStartVertexIdChangedEvent); } } } public void setElasticBand(ElasticBand elasticBand) { mElasticBand = elasticBand; setChanged(); notifyObservers(mElasticBandSetEvent); } public ElasticBand getElasticBand() { return mElasticBand; } public void resizeElasticBand(Point movingCorner) { mElasticBand.mMovingCorner = movingCorner; setChanged(); notifyObservers(mElasticBandResizedEvent); } public boolean inSelection(Vertex v) { int i = 0; if (mSelection.mVertices == null) { return false; } else { for (i = 0; i < mSelection.mVertices.length; i++) { if (mSelection.mVertices[i] == v) { return true; } } return false; } } // Only use this method to remove one vertex. // If you wish to remove more, it would // propably be more efficient to create a // new Selection object. public void removeFromSelection(Vertex v) { Vertex[] vertices = null; int i = 0; int j = 0; if (mSelection.mVertices.length == 1) { mSelection.mVertices = null; mSelection.mTopLeftX = 0; mSelection.mTopLeftY = 0; mSelection.mBottomRightX = 0; mSelection.mBottomRightY = 0; } else { vertices = new Vertex[mSelection.mVertices.length - 1]; for (i = 0; i < mSelection.mVertices.length; i++) { if (mSelection.mVertices[i] != v) { vertices[j] = mSelection.mVertices[i]; j++; } } mSelection.mVertices = vertices; updateSelectionCorners(); } setChanged(); notifyObservers(mSelectionChangedEvent); } // Only use this method to add one vertex. // If you wish to add more, it would // propably be more efficient to create a // new Selection object. public void addToSelection(Vertex v) { Vertex[] vertices = new Vertex[mSelection.mVertices.length + 1]; GraphPoint centrePoint = null; int i = 0; if (mSelection.mVertices == null) { centrePoint = v.getCentrePoint(); mSelection.mVertices = new Vertex[] { v }; mSelection.mTopLeftX = centrePoint.x; mSelection.mTopLeftY = centrePoint.y; mSelection.mBottomRightX = centrePoint.x; mSelection.mBottomRightY = centrePoint.y; } else { for (i = 0; i < mSelection.mVertices.length; i++) { vertices[i] = mSelection.mVertices[i]; } vertices[mSelection.mVertices.length] = v; mSelection.mVertices = vertices; updateSelectionCorners(); } setChanged(); notifyObservers(mSelectionChangedEvent); } public void resetVertexOutlines() { Vertex[] vertices = getVertices(); int i = 0; for (i = 0; i < vertices.length; i++) { mVertexOutlineCreator.setOutline(vertices[i]); } } public void setGraphModelCastorData(GraphModelCastorData data) { Class vertexOutlineCreatorClass = null; int i = 0; // Create the vertex outline creator if (data.mClassNameOfVertexOutlineCreator.equals("")) { mVertexOutlineCreator = null; } else { try { vertexOutlineCreatorClass = Class.forName(data.mClassNameOfVertexOutlineCreator); mVertexOutlineCreator = (VertexOutlineCreator)vertexOutlineCreatorClass.newInstance(); } catch (Exception e) { e.printStackTrace(); mVertexOutlineCreator = null; } } // Create and populate the vertex hashtable mVertexHashtable = new Hashtable(); for (i = 0; i < data.mVertexImpls.length; i++) { mVertexHashtable.put(String.valueOf(data.mVertexImpls[i].getID()), data.mVertexImpls[i]); checkSize(data.mVertexImpls[i]); } // Create and populate the edge hastable mEdgeHashtable = new Hashtable(); for (i = 0; i < data.mEdgeImpls.length; i++) { mEdgeHashtable.put(String.valueOf(data.mEdgeImpls[i].getID()), data.mEdgeImpls[i]); } // Set the start vertex id and the id generation counter mStartVertexId = data.mStartVertexId; mNextId = data.mNextId; } public GraphModelCastorData getGraphModelCastorData() { Object[] vertexObjs = mVertexHashtable.values().toArray(); Vertex[] vertexImpls = new Vertex[vertexObjs.length]; Object[] edgeObjs = mEdgeHashtable.values().toArray(); DirectedEdge[] directedEdgeImpls = new DirectedEdge[edgeObjs.length]; String className = null; int i = 0; // Put in the vertices for (i = 0; i < vertexImpls.length; i++) { vertexImpls[i] = (Vertex)vertexObjs[i]; } // Put in the edges for (i = 0; i < directedEdgeImpls.length; i++) { directedEdgeImpls[i] = (DirectedEdge)edgeObjs[i]; } // Determine the class name of the vertex outline creator if (mVertexOutlineCreator == null) { className = ""; } else { className = mVertexOutlineCreator.getClass().getName(); } return new GraphModelCastorData(className, vertexImpls, directedEdgeImpls, mStartVertexId, mNextId); } }