diff options
author | Kevin Rushforth <[email protected]> | 2007-03-29 20:34:17 +0000 |
---|---|---|
committer | Kevin Rushforth <[email protected]> | 2007-03-29 20:34:17 +0000 |
commit | bb5331e867166954565f09ebfae6e9ef8e7d91f3 (patch) | |
tree | 18518419afe10d51b5946aaa837c09fff61fe6f3 | |
parent | d319a907da13b127971aec547022a7dce8cb9c05 (diff) |
Fixed issue 458: Canvas3D stops rendering on window close
git-svn-id: https://svn.java.net/svn/j3d-core~svn/trunk@803 ba19aa83-45c5-6ac9-afd3-db810772062c
4 files changed, 148 insertions, 135 deletions
diff --git a/src/classes/share/javax/media/j3d/Canvas3D.java b/src/classes/share/javax/media/j3d/Canvas3D.java index 778b98e..607c010 100644 --- a/src/classes/share/javax/media/j3d/Canvas3D.java +++ b/src/classes/share/javax/media/j3d/Canvas3D.java @@ -619,8 +619,12 @@ public class Canvas3D extends Canvas { boolean firstPaintCalled = false; - // This reflects whether or not this canvas has seen an addNotify. + // This reflects whether or not this canvas has seen an addNotify. It is + // forced to true for off-screen canvases boolean added = false; + + // Flag indicating whether addNotify has been called (so we don't process it twice). + private boolean addNotifyCalled = false; // This is the id for the underlying graphics context structure. Context ctx = null; @@ -885,10 +889,14 @@ public class Canvas3D extends Canvas { EventCatcher eventCatcher; // The view event catcher for this canvas. - CanvasViewEventCatcher canvasViewEventCatcher; - - // The parent window for this canvas. - private Container parent; + private CanvasViewEventCatcher canvasViewEventCatcher; + + // The top-level parent window for this canvas. + private Window windowParent; + + // Issue 458 - list of all parent containers for this canvas + // (includes top-level parent window) + private LinkedList<Container> containerParentList = new LinkedList<Container>(); // flag that indicates if light has changed boolean lightChanged = false; @@ -1180,6 +1188,45 @@ public class Canvas3D extends Canvas { } /** + * Method to return whether or not the Canvas3D is recursively visible; + * that is, whether the Canas3D is currently visible on the screen. Note + * that we don't directly use isShowing() because that won't work for an + * auto-offScreen Canvas3D. + */ + private boolean isRecursivelyVisible() { + Container parent = getParent(); + return isVisible() && parent != null && parent.isShowing(); + } + + /** + * Method to return whether the top-level Window parent is iconified + */ + private boolean isIconified() { + if (windowParent instanceof Frame) { + return (((Frame)windowParent).getExtendedState() & Frame.ICONIFIED) != 0; + } + + return false; + } + + // Issue 458 - evaluate this Canvas3D's visibility whenever we get a + // Window or Component Event that could change it. + void evaluateVisiblilty() { + boolean nowVisible = isRecursivelyVisible() && !isIconified(); + + // Only need to reevaluate and repaint if visibility has changed + if (this.visible != nowVisible) { + this.visible = nowVisible; + evaluateActive(); + if (nowVisible) { + if (view != null) { + view.repaint(); + } + } + } + } + + /** * This version looks for the view and notifies it. */ void redraw() { @@ -1228,6 +1275,11 @@ public class Canvas3D extends Canvas { * to function properly. */ public void addNotify() { + // Return immediately if addNotify called twice with no removeNotify + if (addNotifyCalled) { + return; + } + addNotifyCalled = true; // Issue 131: This method is now being called by JCanvas3D for its // off-screen Canvas3D, so we need to handle off-screen properly here. @@ -1257,36 +1309,29 @@ public class Canvas3D extends Canvas { } screen.addUser(this); - parent = this.getParent(); - while (!(parent instanceof Window)) { - parent = parent.getParent(); - } - - ((Window)parent).addWindowListener(eventCatcher); - - if (VirtualUniverse.mc.isD3D()) { - ((Window)parent).addComponentListener(eventCatcher); - } + // Issue 458 - Add the eventCatcher as a component listener for each + // parent container in the window hierarchy + assert containerParentList.isEmpty(); - if(canvasViewEventCatcher.parentList.size() > 0) { - Component comp; - //Release and clear. - for(int i=0; i<canvasViewEventCatcher.parentList.size(); i++) { - comp = (Component)canvasViewEventCatcher.parentList.get(i); - comp.removeComponentListener(canvasViewEventCatcher); + windowParent = null; + Container container = this.getParent(); + while (container != null) { + if (container instanceof Window) { + windowParent = (Window)container; } - canvasViewEventCatcher.parentList.clear(); + container.addComponentListener(eventCatcher); + container.addComponentListener(canvasViewEventCatcher); + containerParentList.add(container); + container = container.getParent(); } - Component parent = (Component) this.getParent(); - while(parent != null) { - parent.addComponentListener(canvasViewEventCatcher); - canvasViewEventCatcher.parentList.add(parent); - parent = parent.getParent(); - } - // Need to traverse up the parent and add listener. + this.addComponentListener(eventCatcher); this.addComponentListener(canvasViewEventCatcher); + if (windowParent != null) { + windowParent.addWindowListener(eventCatcher); + } + synchronized(dirtyMaskLock) { cvDirtyMask[0] |= MOVED_OR_RESIZED_DIRTY; cvDirtyMask[1] |= MOVED_OR_RESIZED_DIRTY; @@ -1340,6 +1385,11 @@ public class Canvas3D extends Canvas { * method for Java 3D to function properly. */ public void removeNotify() { + // Return immediately if addNotify not called first + if (!addNotifyCalled) { + return; + } + addNotifyCalled = false; // Do nothing for manually-rendered off-screen canvases if (manualRendering) { @@ -1400,11 +1450,16 @@ public class Canvas3D extends Canvas { super.removeNotify(); - // This may happen if user explicity call this before - // addNotify() + // Release and clear. + for (Container container : containerParentList) { + container.removeComponentListener(eventCatcher); + container.removeComponentListener(canvasViewEventCatcher); + } + containerParentList.clear(); + this.removeComponentListener(eventCatcher); + this.removeComponentListener(canvasViewEventCatcher); if (eventCatcher != null) { - this.removeComponentListener(eventCatcher); this.removeFocusListener(eventCatcher); this.removeKeyListener(eventCatcher); this.removeMouseListener(eventCatcher); @@ -1413,31 +1468,9 @@ public class Canvas3D extends Canvas { eventCatcher.reset(); } - - if (canvasViewEventCatcher != null) { - if (canvasViewEventCatcher.parentList.size() > 0) { - //Release and clear. - for(int i=canvasViewEventCatcher.parentList.size()-1; i>=0; i--) { - Component comp = - (Component)canvasViewEventCatcher.parentList.get(i); - comp.removeComponentListener(canvasViewEventCatcher); - } - canvasViewEventCatcher.parentList.clear(); - } - - // Need to traverse up the parent and remove listener. - this.removeComponentListener(canvasViewEventCatcher); - } - - if (parent != null) { - ((Window)parent).removeWindowListener(eventCatcher); - if (VirtualUniverse.mc.isD3D()) { - ((Window)parent).removeComponentListener(eventCatcher); - } - } - - if (parent != null) { - parent.requestFocus(); + if (windowParent != null) { + windowParent.removeWindowListener(eventCatcher); + windowParent.requestFocus(); } added = false; @@ -1452,8 +1485,7 @@ public class Canvas3D extends Canvas { // Fix for issue 102 removing strong reference and avoiding memory leak // due retention of parent container - - this.parent = null; + this.windowParent = null; } // This decides if the canvas is active diff --git a/src/classes/share/javax/media/j3d/CanvasViewEventCatcher.java b/src/classes/share/javax/media/j3d/CanvasViewEventCatcher.java index b1403b4..20af887 100644 --- a/src/classes/share/javax/media/j3d/CanvasViewEventCatcher.java +++ b/src/classes/share/javax/media/j3d/CanvasViewEventCatcher.java @@ -22,12 +22,11 @@ import java.awt.event.*; * */ class CanvasViewEventCatcher extends ComponentAdapter { - + // The canvas associated with this event catcher - Canvas3D canvas; - ArrayList parentList = new ArrayList(); - static final boolean DEBUG = false; - + private Canvas3D canvas; + private static final boolean DEBUG = false; + CanvasViewEventCatcher(Canvas3D c) { canvas = c; } diff --git a/src/classes/share/javax/media/j3d/EventCatcher.java b/src/classes/share/javax/media/j3d/EventCatcher.java index 3dc7e7e..9532387 100644 --- a/src/classes/share/javax/media/j3d/EventCatcher.java +++ b/src/classes/share/javax/media/j3d/EventCatcher.java @@ -26,13 +26,12 @@ class EventCatcher extends Object implements ComponentListener, FocusListener, // The canvas associated with this event catcher private Canvas3D canvas; - static final boolean DEBUG = false; + private static final boolean DEBUG = false; private boolean stopped = false; /** * flags for event listeners */ - private boolean componentEvents = false; private boolean focusEvents = false; private boolean keyEvents = false; private boolean mouseEvents = false; @@ -44,29 +43,10 @@ class EventCatcher extends Object implements ComponentListener, FocusListener, canvas = c; if (VirtualUniverse.mc.isD3D()) { - enableComponentEvents(); enableKeyEvents(); } } - - void enableComponentEvents() { - - if (!componentEvents) { - canvas.addComponentListener(this); - componentEvents = true; - } - } - - /* - void disableComponentEvents() { - if (componentEvents) { - canvas.removeComponentListener(this); - componentEvents = false; - } - } - */ - void enableFocusEvents() { if (!focusEvents) { canvas.addFocusListener(this); @@ -165,46 +145,51 @@ class EventCatcher extends Object implements ComponentListener, FocusListener, public void componentResized(ComponentEvent e) { if (e.getSource() == canvas) { + if (DEBUG) { + System.out.println(e); + } canvas.sendEventToBehaviorScheduler(e); - canvas.visible = true; if (VirtualUniverse.mc.isD3D()) { canvas.notifyD3DPeer(Canvas3D.RESIZE); } - canvas.evaluateActive(); - repaint(); - if (DEBUG) { - System.out.println(e); - } + canvas.evaluateVisiblilty(); + canvas.redraw(); } } - public void componentHidden(ComponentEvent e) { - canvas.sendEventToBehaviorScheduler(e); - canvas.visible = false; - if (DEBUG) { - System.out.println(e); - } + public void componentMoved(ComponentEvent e) { + if (e.getSource() == canvas) { + if (DEBUG) { + System.out.println(e); + } + canvas.sendEventToBehaviorScheduler(e); + + // Issue 458 - the following is not needed for a move +// if (VirtualUniverse.mc.isD3D()) { +// canvas.notifyD3DPeer(Canvas3D.RESIZE); +// } +// canvas.evaluateVisiblilty(true); + } } - public void componentMoved(ComponentEvent e) { - canvas.sendEventToBehaviorScheduler(e); - if (VirtualUniverse.mc.isD3D()) { - canvas.notifyD3DPeer(Canvas3D.RESIZE); - } - repaint(); + public void componentHidden(ComponentEvent e) { if (DEBUG) { System.out.println(e); } + if (e.getSource() == canvas) { + canvas.sendEventToBehaviorScheduler(e); + } + canvas.evaluateVisiblilty(); } public void componentShown(ComponentEvent e) { - canvas.sendEventToBehaviorScheduler(e); - canvas.visible = true; - canvas.evaluateActive(); - repaint(); if (DEBUG) { System.out.println(e); } + if (e.getSource() == canvas) { + canvas.sendEventToBehaviorScheduler(e); + } + canvas.evaluateVisiblilty(); } public void focusGained(FocusEvent e) { @@ -335,19 +320,16 @@ class EventCatcher extends Object implements ComponentListener, FocusListener, System.out.println(e); } } - - - public void windowActivated(WindowEvent e) { - windowOpened(e); - } + /* + * WindowListener methods + */ public void windowClosed(WindowEvent e) { if (DEBUG) { System.out.println(e); } canvas.sendEventToBehaviorScheduler(e); - canvas.visible = false; - canvas.evaluateActive(); + // Issue 458 - Don't set canvas visible to false } public void windowClosing(WindowEvent e) { @@ -355,8 +337,14 @@ class EventCatcher extends Object implements ComponentListener, FocusListener, System.out.println(e); } canvas.sendEventToBehaviorScheduler(e); - canvas.visible = false; - canvas.evaluateActive(); + // Issue 458 - Don't set canvas.visible to false + } + + public void windowActivated(WindowEvent e) { + if (DEBUG) { + System.out.println(e); + } + canvas.sendEventToBehaviorScheduler(e); } public void windowDeactivated(WindowEvent e) { @@ -371,11 +359,10 @@ class EventCatcher extends Object implements ComponentListener, FocusListener, System.out.println(e); } canvas.sendEventToBehaviorScheduler(e); - canvas.visible = true; - if (canvas.view != null) + if (canvas.view != null) { canvas.view.sendEventToSoundScheduler(e); - canvas.evaluateActive(); - repaint(); + } + canvas.evaluateVisiblilty(); } public void windowIconified(WindowEvent e) { @@ -383,10 +370,10 @@ class EventCatcher extends Object implements ComponentListener, FocusListener, System.out.println(e); } canvas.sendEventToBehaviorScheduler(e); - canvas.visible = false; - if (canvas.view != null) + if (canvas.view != null) { canvas.view.sendEventToSoundScheduler(e); - canvas.evaluateActive(); + } + canvas.evaluateVisiblilty(); } public void windowOpened(WindowEvent e) { @@ -394,21 +381,12 @@ class EventCatcher extends Object implements ComponentListener, FocusListener, System.out.println(e); } canvas.sendEventToBehaviorScheduler(e); - canvas.visible = true; - canvas.evaluateActive(); - repaint(); - } - - void repaint() { - if (canvas.view != null) { - canvas.view.repaint(); - } + canvas.evaluateVisiblilty(); } - + void reset() { focusEvents = false; keyEvents = false; - componentEvents = false; mouseEvents = false; mouseMotionEvents = false; mouseWheelEvents = false; diff --git a/src/classes/share/javax/media/j3d/VirtualUniverse.java b/src/classes/share/javax/media/j3d/VirtualUniverse.java index 6591471..9ed1d80 100644 --- a/src/classes/share/javax/media/j3d/VirtualUniverse.java +++ b/src/classes/share/javax/media/j3d/VirtualUniverse.java @@ -653,6 +653,8 @@ public class VirtualUniverse extends Object { } void enableComponentEvents() { + // Issue 458 - This method is now a noop + /* Enumeration cvs; Canvas3D cv; ViewPlatformRetained vp; @@ -668,12 +670,14 @@ public class VirtualUniverse extends Object { while(cvs.hasMoreElements()) { cv = (Canvas3D) cvs.nextElement(); // offscreen canvas does not have event catcher - if (cv.eventCatcher != null) + if (cv.eventCatcher != null) { cv.eventCatcher.enableComponentEvents(); + } } } } } + */ } void disableFocusEvents() { |