1
2
3
4
5
6
7
8
9
10 package edu.uci.ics.jung.visualization.annotations;
11
12 import java.awt.Component;
13 import java.awt.Dimension;
14 import java.awt.Shape;
15 import java.awt.geom.AffineTransform;
16 import java.awt.geom.Point2D;
17 import java.awt.geom.Rectangle2D;
18 import java.util.Collection;
19 import java.util.HashSet;
20 import java.util.Set;
21
22 import edu.uci.ics.jung.visualization.Layer;
23 import edu.uci.ics.jung.visualization.RenderContext;
24 import edu.uci.ics.jung.visualization.transform.AffineTransformer;
25 import edu.uci.ics.jung.visualization.transform.LensTransformer;
26 import edu.uci.ics.jung.visualization.transform.MutableTransformer;
27
28
29
30
31
32
33
34
35 public class AnnotationManager {
36
37 protected AnnotationRenderer annotationRenderer = new AnnotationRenderer();
38 protected AnnotationPaintable lowerAnnotationPaintable;
39 protected AnnotationPaintable upperAnnotationPaintable;
40
41 protected RenderContext<?,?> rc;
42 protected AffineTransformer transformer;
43
44 public AnnotationManager(RenderContext<?,?> rc) {
45 this.rc = rc;
46 this.lowerAnnotationPaintable = new AnnotationPaintable(rc, annotationRenderer);
47 this.upperAnnotationPaintable = new AnnotationPaintable(rc, annotationRenderer);
48
49 MutableTransformer mt = rc.getMultiLayerTransformer().getTransformer(Layer.LAYOUT);
50 if(mt instanceof AffineTransformer) {
51 transformer = (AffineTransformer)mt;
52 } else if(mt instanceof LensTransformer) {
53 transformer = (AffineTransformer)((LensTransformer)mt).getDelegate();
54 }
55
56 }
57
58 public AnnotationPaintable getAnnotationPaintable(Annotation.Layer layer) {
59 if(layer == Annotation.Layer.LOWER) {
60 return this.lowerAnnotationPaintable;
61 }
62 if(layer == Annotation.Layer.UPPER) {
63 return this.upperAnnotationPaintable;
64 }
65 return null;
66 }
67
68 public void add(Annotation.Layer layer, Annotation<?> annotation) {
69 if(layer == Annotation.Layer.LOWER) {
70 this.lowerAnnotationPaintable.add(annotation);
71 }
72 if(layer == Annotation.Layer.UPPER) {
73 this.upperAnnotationPaintable.add(annotation);
74 }
75 }
76
77 public void remove(Annotation<?> annotation) {
78 this.lowerAnnotationPaintable.remove(annotation);
79 this.upperAnnotationPaintable.remove(annotation);
80 }
81
82 protected AnnotationPaintable getLowerAnnotationPaintable() {
83 return lowerAnnotationPaintable;
84 }
85
86 protected AnnotationPaintable getUpperAnnotationPaintable() {
87 return upperAnnotationPaintable;
88 }
89
90 @SuppressWarnings("unchecked")
91 public Annotation getAnnotation(Point2D p) {
92 Set<Annotation> annotations = new HashSet<Annotation>(lowerAnnotationPaintable.getAnnotations());
93 annotations.addAll(upperAnnotationPaintable.getAnnotations());
94 return getAnnotation(p, annotations);
95 }
96
97 @SuppressWarnings("unchecked")
98 public Annotation getAnnotation(Point2D p, Collection<Annotation> annotations) {
99 double closestDistance = Double.MAX_VALUE;
100 Annotation closestAnnotation = null;
101 for(Annotation annotation : annotations) {
102 Object ann = annotation.getAnnotation();
103 if(ann instanceof Shape) {
104 Point2D ip = rc.getMultiLayerTransformer().inverseTransform(p);
105 Shape shape = (Shape)ann;
106 if(shape.contains(ip)) {
107
108 Rectangle2D shapeBounds = shape.getBounds2D();
109 Point2D shapeCenter = new Point2D.Double(shapeBounds.getCenterX(), shapeBounds.getCenterY());
110 double distanceSq = shapeCenter.distanceSq(ip);
111 if(distanceSq < closestDistance) {
112 closestDistance = distanceSq;
113 closestAnnotation = annotation;
114 }
115 }
116 } else if(ann instanceof String) {
117
118 Point2D ip = rc.getMultiLayerTransformer().inverseTransform(Layer.VIEW, p);
119 Point2D ap = annotation.getLocation();
120 String label = (String)ann;
121 Component component = prepareRenderer(rc, annotationRenderer, label);
122
123 AffineTransform base = new AffineTransform(transformer.getTransform());
124 double rotation = transformer.getRotation();
125
126 AffineTransform unrotate =
127 AffineTransform.getRotateInstance(-rotation, ap.getX(), ap.getY());
128 base.concatenate(unrotate);
129
130 Dimension d = component.getPreferredSize();
131 Rectangle2D componentBounds = new Rectangle2D.Double(ap.getX(), ap.getY(), d.width, d.height);
132
133 Shape componentBoundsShape = base.createTransformedShape(componentBounds);
134 Point2D componentCenter = new Point2D.Double(componentBoundsShape.getBounds().getCenterX(),
135 componentBoundsShape.getBounds().getCenterY());
136 if(componentBoundsShape.contains(ip)) {
137 double distanceSq = componentCenter.distanceSq(ip);
138 if(distanceSq < closestDistance) {
139 closestDistance = distanceSq;
140 closestAnnotation = annotation;
141 }
142 }
143
144 }
145 }
146 return closestAnnotation;
147 }
148
149 public Component prepareRenderer(RenderContext<?,?> rc, AnnotationRenderer annotationRenderer, Object value) {
150 return annotationRenderer.getAnnotationRendererComponent(rc.getScreenDevice(), value);
151 }
152
153
154
155
156
157 }