1
2
3
4
5
6
7
8
9
10
11
12 package edu.uci.ics.jung.visualization.control;
13
14 import java.awt.BasicStroke;
15 import java.awt.Color;
16 import java.awt.Cursor;
17 import java.awt.Dimension;
18 import java.awt.Graphics2D;
19 import java.awt.Point;
20 import java.awt.RenderingHints;
21 import java.awt.Toolkit;
22 import java.awt.event.MouseEvent;
23 import java.awt.event.MouseListener;
24 import java.awt.event.MouseMotionListener;
25 import java.awt.geom.Point2D;
26 import java.awt.image.BufferedImage;
27 import java.util.Collections;
28
29 import edu.uci.ics.jung.visualization.Layer;
30 import edu.uci.ics.jung.visualization.VisualizationViewer;
31 import edu.uci.ics.jung.visualization.transform.MutableTransformer;
32
33
34
35
36
37
38
39
40
41 public class RotatingGraphMousePlugin extends AbstractGraphMousePlugin
42 implements MouseListener, MouseMotionListener {
43
44
45
46
47 public RotatingGraphMousePlugin() {
48 this(MouseEvent.BUTTON1_MASK | MouseEvent.SHIFT_MASK);
49 }
50
51
52
53
54
55 public RotatingGraphMousePlugin(int modifiers) {
56 super(modifiers);
57 Dimension cd = Toolkit.getDefaultToolkit().getBestCursorSize(16,16);
58 BufferedImage cursorImage =
59 new BufferedImage(cd.width,cd.height,BufferedImage.TYPE_INT_ARGB);
60 Graphics2D g = cursorImage.createGraphics();
61 g.addRenderingHints(Collections.singletonMap(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
62 g.setColor(new Color(0,0,0,0));
63 g.fillRect(0,0,16,16);
64
65 int left = 0;
66 int top = 0;
67 int right = 15;
68 int bottom = 15;
69
70 g.setColor(Color.white);
71 g.setStroke(new BasicStroke(3));
72
73 g.drawLine(left+2,top+6,right/2+1,top);
74 g.drawLine(right/2+1,top,right-2,top+5);
75
76 g.drawLine(left+2,bottom-6,right/2,bottom);
77 g.drawLine(right/2,bottom,right-2,bottom-6);
78
79 g.drawLine(left+2,top+6,left+5,top+6);
80 g.drawLine(left+2,top+6,left+2,top+3);
81
82 g.drawLine(right-2,bottom-6,right-6,bottom-6);
83 g.drawLine(right-2, bottom-6,right-2,bottom-3);
84
85
86 g.setColor(Color.black);
87 g.setStroke(new BasicStroke(1));
88
89 g.drawLine(left+2,top+6,right/2+1,top);
90 g.drawLine(right/2+1,top,right-2,top+5);
91
92 g.drawLine(left+2,bottom-6,right/2,bottom);
93 g.drawLine(right/2,bottom,right-2,bottom-6);
94
95 g.drawLine(left+2,top+6,left+5,top+6);
96 g.drawLine(left+2,top+6,left+2,top+3);
97
98 g.drawLine(right-2,bottom-6,right-6,bottom-6);
99 g.drawLine(right-2, bottom-6,right-2,bottom-3);
100
101 g.dispose();
102
103 cursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImage, new Point(), "RotateCursor");
104 }
105
106
107
108
109
110
111 public void mousePressed(MouseEvent e) {
112 VisualizationViewer vv = (VisualizationViewer)e.getSource();
113 boolean accepted = checkModifiers(e);
114 down = e.getPoint();
115 if(accepted) {
116 vv.setCursor(cursor);
117 }
118 }
119
120
121
122
123 public void mouseReleased(MouseEvent e) {
124 VisualizationViewer vv = (VisualizationViewer)e.getSource();
125 down = null;
126 vv.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
127 }
128
129
130
131
132
133 public void mouseDragged(MouseEvent e) {
134 if(down == null) return;
135 VisualizationViewer vv = (VisualizationViewer)e.getSource();
136 boolean accepted = checkModifiers(e);
137 if(accepted) {
138 MutableTransformer modelTransformer =
139 vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT);
140
141 vv.setCursor(cursor);
142
143 Point2D center = vv.getCenter();
144 Point2D q = down;
145 Point2D p = e.getPoint();
146 Point2D v1 = new Point2D.Double(center.getX()-p.getX(), center.getY()-p.getY());
147 Point2D v2 = new Point2D.Double(center.getX()-q.getX(), center.getY()-q.getY());
148 double theta = angleBetween(v1, v2);
149 modelTransformer.rotate(theta, vv.getRenderContext().getMultiLayerTransformer().inverseTransform(Layer.VIEW, center));
150 down.x = e.getX();
151 down.y = e.getY();
152
153 e.consume();
154 }
155 }
156
157
158
159
160
161
162
163
164 protected double angleBetween(Point2D v1, Point2D v2) {
165 double x1 = v1.getX();
166 double y1 = v1.getY();
167 double x2 = v2.getX();
168 double y2 = v2.getY();
169
170 double cross = x1*y2 - x2*y1;
171 int cw = 1;
172 if(cross > 0) {
173 cw = -1;
174 }
175
176 double angle =
177 cw*Math.acos( ( x1*x2 + y1*y2 ) /
178 ( Math.sqrt( x1*x1 + y1*y1 ) *
179 Math.sqrt( x2*x2 + y2*y2 ) ) );
180 if(Double.isNaN(angle)) {
181 angle = 0;
182 }
183 return angle;
184 }
185
186 public void mouseClicked(MouseEvent e) {
187 }
188
189 public void mouseEntered(MouseEvent e) {
190 }
191
192 public void mouseExited(MouseEvent e) {
193 }
194
195 public void mouseMoved(MouseEvent e) {
196 }
197 }