View Javadoc

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