View Javadoc

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