001: /*
002: * $RCSfile: MouseBehavior.java,v $
003: *
004: * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * - Redistribution of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * - Redistribution in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * Neither the name of Sun Microsystems, Inc. or the names of
019: * contributors may be used to endorse or promote products derived
020: * from this software without specific prior written permission.
021: *
022: * This software is provided "AS IS," without a warranty of any
023: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
024: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
025: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
026: * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
027: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
028: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
029: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
030: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
031: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
032: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
033: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
034: * POSSIBILITY OF SUCH DAMAGES.
035: *
036: * You acknowledge that this software is not designed, licensed or
037: * intended for use in the design, construction, operation or
038: * maintenance of any nuclear facility.
039: *
040: * $Revision: 1.6 $
041: * $Date: 2007/02/09 17:20:12 $
042: * $State: Exp $
043: */
044:
045: package com.sun.j3d.utils.behaviors.mouse;
046:
047: import java.awt.*;
048: import java.awt.event.*;
049: import java.util.*;
050: import javax.media.j3d.*;
051: import javax.vecmath.*;
052: import com.sun.j3d.internal.J3dUtilsI18N;
053:
054: /**
055: * Base class for all mouse manipulators (see MouseRotate, MouseZoom
056: * and MouseTranslate for
057: * examples of how to extend this base class).
058: */
059:
060: public abstract class MouseBehavior extends Behavior implements
061: MouseListener, MouseMotionListener, MouseWheelListener {
062:
063: private boolean listener = false;
064:
065: protected WakeupCriterion[] mouseEvents;
066: protected WakeupOr mouseCriterion;
067: protected int x, y;
068: protected int x_last, y_last;
069: protected TransformGroup transformGroup;
070: protected Transform3D transformX;
071: protected Transform3D transformY;
072: protected Transform3D currXform;
073: protected boolean buttonPress = false;
074: protected boolean reset = false;
075: protected boolean invert = false;
076: protected boolean wakeUp = false;
077: protected int flags = 0;
078:
079: // to queue the mouse events
080: protected LinkedList mouseq;
081:
082: // true if this behavior is enable
083: protected boolean enable = true;
084:
085: /**
086: * Set this flag if you want to manually wakeup the behavior.
087: */
088: public static final int MANUAL_WAKEUP = 0x1;
089:
090: /**
091: * Set this flag if you want to invert the inputs. This is useful when
092: * the transform for the view platform is being changed instead of the
093: * transform for the object.
094: */
095: public static final int INVERT_INPUT = 0x2;
096:
097: /**
098: * Creates a mouse behavior object with a given transform group.
099: * @param transformGroup The transform group to be manipulated.
100: */
101: public MouseBehavior(TransformGroup transformGroup) {
102: super ();
103: // need to remove old behavior from group
104: this .transformGroup = transformGroup;
105: currXform = new Transform3D();
106: transformX = new Transform3D();
107: transformY = new Transform3D();
108: reset = true;
109: }
110:
111: /**
112: * Initializes standard fields. Note that this behavior still
113: * needs a transform group to work on (use setTransformGroup(tg)) and
114: * the transform group must add this behavior.
115: * @param format flags
116: */
117: public MouseBehavior(int format) {
118: super ();
119: flags = format;
120: currXform = new Transform3D();
121: transformX = new Transform3D();
122: transformY = new Transform3D();
123: reset = true;
124: }
125:
126: /**
127: * Creates a mouse behavior that uses AWT listeners and behavior
128: * posts rather than WakeupOnAWTEvent. The behaviors is added to
129: * the specified Component and works on the given TransformGroup.
130: * A null component can be passed to specify the behaviors should use
131: * listeners. Components can then be added to the behavior with the
132: * addListener(Component c) method.
133: * @param c The Component to add the MouseListener and
134: * MouseMotionListener to.
135: * @param transformGroup The TransformGroup to operate on.
136: * @since Java 3D 1.2.1
137: */
138: public MouseBehavior(Component c, TransformGroup transformGroup) {
139: this (transformGroup);
140: if (c != null) {
141: c.addMouseListener(this );
142: c.addMouseMotionListener(this );
143: c.addMouseWheelListener(this );
144: }
145: listener = true;
146: }
147:
148: /**
149: * Creates a mouse behavior that uses AWT listeners and behavior
150: * posts rather than WakeupOnAWTEvent. The behavior is added to the
151: * specified Component. A null component can be passed to specify
152: * the behavior should use listeners. Components can then be added
153: * to the behavior with the addListener(Component c) method.
154: * Note that this behavior still needs a transform
155: * group to work on (use setTransformGroup(tg)) and the transform
156: * group must add this behavior.
157: * @param format interesting flags (wakeup conditions).
158: * @since Java 3D 1.2.1
159: */
160: public MouseBehavior(Component c, int format) {
161: this (format);
162: if (c != null) {
163: c.addMouseListener(this );
164: c.addMouseMotionListener(this );
165: c.addMouseWheelListener(this );
166: }
167: listener = true;
168: }
169:
170: /**
171: * Swap a new transformGroup replacing the old one. This allows
172: * manipulators to operate on different nodes.
173: *
174: * @param transformGroup The *new* transform group to be manipulated.
175: */
176: public void setTransformGroup(TransformGroup transformGroup) {
177: // need to remove old behavior from group
178: this .transformGroup = transformGroup;
179: currXform = new Transform3D();
180: transformX = new Transform3D();
181: transformY = new Transform3D();
182: reset = true;
183: }
184:
185: /**
186: * Return the transformGroup on which this node is operating
187: */
188: public TransformGroup getTransformGroup() {
189: return this .transformGroup;
190: }
191:
192: /** Initializes the behavior.
193: */
194:
195: public void initialize() {
196: mouseEvents = new WakeupCriterion[4];
197:
198: if (!listener) {
199: mouseEvents[0] = new WakeupOnAWTEvent(
200: MouseEvent.MOUSE_DRAGGED);
201: mouseEvents[1] = new WakeupOnAWTEvent(
202: MouseEvent.MOUSE_PRESSED);
203: mouseEvents[2] = new WakeupOnAWTEvent(
204: MouseEvent.MOUSE_RELEASED);
205: mouseEvents[3] = new WakeupOnAWTEvent(
206: MouseEvent.MOUSE_WHEEL);
207: } else {
208: mouseEvents[0] = new WakeupOnBehaviorPost(this ,
209: MouseEvent.MOUSE_DRAGGED);
210: mouseEvents[1] = new WakeupOnBehaviorPost(this ,
211: MouseEvent.MOUSE_PRESSED);
212: mouseEvents[2] = new WakeupOnBehaviorPost(this ,
213: MouseEvent.MOUSE_RELEASED);
214: mouseEvents[3] = new WakeupOnBehaviorPost(this ,
215: MouseEvent.MOUSE_WHEEL);
216: mouseq = new LinkedList();
217: }
218: mouseCriterion = new WakeupOr(mouseEvents);
219: wakeupOn(mouseCriterion);
220: x = 0;
221: y = 0;
222: x_last = 0;
223: y_last = 0;
224: }
225:
226: /**
227: * Manually wake up the behavior. If MANUAL_WAKEUP flag was set upon
228: * creation, you must wake up this behavior each time it is handled.
229: */
230:
231: public void wakeup() {
232: wakeUp = true;
233: }
234:
235: /**
236: * Handles mouse events
237: */
238: public void processMouseEvent(MouseEvent evt) {
239: if (evt.getID() == MouseEvent.MOUSE_PRESSED) {
240: buttonPress = true;
241: return;
242: } else if (evt.getID() == MouseEvent.MOUSE_RELEASED) {
243: buttonPress = false;
244: wakeUp = false;
245: }
246: /*
247: else if (evt.getID() == MouseEvent.MOUSE_MOVED) {
248: // Process mouse move event
249: }
250: else if (evt.getID() == MouseEvent.MOUSE_WHEEL) {
251: // Process mouse wheel event
252: }
253: */
254: }
255:
256: /**
257: * All mouse manipulators must implement this.
258: */
259: public abstract void processStimulus(Enumeration criteria);
260:
261: /**
262: * Adds this behavior as a MouseListener, mouseWheelListener and MouseMotionListener to
263: * the specified component. This method can only be called if
264: * the behavior was created with one of the constructors that takes
265: * a Component as a parameter.
266: * @param c The component to add the MouseListener, MouseWheelListener and
267: * MouseMotionListener to.
268: * @exception IllegalStateException if the behavior was not created
269: * as a listener
270: * @since Java 3D 1.2.1
271: */
272: public void addListener(Component c) {
273: if (!listener) {
274: throw new IllegalStateException(J3dUtilsI18N
275: .getString("Behavior0"));
276: }
277: c.addMouseListener(this );
278: c.addMouseMotionListener(this );
279: c.addMouseWheelListener(this );
280: }
281:
282: public void mouseClicked(MouseEvent e) {
283: }
284:
285: public void mouseEntered(MouseEvent e) {
286: }
287:
288: public void mouseExited(MouseEvent e) {
289: }
290:
291: public void mousePressed(MouseEvent e) {
292: // System.out.println("mousePressed");
293:
294: // add new event to the queue
295: // must be MT safe
296: if (enable) {
297: synchronized (mouseq) {
298: mouseq.add(e);
299: // only need to post if this is the only event in the queue
300: if (mouseq.size() == 1)
301: postId(MouseEvent.MOUSE_PRESSED);
302: }
303: }
304: }
305:
306: public void mouseReleased(MouseEvent e) {
307: // System.out.println("mouseReleased");
308:
309: // add new event to the queue
310: // must be MT safe
311: if (enable) {
312: synchronized (mouseq) {
313: mouseq.add(e);
314: // only need to post if this is the only event in the queue
315: if (mouseq.size() == 1)
316: postId(MouseEvent.MOUSE_RELEASED);
317: }
318: }
319: }
320:
321: public void mouseDragged(MouseEvent e) {
322: // System.out.println("mouseDragged");
323:
324: // add new event to the to the queue
325: // must be MT safe.
326: if (enable) {
327: synchronized (mouseq) {
328: mouseq.add(e);
329: // only need to post if this is the only event in the queue
330: if (mouseq.size() == 1)
331: postId(MouseEvent.MOUSE_DRAGGED);
332: }
333: }
334: }
335:
336: public void mouseMoved(MouseEvent e) {
337: }
338:
339: public void setEnable(boolean state) {
340: super .setEnable(state);
341: this .enable = state;
342: if (!enable && (mouseq != null)) {
343: mouseq.clear();
344: }
345: }
346:
347: public void mouseWheelMoved(MouseWheelEvent e) {
348: System.out.println("MouseBehavior : mouseWheel enable = "
349: + enable);
350:
351: // add new event to the to the queue
352: // must be MT safe.
353: if (enable) {
354: synchronized (mouseq) {
355: mouseq.add(e);
356: // only need to post if this is the only event in the queue
357: if (mouseq.size() == 1)
358: postId(MouseEvent.MOUSE_WHEEL);
359: }
360: }
361: }
362: }
|