1 package de.fzi.wim.guibase.graphview.view;
2
3 import java.awt.Color;
4 import java.awt.Graphics2D;
5 import java.awt.Point;
6 import java.awt.Rectangle;
7
8 import de.fzi.wim.guibase.graphview.graph.*;
9 import de.fzi.wim.guibase.graphview.controller.*;
10
11 /***
12 * The painter that paints the edge as the arrow.
13 */
14 public class ArrowEdgePainter extends AbstractEdgePainter {
15 /*** The length of the arrow base. */
16 protected static final double ARROW_BASE_LENGTH=3.0;
17 /*** An instance. */
18 public static final EdgePainter INSTANCE=new ArrowEdgePainter();
19
20 /***
21 * Paints the supplied edge.
22 *
23 * @param graphPane the graph pane
24 * @param g the graphics
25 * @param edge the edge to paint
26 */
27 public void paintEdge(JGraphPane graphPane,Graphics2D g,Edge edge) {
28 HighlightingManipulator highlightingManipulator=(HighlightingManipulator)graphPane.getManipulator(HighlightingManipulator.NAME);
29 boolean isHighlighted=highlightingManipulator!=null && highlightingManipulator.getHighlightedEdge()==edge;
30 DraggingManipulator draggingManipulator=(DraggingManipulator)graphPane.getManipulator(DraggingManipulator.NAME);
31 boolean isDragging=draggingManipulator!=null && draggingManipulator.getDraggedEdge()==edge;
32 Point from=graphPane.getScreenPointForNode(edge.getFrom());
33 Point to=graphPane.getScreenPointForNode(edge.getTo());
34 Color color=g.getColor();
35 g.setColor(getEdgeColor(edge,isHighlighted,isDragging));
36 paintArrow(g,from.x,from.y,to.x,to.y);
37 g.setColor(color);
38 }
39 /***
40 * Returns the color for the edge.
41 *
42 * @param edge the edge to be painted
43 * @param isHighlighted <code>true</code> if the edge is highlighted
44 * @param isDragging <code>true</code> if the edge is being dragged
45 * @return the color for the edge
46 */
47 protected Color getEdgeColor(Edge edge,boolean isHighlighted,boolean isDragging) {
48 if (isHighlighted || isDragging)
49 return Color.red;
50 else
51 return Color.gray;
52 }
53 /***
54 * Paints the arrow.
55 *
56 * @param g the graphics
57 * @param x1 the source x coordinate
58 * @param y1 the source y coordinate
59 * @param x2 the target x coordinate
60 * @param y2 the target y coordinate
61 */
62 public static void paintArrow(Graphics2D g,int x1,int y1,int x2,int y2) {
63 double dx;
64 double dy;
65 double deltaX=x1-x2;
66 double deltaY=y1-y2;
67 if (Math.abs(deltaY)>Math.abs(deltaX)) {
68 double slope=Math.abs(deltaX/deltaY);
69 dx=ARROW_BASE_LENGTH/Math.sqrt(1+slope*slope);
70 dy=dx*slope;
71 }
72 else {
73 double slope=Math.abs(deltaY/deltaX);
74 dy=ARROW_BASE_LENGTH/Math.sqrt(1+slope*slope);
75 dx=dy*slope;
76 }
77 if (deltaY>0)
78 dx*=-1;
79 if (deltaX<0)
80 dy*=-1;
81 int[] pointsX=new int[] { x2,(int)(x1-dx),(int)(x1+dx) };
82 int[] pointsY=new int[] { y2,(int)(y1-dy),(int)(y1+dy) };
83 g.fillPolygon(pointsX,pointsY,3);
84 }
85 /***
86 * Returns the distance of the point to the edge.
87 *
88 * @param graphPane the graph pane
89 * @param g the graphics object
90 * @param edge the edge
91 * @param point the point
92 * @return the distance of the point from the edge
93 */
94 public double screenDistanceFromEdge(JGraphPane graphPane,Graphics2D g,Edge edge,Point point) {
95 double px=point.x;
96 double py=point.y;
97 Point from=graphPane.getScreenPointForNode(edge.getFrom());
98 Point to=graphPane.getScreenPointForNode(edge.getTo());
99 double x1=from.x;
100 double y1=from.y;
101 double x2=to.x;
102 double y2=to.y;
103 if (px<Math.min(x1,x2)-8 || px>Math.max(x1,x2)+8 || py<Math.min(y1,y2)-8 || py>Math.max(y1,y2)+8)
104 return 1000;
105 double dist=1000;
106 if (x1-x2!=0)
107 dist=Math.abs((y2-y1)/(x2-x1)*(px-x1)+(y1-py));
108 if (y1-y2!=0)
109 dist=Math.min(dist,Math.abs((x2-x1)/(y2-y1)*(py-y1)+(x1-px)));
110 return dist;
111 }
112 /***
113 * Returns the outer rectangle of the edge on screen.
114 *
115 * @param graphPane the graph pane
116 * @param edge the edge
117 * @param edgeScreenRectangle the rectangle receiving the edge's coordinates
118 */
119 public void getEdgeScreenBounds(JGraphPane graphPane,Edge edge,Rectangle edgeScreenRectangle) {
120 Point from=graphPane.getScreenPointForNode(edge.getFrom());
121 Point to=graphPane.getScreenPointForNode(edge.getTo());
122 edgeScreenRectangle.setBounds(Math.min(from.x,to.x),Math.min(from.y,to.y),Math.abs(to.x-from.x)+1,Math.abs(to.y-from.y)+1);
123 }
124 }