Sadly I can't do it inside a Behavoir class (I must think about that but
...). I could change my code to set the TransformGroup only after
finishing the movement. But for my application it isn't nice. And I
still wonder if it will be a solution for the problem. The out of memory
will come! Later - but it will. I don't want to provide a Button for
recreate the scene graph - it is too much Microsoft solution for me...

I haven't been following this thread too closely, but it seems like what you need is the trick done in some of the Java 3D demos where you queue AWT events and then process them from the Java 3D behavior thread.

Java 3D has some synchronization issues with lots of different behaviors,
so what I've done is have a single behavior in my system that wakes up
each frame, and does everything that needs to be done.  Doing everything
in the same behavior solved a lot of those issues.

Here's the code I wrote.  I adapted this from a couple of the demos.
First, there's AwtEventQueuer.  You instantiate this class on your
canvas and it queues all mouse events.  Not handling the mouse events
in the Swing thread makes sure you don't miss any, and handling them
in the behavior thread makes sure you don't have synchronization issues.

The class was modified to only keep one drag event per frame.  You may
want to take that out.



import java.awt.event.*;
import java.awt.*;
import java.util.*;

import javax.swing.event.MouseInputListener;

/**
 * AWT event callbacks such as these are called from the AWT thread.
 * If you take too long handling an event, subsequent events will be
 * lost.  Therefore, the best way to handle AWT events is to queue
 * them to handle later.<p>
 *
 * The other advantage of doing it this way is that we can
 * synchronize handling keyboard and mouse events with other
 * updates to the system.  We don't need to handle them when
 * AWT gives them to use, we can handle them whenever we want.<p>
 *
 * This code is based on code in the Java 3D utilities source,
 * KeyNavigatorBehavior.java and MouseBehavior.java.  Those
 * use behavior post to inform other behaviors of the existence
 * of events.  We are just going to check each frame, so we
 * don't need that additional overhead.<p>
 *
 * The code has been optimized so that only the last drag or move
 * event is in the queue.
 */
public class AwtEventQueuer implements KeyListener, MouseInputListener {

       private static final int VERBOSE = 1;
       private static final int DEBUG = 0;

private LinkedList eventq = new LinkedList();

private boolean enabled = true;

       private MouseEvent moveEvent = null;
       private MouseEvent dragEvent = null;



       /**
        * Enables capturing of AWT events.  The default.
        */
       public void enable()
       {
               enabled = true;
       } // End of enable



       /**
        * Disables capturing of AWT events.  AWT events are ignored until enable() is
        * called.  Events already in the queue may still be fetched.
        */
       public void disable()
       {
               enabled = false;
       } // End of disable



       /**
        * Add an event to the Event Queue.
        * @param e The event.
        */
       public void addEvent(InputEvent e)
       {
               if (enabled) {
                       synchronized (eventq) {

                               // Don't want multiple drag or move events in queue
                               if (e instanceof MouseEvent) {
                                       int id = ((MouseEvent)e).getID();
                                       if (id == MouseEvent.MOUSE_DRAGGED) {
                                               if (dragEvent != null) 
eventq.remove(dragEvent);
                                               dragEvent = (MouseEvent)e;
                                       } else if (id == MouseEvent.MOUSE_MOVED) {
                                               if (moveEvent != null) 
eventq.remove(moveEvent);
                                               moveEvent = (MouseEvent)e;
                                       }
                               }
                               eventq.add(e);
                       }
               }
       } // End of addEvent



       /**
        * Get the next InputEvent from the event queue.
        * @return The event.
        */
       public InputEvent getNextEvent()
       {
               InputEvent e;
               synchronized (eventq) {
                       if (eventq.size() == 0) e = null;
                       else {
                               e = (InputEvent)(eventq.removeFirst());
                               if (e instanceof MouseEvent) {
                                       int id = ((MouseEvent)e).getID();
                                       if (id == MouseEvent.MOUSE_DRAGGED) dragEvent = 
null;
                                       else if (id == MouseEvent.MOUSE_MOVED) 
moveEvent = null;
                               }
                       }
               }
               return e;
       } // End of getNextEvent



       public void keyPressed(KeyEvent e) {
               if ((DEBUG & VERBOSE) != 0)  System.out.println("keyPressed: " + e);
               addEvent(e);
       } // End of keyPressed



