1
2
3
4
5
6
7
8 package org.glassbox.graphview;
9
10 import de.fzi.wim.guibase.graphview.view.AbstractEdgePainter;
11 import de.fzi.wim.guibase.graphview.view.JGraphPane;
12 import de.fzi.wim.guibase.graphview.graph.Edge;
13
14 import java.awt.geom.CubicCurve2D;
15 import java.awt.geom.Point2D;
16 import java.awt.*;
17
18 /***
19 An abstract painter for CubicCurve edges with optional pointers, ideal for GraphViz layouted edges.
20 */
21 public abstract class AbstractCubicCurveReadEdgePainter extends AbstractEdgePainter implements ZoomableEdgePainter {
22 private CubicCurve2D _curve;
23 private Polygon _arrow;
24 private int _arrowwidth, _arrowlength;
25 private double _aw, _al;
26 private Point _p1, _cp1, _cp2, _p2;
27
28 protected AbstractCubicCurveReadEdgePainter(int arrowlength, int arrowwidth) {
29 _curve = new CubicCurve2D.Double();
30 _p1 = new Point();
31 _cp1 = new Point();
32 _cp2 = new Point();
33 _p2 = new Point();
34 _arrow = new Polygon();
35 _arrowwidth = arrowwidth;
36 _arrowlength = arrowlength;
37 setZoomFactor(1d);
38 }
39
40 public void setZoomFactor(double zf) {
41 _al = (int)((double)_arrowlength * zf);
42 _aw = (int)((double)_arrowwidth * zf);
43 }
44
45 private static double calc(double c, double m) {
46 return Math.sqrt(c*c/(1+m*m));
47 }
48
49 public void paintEdge(JGraphPane grp, Graphics2D g, Edge e) {
50 Point2D[] cp = getControlPoints(e);
51
52 g.setColor(getEdgeColor(grp, e));
53 g.setStroke(getEdgeStroke(grp, e));
54
55
56 for (int i=0; i+3<cp.length; i+=3) {
57 grp.graphToScreenPoint(cp[i], _p1);
58 grp.graphToScreenPoint(cp[i+1], _cp1);
59 grp.graphToScreenPoint(cp[i+2], _cp2);
60 grp.graphToScreenPoint(cp[i+3], _p2);
61 _curve.setCurve(_p1.x, _p1.y, _cp1.x, _cp1.y, _cp2.x, _cp2.y, _p2.x, _p2.y);
62 g.draw(_curve);
63
64
65
66
67
68
69
70
71
72
73
74
75 }
76
77
78 g.setColor(getPointerColor(grp, e));
79
80 if (hasArrowAtStart(e)) {
81
82 Point2D p1 = cp[cp.length-2];
83 Point2D p2 = cp[cp.length-1];
84 grp.graphToScreenPoint(p1, _p1);
85 grp.graphToScreenPoint(p2, _p2);
86 ArrowTools.getReadBar(_p1, _p2, _aw, _arrow);
87 g.fillPolygon(_arrow);
88
89
90 Point2D p0 = cp[0];
91 Point2D ps = getPointOfArrowAtStart(e);
92 grp.graphToScreenPoint(p0, _p1);
93 grp.graphToScreenPoint(ps, _p2);
94 ArrowTools.getArrowShape(_p1, _p2, _al, _aw, _arrow);
95 g.fillPolygon(_arrow);
96 }
97
98 if (hasArrowAtEnd(e)) {
99
100 Point2D p0 = cp[0];
101 Point2D ps = cp[1];
102 grp.graphToScreenPoint(p0, _p1);
103 grp.graphToScreenPoint(ps, _p2);
104 ArrowTools.getReadBar(_p1, _p2, _aw, _arrow);
105 g.fillPolygon(_arrow);
106
107
108 Point2D pn = cp[cp.length-1];
109 Point2D pe = getPointOfArrowAtEnd(e);
110 grp.graphToScreenPoint(pn, _p1);
111 grp.graphToScreenPoint(pe, _p2);
112 ArrowTools.getArrowShape(_p1, _p2, _al, _aw, _arrow);
113 g.fillPolygon(_arrow);
114 }
115
116
117 g.setColor(getTextColor(grp, e));
118 g.setFont(getFont(grp, e));
119
120 if (hasLabel(e)) {
121 Point2D lp = getLabelPosition(e);
122 grp.graphToScreenPoint(lp, _p1);
123 String en = getEdgeLabel(grp, e);
124 int lw = grp.getFontMetrics(g.getFont()).stringWidth(en);
125 int lh = grp.getFontMetrics(g.getFont()).getHeight();
126 int asc = grp.getFontMetrics(g.getFont()).getAscent();
127 int x = _p1.x - lw/2;
128 int y = _p1.y - lh/2 + asc;
129 g.drawString(en, x, y);
130 }
131 }
132
133 public void getEdgeScreenBounds(JGraphPane grp, Edge edge, Rectangle scr) {
134 Point2D[] cp = getControlPoints(edge);
135
136 boolean first = true;
137 for (int i=0; i+3<cp.length; i+=3) {
138 grp.graphToScreenPoint(cp[i], _p1);
139 grp.graphToScreenPoint(cp[i+1], _cp1);
140 grp.graphToScreenPoint(cp[i+2], _cp2);
141 grp.graphToScreenPoint(cp[i+3], _p2);
142 _curve.setCurve(_p1.x, _p1.y, _cp1.x, _cp1.y, _cp2.x, _cp2.y, _p2.x, _p2.y);
143 if (first) {
144 first = false;
145 scr.setBounds(_curve.getBounds());
146 } else {
147 scr.add(_curve.getBounds());
148 }
149 }
150
151 if (hasArrowAtStart(edge)) {
152 Point2D p0 = cp[0];
153 Point2D ps = getPointOfArrowAtStart(edge);
154 grp.graphToScreenPoint(p0, _p1);
155 grp.graphToScreenPoint(ps, _p2);
156 ArrowTools.getArrowShape(_p1, _p2, _al, _aw, _arrow);
157 scr.add(_arrow.getBounds());
158 }
159
160 if (hasArrowAtEnd(edge)) {
161 Point2D pn = cp[cp.length-1];
162 Point2D pe = getPointOfArrowAtEnd(edge);
163 grp.graphToScreenPoint(pn, _p1);
164 grp.graphToScreenPoint(pe, _p2);
165 ArrowTools.getArrowShape(_p1, _p2, _al, _aw, _arrow);
166 scr.add(_arrow.getBounds());
167 }
168
169 scr.x -= 1;
170 scr.y -= 1;
171 scr.width += 2;
172 scr.height += 2;
173 }
174
175 public double screenDistanceFromEdge(JGraphPane grp,Edge edge,Point point) {
176
177 return super.screenDistanceFromEdge(grp, edge, point);
178 }
179
180 protected abstract Point2D[] getControlPoints(Edge e);
181
182 protected abstract boolean hasArrowAtStart(Edge e);
183
184 protected abstract boolean hasArrowAtEnd(Edge e);
185
186 protected abstract Point2D getPointOfArrowAtStart(Edge e);
187
188 protected abstract Point2D getPointOfArrowAtEnd(Edge e);
189
190 protected abstract boolean hasLabel(Edge e);
191
192 protected abstract Point2D getLabelPosition(Edge e);
193
194 protected abstract Color getEdgeColor(JGraphPane grp, Edge e);
195
196 protected abstract Color getPointerColor(JGraphPane grp, Edge e);
197
198 protected abstract Color getTextColor(JGraphPane grp, Edge e);
199
200 protected abstract Font getFont(JGraphPane grp, Edge e);
201
202 protected abstract Stroke getEdgeStroke(JGraphPane grp, Edge e);
203
204 protected abstract String getEdgeLabel(JGraphPane grp, Edge e);
205 }