package com.c2kernel.graph.view; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Paint; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Observable; import java.util.Observer; 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; public class GraphPanel extends JPanel implements Observer { protected final Paint mSelectionPaint = Color.black; protected final Paint mStartPaint = Color.green; protected final Image mResizePadImg = Resource.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; public GraphPanel(DirectedEdgeRenderer eRenderer, VertexRenderer vRenderer) { mVertexRenderer = vRenderer; mDirectedEdgeRenderer = eRenderer; // Request the keyboard focus if the mouse // is pressed on the graph panel addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent me) { requestFocus(); } }); } public void setGraphModelManager(GraphModelManager graphModelManager) { mGraphModelManager = graphModelManager; } @Override public void update(Observable o, Object arg) { if (arg instanceof GraphModelResizedEvent || arg instanceof EntireModelChangedEvent) { setPreferredSize(new Dimension(mGraphModelManager.getModel().getWidth(), mGraphModelManager.getModel().getHeight())); revalidate(); } repaint(); } @Override public void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g; 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 vertexCentre = null; int i = 0; super.paintComponent(g); if (mGraphModelManager != null) { // Get the edges and vertices from the model edges = mGraphModelManager.getModel().getEdges(); vertices = mGraphModelManager.getModel().getVertices(); //graphable = mGraphModelManager.getModel(). // Draw the edges for (i = 0; i < edges.length; i++) { mDirectedEdgeRenderer.draw(g2d, edges[i]); } // Draw the vertices for (i = 0; i < vertices.length; i++) { mVertexRenderer.draw(g2d, vertices[i]); } g2d.setPaint(mStartPaint); // Highlight the start vertex if there is one startVertex = mGraphModelManager.getModel().getStartVertex(); if (startVertex != null) { 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) { g2d.setStroke(mDashed); for (i = 0; i < selection.mVertices.length; i++) { if (selection.mVertices[i] != mGraphModelManager.getModel().getContainingVertex()) drawVertexHighlight(g2d, selection.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()) { vertexCentre = selection.mVertices[0].getCentrePoint(); g2d.drawImage( mResizePadImg, vertexCentre.x + selection.mVertices[0].getWidth() / 2, vertexCentre.y + selection.mVertices[0].getHeight() / 2, this); } } // Draw the outline of the selected // edge if there is one if (selection.mEdge != null) { drawEdgeHighlight(g2d, selection.mEdge); } // Get the elastic band elasticBand = mGraphModelManager.getModel().getElasticBand(); // Draw the elastic band if there // is one if (elasticBand != null) { g2d.drawLine( elasticBand.mFixedCorner.x, elasticBand.mFixedCorner.y, elasticBand.mMovingCorner.x, elasticBand.mFixedCorner.y); g2d.drawLine( elasticBand.mMovingCorner.x, elasticBand.mFixedCorner.y, elasticBand.mMovingCorner.x, elasticBand.mMovingCorner.y); g2d.drawLine( elasticBand.mMovingCorner.x, elasticBand.mMovingCorner.y, elasticBand.mFixedCorner.x, elasticBand.mMovingCorner.y); g2d.drawLine( elasticBand.mFixedCorner.x, elasticBand.mMovingCorner.y, elasticBand.mFixedCorner.x, elasticBand.mFixedCorner.y); } // Draw the new edge under construction if there is one newEdgeEndPoint = mGraphModelManager.getModel().getNewEdgeEndPoint(); newEdgeOriginVertex = mGraphModelManager.getModel().getNewEdgeOriginVertex(); if ((newEdgeEndPoint != null) && (newEdgeOriginVertex != null)) { newEdgeOriginPoint = newEdgeOriginVertex.getCentrePoint(); g2d.setPaint(Color.black); g2d.drawLine(newEdgeOriginPoint.x, newEdgeOriginPoint.y, newEdgeEndPoint.x, newEdgeEndPoint.y); } } } // Draws the highlight of the specified vertex the specified dist from its outline protected void drawVertexHighlight(Graphics2D g2d, Vertex vertex, int dist) { GraphPoint[] outlinePoints = vertex.getOutlinePoints(); GraphPoint centrePoint = vertex.getCentrePoint(); int i = 0; /* * float dash1[] ={5.0f}; BasicStroke bs = new BasicStroke(5.0f, BasicStroke.CAP_BUTT,BasicStroke.JOIN_ROUND,10.0f, dash1,0.0f); */ for (i = 0; i < outlinePoints.length - 1; i++) { drawShiftedLine(dist, g2d, centrePoint, outlinePoints[i].x, outlinePoints[i].y, outlinePoints[i + 1].x, outlinePoints[i + 1].y); } drawShiftedLine( dist, g2d, centrePoint, outlinePoints[outlinePoints.length - 1].x, outlinePoints[outlinePoints.length - 1].y, outlinePoints[0].x, outlinePoints[0].y); } // Draws the specifed line the specified distance away from the specified centre point private static void drawShiftedLine(int dist, Graphics2D g2d, GraphPoint centrePoint, int x1, int y1, int x2, int y2) { if (x1 > centrePoint.x) x1 += dist; if (x1 < centrePoint.x) x1 -= dist; if (y1 > centrePoint.y) y1 += dist; if (y1 < centrePoint.y) y1 -= dist; if (x2 > centrePoint.x) x2 += dist; if (x2 < centrePoint.x) x2 -= dist; if (y2 > centrePoint.y) y2 += dist; if (y2 < centrePoint.y) y2 -= dist; g2d.drawLine(x1, y1, x2, y2); } // Draws the highlight of the specified edge protected void drawEdgeHighlight(Graphics2D g2d, DirectedEdge edge) { GraphPoint originPoint = edge.getOriginPoint(); GraphPoint terminusPoint = edge.getTerminusPoint(); int midX = originPoint.x + (terminusPoint.x - originPoint.x) / 2; int midY = originPoint.y + (terminusPoint.y - originPoint.y) / 2; int minX = midX - 10; int minY = midY - 10; int maxX = midX + 10; int maxY = midY + 10; g2d.drawLine(minX, minY, maxX, minY); g2d.drawLine(maxX, minY, maxX, maxY); g2d.drawLine(maxX, maxY, minX, maxY); g2d.drawLine(minX, maxY, minX, minY); } @Override public void printComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; DirectedEdge[] edges = null; Vertex[] vertices = null; Vertex startVertex = null; int i = 0; g.setColor(Color.white); g2d.fillRect(0,0,getWidth(),getHeight()); if (mGraphModelManager != null) { // Get the edges and vertices from the model edges = mGraphModelManager.getModel().getEdges(); vertices = mGraphModelManager.getModel().getVertices(); //graphable = mGraphModelManager.getModel(). // Draw the edges for (i = 0; i < edges.length; i++) { mDirectedEdgeRenderer.draw(g2d, edges[i]); } // Draw the vertices for (i = 0; i < vertices.length; i++) { mVertexRenderer.draw(g2d, vertices[i]); } g2d.setPaint(mStartPaint); // Highlight the start vertex if there is one startVertex = mGraphModelManager.getModel().getStartVertex(); if (startVertex != null) { drawVertexHighlight(g2d, startVertex, 1); } } } protected void superPaint(Graphics g) { super.paintComponent(g); } }