       public void keyReleased(KeyEvent e) {
               if ((DEBUG & VERBOSE) != 0)  System.out.println("keyReleased: " + e);
               addEvent(e);
       } // End of keyReleased



       public void keyTyped(KeyEvent e) {
               if ((DEBUG & VERBOSE) != 0)  System.out.println("keyTyped: " + e);
               addEvent(e);
       } // End of keyTyped



       public void mouseClicked(MouseEvent e) {
               if ((DEBUG & VERBOSE) != 0)  System.out.println("mouseClicked: " + e);
               addEvent(e);
       } // End of mouseClicked



       public void mouseEntered(MouseEvent e) {
               if ((DEBUG & VERBOSE) != 0)  System.out.println("mouseEntered: " + e);
               addEvent(e);
       } // End of mouseEntered



       public void mouseExited(MouseEvent e) {
               if ((DEBUG & VERBOSE) != 0)  System.out.println("mouseExited: " + e);
               addEvent(e);
       } // End of mouseExited



       public void mousePressed(MouseEvent e) {
               if ((DEBUG & VERBOSE) != 0)  System.out.println("mousePressed: " + e);
               addEvent(e);
       } // End of mousePressed



       public void mouseReleased(MouseEvent e) {
               if ((DEBUG & VERBOSE) != 0)  System.out.println("mouseReleased: " + e);
               addEvent(e);
       } // End of mouseReleased



       public void mouseDragged(MouseEvent e) {
               if ((DEBUG & VERBOSE) != 0)  System.out.println("mouseDragged: " + e);
               addEvent(e);
       } // End of mouseDragged



       public void mouseMoved(MouseEvent e) {
               if ((DEBUG & VERBOSE) != 0)  System.out.println("mouseMoved: " + e);
               addEvent(e);
       } // End of mouseMoved



       public AwtEventQueuer(Component c)
       {
               c.addMouseListener(this);
               c.addMouseMotionListener(this);
               c.addKeyListener(this);
       } // End of constructor

} // End of class AwtEventQueuer



So once you put this class on your canvas, you want to create a behavior
that wakes up each frame and empties the queue.  This is where all your
standard keyboard and mouse handling goes, including your picking code,
only now you're in the behavior thread.  Here's a small section of
my code:



       /**
        * Empties all AWT events that have been queued in AwtEventQueuer.
        *
        */
       public void eachFrame()
       {
               AwtEventQueuer aeq = re.getAwtEventQueuer();
               int indexOfClosest = -3;

               InputEvent ie = aeq.getNextEvent();
               while (ie != null) {
                       if (ie instanceof MouseEvent) {

                               mevent = (MouseEvent) ie;
                               mousex = mevent.getPoint().x;
                               mousey = mevent.getPoint().y;
                               boolean consumeEvent = false;

                               if (mevent.getID() == MouseEvent.MOUSE_PRESSED) {
                                       if (mevent.getButton() == MouseEvent.BUTTON1) {
                                               leftButtonDown = true;
                                               indexOfClosest = 
findPickableObject(mousex, mousey);
                                               if ((indexOfClosest == -2) && 
(upArrowDown == false)) {
                                                       re.upArrowDown();
                                                       upArrowDown = true;
                                                       consumeEvent = true;
                                               }
                                       }
                               } else if (mevent.getID() == MouseEvent.MOUSE_RELEASED)
                               {
                               } else if (mevent.getID() == MouseEvent.MOUSE_DRAGGED) {
                               }

                               if ((navigator != null) && !consumeEvent)
                                       navigator.processMouseEvent(mevent);

                       } else if (ie instanceof KeyEvent)
                       {
                               KeyEvent kevent = (KeyEvent) ie;
                               int keyCode = kevent.getKeyCode();
                               if (kevent.getID() == KeyEvent.KEY_PRESSED)
                               {
                                       char keyChar = kevent.getKeyChar();
                                       switch (keyChar)
                                       {
                                               case 'l' :
                                                       break;
                                               case 'a' :
                                                       break;
                                       }
                               }
                               if (navigator != null)
                                       navigator.processKeyEvent(kevent);
                               c3d.requestFocus();
                       }
                       ie = aeq.getNextEvent();
               }
       }

-Paul

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to