From d6f6211306708d22ddcbe4e350f906c63220d7a4 Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Fri, 29 Jun 2012 16:21:42 +0200 Subject: More graph gui components. Selection moved from GraphModel to GraphPanel --- .../com/c2kernel/gui/graph/view/GraphPanel.java | 367 ++++++++++++++++++--- 1 file changed, 327 insertions(+), 40 deletions(-) (limited to 'src/main/java/com/c2kernel/gui/graph/view/GraphPanel.java') diff --git a/src/main/java/com/c2kernel/gui/graph/view/GraphPanel.java b/src/main/java/com/c2kernel/gui/graph/view/GraphPanel.java index fa7ed6f..a234d65 100644 --- a/src/main/java/com/c2kernel/gui/graph/view/GraphPanel.java +++ b/src/main/java/com/c2kernel/gui/graph/view/GraphPanel.java @@ -6,33 +6,46 @@ import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Paint; -import java.awt.Point; +import java.awt.Polygon; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import com.c2kernel.gui.graph.event.ElasticBandResizedEvent; +import com.c2kernel.gui.graph.event.ElasticBandSetEvent; +import com.c2kernel.gui.graph.event.SelectionMovedEvent; import java.util.Observable; import java.util.Observer; +import java.util.Vector; import javax.swing.JPanel; import com.c2kernel.graph.event.EntireModelChangedEvent; import com.c2kernel.graph.event.GraphModelResizedEvent; import com.c2kernel.graph.model.DirectedEdge; -import com.c2kernel.graph.model.ElasticBand; import com.c2kernel.graph.model.GraphModelManager; import com.c2kernel.graph.model.GraphPoint; -import com.c2kernel.graph.model.Selection; import com.c2kernel.graph.model.Vertex; -import com.c2kernel.utils.Resource; +import com.c2kernel.gui.ImageLoader; +import com.c2kernel.gui.graph.controller.ElasticBand; +import com.c2kernel.gui.graph.controller.Selection; +import com.c2kernel.gui.graph.event.SelectionChangedEvent; public class GraphPanel extends JPanel implements Observer { + // There should always be a Selection object + protected Selection mSelection = new Selection(null, null, 0, 0, 0, 0); + private ElasticBand mElasticBand = null; protected final Paint mSelectionPaint = Color.black; protected final Paint mStartPaint = Color.green; - protected final Image mResizePadImg = Resource.findImage("graph/resizepad.gif").getImage(); + protected final Image mResizePadImg = ImageLoader.findImage("graph/resizepad.gif").getImage(); protected final BasicStroke mDashed = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[] { 5.0f }, 0.0f); protected GraphModelManager mGraphModelManager = null; protected VertexRenderer mVertexRenderer = null; protected DirectedEdgeRenderer mDirectedEdgeRenderer = null; + private final SelectionChangedEvent mSelectionChangedEvent = new SelectionChangedEvent(); + private final SelectionMovedEvent mSelectionMovedEvent = new SelectionMovedEvent(); + private final ElasticBandResizedEvent mElasticBandResizedEvent = new ElasticBandResizedEvent(); + private final ElasticBandSetEvent mElasticBandSetEvent = new ElasticBandSetEvent(); + public GraphPanel(DirectedEdgeRenderer eRenderer, VertexRenderer vRenderer) { mVertexRenderer = vRenderer; @@ -55,6 +68,10 @@ public class GraphPanel extends JPanel implements Observer @Override public void update(Observable o, Object arg) { + if (arg instanceof EntireModelChangedEvent) + { + mSelection = new Selection(null, null, 0, 0, 0, 0); + } if (arg instanceof GraphModelResizedEvent || arg instanceof EntireModelChangedEvent) { setPreferredSize(new Dimension(mGraphModelManager.getModel().getWidth(), mGraphModelManager.getModel().getHeight())); @@ -62,6 +79,282 @@ public class GraphPanel extends JPanel implements Observer } repaint(); } + // 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++) { + mGraphModelManager.getModel().removeVertex(mSelection.mVertices[i]); + } + } + else if (mSelection.mEdge != null) { + mGraphModelManager.getModel().removeEdge(mSelection.mEdge); + } + // Make sure nothing is selected + if ((mSelection.mEdge != null) || (mSelection.mVertices != null)) { + mSelection.mEdge = null; + mSelection.mVertices = null; + mSelectionChangedEvent.mSelection = mSelection; + mGraphModelManager.notifyObservers(mSelectionChangedEvent); + } + } + + public void selectAll() { + Vertex[] allVertices = mGraphModelManager.getModel().getVertices(); + if (allVertices.length > 0) { + mSelection.mEdge = null; + mSelection.mVertices = allVertices; + updateSelectionCorners(); + mSelectionChangedEvent.mSelection = mSelection; + mGraphModelManager.notifyObservers(mSelectionChangedEvent); + } + } + + public void selectContentsOfElasticBand() { + if (mElasticBand == null) return; + Polygon bandPolygon = new Polygon(); + Vertex[] allVertices = mGraphModelManager.getModel().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; + // select parent vertex if we have selected the 'paper' + if (mGraphModelManager.getModel().getContainingVertex() != null) + verticesInside.add(mGraphModelManager.getModel().getContainingVertex()); + 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; + mGraphModelManager.notifyObservers(mSelectionChangedEvent); + } + + + + public void setSelectedVertexToBeStart() { + if (mSelection.mVertices != null) { + if (mSelection.mVertices.length == 1) { + mGraphModelManager.getModel().setStartVertexId(mSelection.mVertices[0].getID()); + } + } + } + + public Selection getSelection() { + return mSelection; + } + + public void setElasticBand(ElasticBand elasticBand) { + mElasticBand = elasticBand; + mGraphModelManager.notifyObservers(mElasticBandSetEvent); + } + + public void resizeElasticBand(GraphPoint movingCorner) { + mElasticBand.mMovingCorner = movingCorner; + mGraphModelManager.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(); + } + mGraphModelManager.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(); + } + mGraphModelManager.notifyObservers(mSelectionChangedEvent); + } + 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; + int graphWidth = mGraphModelManager.getModel().getWidth(); + if (bottomRightX > graphWidth) newTopLeftX = graphWidth - selectionWidth; + int graphHeight = mGraphModelManager.getModel().getHeight(); + if (bottomRightY > graphHeight) newTopLeftY = graphHeight - 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); + mGraphModelManager.getModel().moveAbsoluteVertex(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; + mGraphModelManager.notifyObservers(mSelectionMovedEvent); + } + public void setSelection(Selection s) { + // If the there is a change + if (selectionChanged(s)) { + mSelection = s; + mSelectionChangedEvent.mSelection = s; + mGraphModelManager.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; + } + } + } @Override public void paintComponent(Graphics g) { @@ -69,11 +362,9 @@ public class GraphPanel extends JPanel implements Observer DirectedEdge[] edges = null; Vertex[] vertices = null; Vertex startVertex = null; - Selection selection = null; - ElasticBand elasticBand = null; Vertex newEdgeOriginVertex = null; GraphPoint newEdgeOriginPoint = null; - Point newEdgeEndPoint = null; + GraphPoint newEdgeEndPoint = null; GraphPoint vertexCentre = null; int i = 0; super.paintComponent(g); @@ -100,63 +391,59 @@ public class GraphPanel extends JPanel implements Observer { drawVertexHighlight(g2d, startVertex, 1); } - // Get the present selection - selection = mGraphModelManager.getModel().getSelection(); g2d.setPaint(mSelectionPaint); // Draw the outline of the selected // vertices if there are any - if (selection.mVertices != null) + if (mSelection.mVertices != null) { g2d.setStroke(mDashed); - for (i = 0; i < selection.mVertices.length; i++) + for (i = 0; i < mSelection.mVertices.length; i++) { - if (selection.mVertices[i] != mGraphModelManager.getModel().getContainingVertex()) - drawVertexHighlight(g2d, selection.mVertices[i], 5); + if (mSelection.mVertices[i] != mGraphModelManager.getModel().getContainingVertex()) + drawVertexHighlight(g2d, mSelection.mVertices[i], 5); } // Draw the resize pads if there is one and only one vertex selected - if (selection.mVertices.length == 1 && - selection.mVertices[0] != mGraphModelManager.getModel().getContainingVertex()) + if (mSelection.mVertices.length == 1 && + mSelection.mVertices[0] != mGraphModelManager.getModel().getContainingVertex()) { - vertexCentre = selection.mVertices[0].getCentrePoint(); + vertexCentre = mSelection.mVertices[0].getCentrePoint(); g2d.drawImage( mResizePadImg, - vertexCentre.x + selection.mVertices[0].getWidth() / 2, - vertexCentre.y + selection.mVertices[0].getHeight() / 2, + vertexCentre.x + mSelection.mVertices[0].getWidth() / 2, + vertexCentre.y + mSelection.mVertices[0].getHeight() / 2, this); } } // Draw the outline of the selected // edge if there is one - if (selection.mEdge != null) + if (mSelection.mEdge != null) { - drawEdgeHighlight(g2d, selection.mEdge); + drawEdgeHighlight(g2d, mSelection.mEdge); } - // Get the elastic band - elasticBand = mGraphModelManager.getModel().getElasticBand(); // Draw the elastic band if there // is one - if (elasticBand != null) + if (mElasticBand != null) { g2d.drawLine( - elasticBand.mFixedCorner.x, - elasticBand.mFixedCorner.y, - elasticBand.mMovingCorner.x, - elasticBand.mFixedCorner.y); + mElasticBand.mFixedCorner.x, + mElasticBand.mFixedCorner.y, + mElasticBand.mMovingCorner.x, + mElasticBand.mFixedCorner.y); g2d.drawLine( - elasticBand.mMovingCorner.x, - elasticBand.mFixedCorner.y, - elasticBand.mMovingCorner.x, - elasticBand.mMovingCorner.y); + mElasticBand.mMovingCorner.x, + mElasticBand.mFixedCorner.y, + mElasticBand.mMovingCorner.x, + mElasticBand.mMovingCorner.y); g2d.drawLine( - elasticBand.mMovingCorner.x, - elasticBand.mMovingCorner.y, - elasticBand.mFixedCorner.x, - elasticBand.mMovingCorner.y); + mElasticBand.mMovingCorner.x, + mElasticBand.mMovingCorner.y, + mElasticBand.mFixedCorner.x, + mElasticBand.mMovingCorner.y); g2d.drawLine( - elasticBand.mFixedCorner.x, - elasticBand.mMovingCorner.y, - elasticBand.mFixedCorner.x, - elasticBand.mFixedCorner.y); + mElasticBand.mFixedCorner.x, + mElasticBand.mMovingCorner.y, + mElasticBand.mFixedCorner.x, + mElasticBand.mFixedCorner.y); } // Draw the new edge under construction if there is one newEdgeEndPoint = mGraphModelManager.getModel().getNewEdgeEndPoint(); -- cgit v1.2.3