1 /*
2 * $RCSfile: MouseWheelZoom.java,v $
3 *
4 * Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistribution of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * - Redistribution in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Sun Microsystems, Inc. or the names of
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * This software is provided "AS IS," without a warranty of any
23 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
24 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
26 * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
27 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
28 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
29 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
30 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
31 * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
32 * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
33 * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGES.
35 *
36 * You acknowledge that this software is not designed, licensed or
37 * intended for use in the design, construction, operation or
38 * maintenance of any nuclear facility.
39 *
40 * $Revision: 1.1 $
41 * $Date: 2009/04/08 06:31:15 $
42 * $State: Exp $
43 */
44
45 package edu.uci.ics.jung.visualization3d.control;
46
47 import java.awt.*;
48 import java.awt.event.*;
49 import java.util.*;
50 import javax.media.j3d.*;
51 import javax.vecmath.*;
52
53 import com.sun.j3d.utils.behaviors.mouse.MouseBehavior;
54 import com.sun.j3d.utils.behaviors.mouse.MouseBehaviorCallback;
55
56
57 /**
58 * MouseWheelZoom is a Java3D behavior object that lets users control the
59 * Z axis translation of an object via mouse wheel.
60 * @since Java 3D 1.3.2
61 */
62
63 public class MouseWheelZoom extends MouseBehavior {
64
65 double z_factor = .1;
66 Vector3d translation = new Vector3d();
67
68 private MouseBehaviorCallback callback = null;
69
70 /**
71 * Creates a zoom behavior given the transform group.
72 * @param transformGroup The transformGroup to operate on.
73 */
74 public MouseWheelZoom(TransformGroup transformGroup) {
75 super(transformGroup);
76 }
77
78 /**
79 * Creates a default mouse zoom behavior.
80 **/
81 public MouseWheelZoom() {
82 super(0);
83 }
84
85 /**
86 * Creates a zoom behavior.
87 * Note that this behavior still needs a transform
88 * group to work on (use setTransformGroup(tg)) and
89 * the transform group must add this behavior.
90 * @param flags
91 */
92 public MouseWheelZoom(int flags) {
93 super(flags);
94 }
95
96 /**
97 * Creates a zoom behavior that uses AWT listeners and behavior
98 * posts rather than WakeupOnAWTEvent. The behavior is added to the
99 * specified Component. A null component can be passed to specify
100 * the behavior should use listeners. Components can then be added
101 * to the behavior with the addListener(Component c) method.
102 * @param c The Component to add the MouseListener
103 * and MouseMotionListener to.
104 * @since Java 3D 1.3.2
105 */
106 public MouseWheelZoom(Component c) {
107 super(c, 0);
108 }
109
110 /**
111 * Creates a zoom behavior that uses AWT listeners and behavior
112 * posts rather than WakeupOnAWTEvent. The behaviors is added to
113 * the specified Component and works on the given TransformGroup.
114 * @param c The Component to add the MouseListener and
115 * MouseMotionListener to. A null component can be passed to specify
116 * the behavior should use listeners. Components can then be added
117 * to the behavior with the addListener(Component c) method.
118 * @param transformGroup The TransformGroup to operate on.
119 * @since Java 3D 1.3.2
120 */
121 public MouseWheelZoom(Component c, TransformGroup transformGroup) {
122 super(c, transformGroup);
123 }
124
125 /**
126 * Creates a zoom behavior that uses AWT listeners and behavior
127 * posts rather than WakeupOnAWTEvent. The behavior is added to the
128 * specified Component. A null component can be passed to specify
129 * the behavior should use listeners. Components can then be added
130 * to the behavior with the addListener(Component c) method.
131 * Note that this behavior still needs a transform
132 * group to work on (use setTransformGroup(tg)) and the transform
133 * group must add this behavior.
134 * @param flags interesting flags (wakeup conditions).
135 * @since Java 3D 1.3.2
136 */
137 public MouseWheelZoom(Component c, int flags) {
138 super(c, flags);
139 }
140
141 public void initialize() {
142 super.initialize();
143 if ((flags & INVERT_INPUT) == INVERT_INPUT) {
144 z_factor *= -1;
145 invert = true;
146 }
147 }
148
149 /**
150 * Return the y-axis movement multipler.
151 **/
152 public double getFactor() {
153 return z_factor;
154 }
155
156 /**
157 * Set the wheel units movement multipler with factor.
158 **/
159 public void setFactor( double factor) {
160 z_factor = factor;
161 }
162
163
164 public void processStimulus(Enumeration criteria) {
165 WakeupCriterion wakeup;
166 AWTEvent[] events;
167 MouseEvent evt;
168
169 while (criteria.hasMoreElements()) {
170 wakeup = (WakeupCriterion) criteria.nextElement();
171 if (wakeup instanceof WakeupOnAWTEvent) {
172 events = ((WakeupOnAWTEvent)wakeup).getAWTEvent();
173 if (events.length > 0) {
174 evt = (MouseEvent) events[events.length-1];
175 doProcess(evt);
176 }
177 }
178
179 else if (wakeup instanceof WakeupOnBehaviorPost) {
180 while (true) {
181 synchronized (mouseq) {
182 if (mouseq.isEmpty()) break;
183 evt = (MouseEvent)mouseq.remove(0);
184 // consolidate MOUSE_WHEEL events
185 while((evt.getID() == MouseEvent.MOUSE_WHEEL) &&
186 !mouseq.isEmpty() &&
187 (((MouseEvent)mouseq.get(0)).getID() ==
188 MouseEvent.MOUSE_WHEEL)) {
189 evt = (MouseEvent)mouseq.remove(0);
190 }
191 }
192 doProcess(evt);
193 }
194 }
195
196 }
197 wakeupOn(mouseCriterion);
198 }
199
200 void doProcess(MouseEvent evt) {
201 int units = 0;
202
203 processMouseEvent(evt);
204
205 if ((evt.getID() == MouseEvent.MOUSE_WHEEL)) {
206 MouseWheelEvent wheelEvent = (MouseWheelEvent)evt;
207 if (wheelEvent.getScrollType() == wheelEvent.WHEEL_UNIT_SCROLL ) {
208 units = wheelEvent.getUnitsToScroll();
209 }
210
211 if (!reset) {
212 transformGroup.getTransform(currXform);
213
214 translation.z = units*z_factor;
215
216 transformX.set(translation);
217
218 if (invert) {
219 currXform.mul(currXform, transformX);
220 } else {
221 currXform.mul(transformX, currXform);
222 }
223
224 transformGroup.setTransform(currXform);
225
226 transformChanged( currXform );
227
228 if (callback!=null)
229 callback.transformChanged( MouseBehaviorCallback.ZOOM,
230 currXform );
231
232 }
233 else {
234 reset = false;
235 }
236 }
237 }
238
239
240 /**
241 * Users can overload this method which is called every time
242 * the Behavior updates the transform
243 *
244 * Default implementation does nothing
245 */
246 public void transformChanged( Transform3D transform ) {
247 }
248
249 /**
250 * The transformChanged method in the callback class will
251 * be called every time the transform is updated
252 */
253 public void setupCallback( MouseBehaviorCallback callback ){
254 this.callback = callback;
255 }
256 }
257