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 }