# Coverage details for edu.uci.ics.jung.visualization.ShapePickSupport

Line | Hits | Source
--- | --- | ---
1 |  | `/*`
2 |  | `* Copyright (c) 2005, the JUNG Project and the Regents of the University`
3 |  | `* of California`
4 |  | `* All rights reserved.`
5 |  | `*`
6 |  | `* This software is open-source under the BSD license; see either`
7 |  | `* "license.txt" or`
8 |  | `* http://jung.sourceforge.net/license.txt for a description.`
9 |  | `* Created on Mar 11, 2005`
10 |  | `*`
11 |  | `*/`
12 |  | `package edu.uci.ics.jung.visualization;`
13 |  | ``
14 |  | `import java.awt.Shape;`
15 |  | `import java.awt.geom.AffineTransform;`
16 |  | `import java.awt.geom.GeneralPath;`
17 |  | `import java.awt.geom.PathIterator;`
18 |  | `import java.awt.geom.Point2D;`
19 |  | `import java.awt.geom.Rectangle2D;`
20 |  | `import java.util.ConcurrentModificationException;`
21 |  | `import java.util.Iterator;`
22 |  | ``
23 |  | `import edu.uci.ics.jung.graph.Edge;`
24 |  | `import edu.uci.ics.jung.graph.Vertex;`
25 |  | `import edu.uci.ics.jung.utils.Pair;`
26 |  | `import edu.uci.ics.jung.visualization.transform.LayoutTransformer;`
27 |  | `import edu.uci.ics.jung.visualization.transform.MutableAffineTransformer;`
28 |  | `import edu.uci.ics.jung.visualization.transform.Transformer;`
29 |  | ``
30 |  | `/**`
31 |  | `* ShapePickSupport provides access to Vertices and Edges based on`
32 |  | `* their actual shapes.`
33 |  | `*`
34 |  | `* @author Tom Nelson - RABA Technologies`
35 |  | `*`
36 |  | `*/`
37 |  | `public class ShapePickSupport implements PickSupport {`
38 |  | ``
39 |  | `protected HasGraphLayout hasGraphLayout;`
40 |  | `protected HasShapeFunctions hasShapeFunctions;`
41 |  | `protected float pickSize;`
42 |  | `protected LayoutTransformer layoutTransformer;`
43 |  | ``
44 |  | `/**`
45 |  | `* Create an instance.`
46 |  | `* The HasGraphLayout is used as the source of the current`
47 |  | `* Graph Layout. The HasShapes`
48 |  | `* is used to access the VertexShapes and the EdgeShapes`
49 |  | `* @param hasGraphLayout source of the current layout.`
50 |  | `* @param hasShapeFunctions source of Vertex and Edge shapes.`
51 |  | `* @param pickSize how large to make the pick footprint for line edges`
52 |  | `*/`
53 |  | `public ShapePickSupport(HasGraphLayout hasGraphLayout,`
54 |  | `LayoutTransformer layoutTransformer, HasShapeFunctions hasShapeFunctions,`
55 | 0 | `float pickSize) {`
56 | 0 | `this.hasGraphLayout = hasGraphLayout;`
57 | 0 | `this.hasShapeFunctions = hasShapeFunctions;`
58 | 0 | `this.layoutTransformer = layoutTransformer;`
59 | 0 | `this.pickSize = pickSize;`
60 | 0 | `}`
61 |  | ``
62 | 0 | `public ShapePickSupport(float pickSize) {`
63 | 0 | `this.pickSize = pickSize;`
64 | 0 | `}`
65 |  | ``
66 |  | `/**`
67 |  | `* Create an instance.`
68 |  | `* The pickSize footprint defaults to 2.`
69 |  | `*/`
70 |  | `public ShapePickSupport() {`
71 | 0 | `this(2);`
72 | 0 | `}`
73 |  | ``
74 |  | `/**`
75 |  | `* called by a HasLayout impl (like VisualizationViewer) when this`
76 |  | `* PickSupport impl is`
77 |  | `* added to it. This allows the PickSupport to`
78 |  | `* always get the current Layout and the current Renderer`
79 |  | `* from thecomponent it supports picking on.`
80 |  | `*/`
81 |  | `public void setHasGraphLayout(HasGraphLayout hasGraphLayout) {`
82 | 0 | `this.hasGraphLayout = hasGraphLayout;`
83 | 0 | `}`
84 |  | ``
85 |  | `/**`
86 |  | `* @param hasShapes The hasShapes to set.`
87 |  | `*/`
88 |  | `public void setHasShapes(HasShapeFunctions hasShapes) {`
89 | 0 | `this.hasShapeFunctions = hasShapes;`
90 | 0 | `}`
91 |  | `/**`
92 |  | `* @return Returns the layoutTransformer.`
93 |  | `*/`
94 |  | `public LayoutTransformer getLayoutTransformer() {`
95 | 0 | `return layoutTransformer;`
96 |  | `}`
97 |  | ``
98 |  | `/**`
99 |  | `* When this PickSupport is set on a VisualizationViewer,`
100 |  | `* the VisualizationViewer calls this method to pass its`
101 |  | `* layout transformer in`
102 |  | `*`
103 |  | `* @param layoutTransformer The layoutTransformer to set.`
104 |  | `*/`
105 |  | `public void setLayoutTransformer(LayoutTransformer layoutTransformer) {`
106 | 0 | `this.layoutTransformer = layoutTransformer;`
107 | 0 | `}`
108 |  | ``
109 |  | `/**`
110 |  | `* Iterates over Vertices, checking to see if x,y is contained in the`
111 |  | `* Vertex's Shape. If (x,y) is contained in more than one vertex, use`
112 |  | `* the vertex whose center is closest to the pick point.`
113 |  | `* @see edu.uci.ics.jung.visualization.PickSupport#getVertex(double, double)`
114 |  | `*/`
115 |  | `public Vertex getVertex(double x, double y) {`
116 | 0 | `Layout layout = hasGraphLayout.getGraphLayout();`
117 |  | ``
118 | 0 | `Vertex closest = null;`
119 | 0 | `double minDistance = Double.MAX_VALUE;`
120 |  | `while(true) {`
121 |  | `try {`
122 | 0 | `for (Iterator iter=layout.getGraph().getVertices().iterator(); iter.hasNext(); ) {`
123 | 0 | `if(hasShapeFunctions != null) {`
124 | 0 | `Vertex v = (Vertex) iter.next();`
125 | 0 | `Shape shape = hasShapeFunctions.getVertexShapeFunction().getShape(v);`
126 |  | `// transform the vertex location to screen coords`
127 | 0 | `Point2D p = layoutTransformer.layoutTransform(layout.getLocation(v));`
128 | 0 | `if(p == null) continue;`
129 | 0 | `AffineTransform xform =`
130 |  | `AffineTransform.getTranslateInstance(p.getX(), p.getY());`
131 | 0 | `shape = xform.createTransformedShape(shape);`
132 |  | `// see if this vertex center is closest to the pick point`
133 |  | `// among any other containing vertices`
134 | 0 | `if(shape.contains(x, y)) {`
135 |  | ``
136 | 0 | `Rectangle2D bounds = shape.getBounds2D();`
137 | 0 | `double dx = bounds.getCenterX() - x;`
138 | 0 | `double dy = bounds.getCenterY() - y;`
139 | 0 | `double dist = dx * dx + dy * dy;`
140 | 0 | `if (dist < minDistance) {`
141 | 0 | `minDistance = dist;`
142 | 0 | `closest = v;`
143 |  | `}`
144 |  | `}`
145 |  | `}`
146 |  | `}`
147 | 0 | `break;`
148 | 0 | `} catch(ConcurrentModificationException cme) {}`
149 |  | `}`
150 | 0 | `return closest;`
151 |  | `}`
152 |  | ``
153 |  | `/**`
154 |  | `* return an edge whose shape intersects the 'pickArea' footprint of the passed`
155 |  | `* x,y, coordinates.`
156 |  | `*/`
157 |  | `public Edge getEdge(double x, double y) {`
158 | 0 | `Layout layout = hasGraphLayout.getGraphLayout();`
159 |  | ``
160 |  | `// as a Line has no area, we can't always use edgeshape.contains(point) so we`
161 |  | `// make a small rectangular pickArea around the point and check if the`
162 |  | `// edgeshape.intersects(pickArea)`
163 | 0 | `Rectangle2D pickArea =`
164 |  | `new Rectangle2D.Float((float)x-pickSize/2,(float)y-pickSize/2,pickSize,pickSize);`
165 | 0 | `Edge closest = null;`
166 | 0 | `double minDistance = Double.MAX_VALUE;`
167 |  | `while(true) {`
168 |  | `try {`
169 | 0 | `for (Iterator iter=layout.getGraph().getEdges().iterator(); iter.hasNext(); ) {`
170 |  | ``
171 | 0 | `if(hasShapeFunctions != null) {`
172 | 0 | `Edge e = (Edge) iter.next();`
173 | 0 | `Pair pair = e.getEndpoints();`
174 | 0 | `Vertex v1 = (Vertex)pair.getFirst();`
175 | 0 | `Vertex v2 = (Vertex)pair.getSecond();`
176 | 0 | `boolean isLoop = v1.equals(v2);`
177 | 0 | `Point2D p1 = layoutTransformer.layoutTransform(layout.getLocation(v1));`
178 | 0 | `Point2D p2 = layoutTransformer.layoutTransform(layout.getLocation(v2));`
179 | 0 | `if(p1 == null || p2 == null) continue;`
180 | 0 | `float x1 = (float) p1.getX();`
181 | 0 | `float y1 = (float) p1.getY();`
182 | 0 | `float x2 = (float) p2.getX();`
183 | 0 | `float y2 = (float) p2.getY();`
184 |  | ``
185 |  | `// translate the edge to the starting vertex`
186 | 0 | `AffineTransform xform = AffineTransform.getTranslateInstance(x1, y1);`
187 |  | ``
188 | 0 | `Shape edgeShape = hasShapeFunctions.getEdgeShapeFunction().getShape(e);`
189 | 0 | `if(isLoop) {`
190 |  | `// make the loops proportional to the size of the vertex`
191 | 0 | `Shape s2 = hasShapeFunctions.getVertexShapeFunction().getShape(v2);`
192 | 0 | `Rectangle2D s2Bounds = s2.getBounds2D();`
193 | 0 | `xform.scale(s2Bounds.getWidth(),s2Bounds.getHeight());`
194 |  | `// move the loop so that the nadir is centered in the vertex`
195 | 0 | `xform.translate(0, -edgeShape.getBounds2D().getHeight()/2);`
196 |  | `} else {`
197 | 0 | `float dx = x2 - x1;`
198 | 0 | `float dy = y2 - y1;`
199 |  | `// rotate the edge to the angle between the vertices`
200 | 0 | `double theta = Math.atan2(dy,dx);`
201 | 0 | `xform.rotate(theta);`
202 |  | `// stretch the edge to span the distance between the vertices`
203 | 0 | `float dist = (float) Math.sqrt(dx*dx + dy*dy);`
204 | 0 | `xform.scale(dist, 1.0f);`
205 |  | `}`
206 |  | ``
207 |  | `// transform the edge to its location and dimensions`
208 | 0 | `edgeShape = xform.createTransformedShape(edgeShape);`
209 |  | ``
210 |  | `// because of the transform, the edgeShape is now a GeneralPath`
211 |  | `// see if this edge is the closest of any that intersect`
212 | 0 | `if(edgeShape.intersects(pickArea)) {`
213 | 0 | `float cx=0;`
214 | 0 | `float cy=0;`
215 | 0 | `float[] f = new float[6];`
216 | 0 | `PathIterator pi = new GeneralPath(edgeShape).getPathIterator(null);`
217 | 0 | `if(pi.isDone()==false) {`
218 | 0 | `pi.next();`
219 | 0 | `pi.currentSegment(f);`
220 | 0 | `cx = f[0];`
221 | 0 | `cy = f[1];`
222 | 0 | `if(pi.isDone()==false) {`
223 | 0 | `pi.currentSegment(f);`
224 | 0 | `cx = f[0];`
225 | 0 | `cy = f[1];`
226 |  | `}`
227 |  | `}`
228 | 0 | `float dx = (float) (cx - x);`
229 | 0 | `float dy = (float) (cy - y);`
230 | 0 | `float dist = dx * dx + dy * dy;`
231 | 0 | `if (dist < minDistance) {`
232 | 0 | `minDistance = dist;`
233 | 0 | `closest = e;`
234 |  | `}`
235 |  | `}`
236 |  | `}`
237 |  | `}`
238 | 0 | `break;`
239 | 0 | `} catch(ConcurrentModificationException cme) {}`
240 |  | `}`
241 | 0 | `return closest;`
242 |  | `}`
243 |  | ``
244 |  | `/**`
245 |  | `* <code>ShapePickSupport</code> gets its layout from its VisualizationViewer, so this`
246 |  | `* method currently does nothing.`
247 |  | `* @see edu.uci.ics.jung.visualization.PickSupport#setLayout(edu.uci.ics.jung.visualization.Layout)`
248 |  | `*/`
249 | 0 | `public void setLayout(Layout layout) {}`
250 |  | `}`

this report was generated by version 1.0.5 of jcoverage. visit www.jcoverage.com for updates. | copyright © 2003, jcoverage ltd. all rights reserved. Java is a trademark of Sun Microsystems, Inc. in the United States and other countries.