From 9517d52c18bfa93d78e03f4c212757eda421afb6 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 14 Mar 2009 05:20:29 +0000 Subject: NEWT window closing: - New WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY and WindowListener.windowDestroyNotify() method. - Removed windowClosed() method for JNI hook - Added windowDestroyNotify() windowDestroyed(), where windowDestroyNotify() shall be called by the native implementation _before_ the window gets shutdown. The Window.java then sends a WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY event, and either Window.java or it's owner GLWindow.java issues the destroy() procedure. - Added GLEventListener.dispose(GLAutoDrawable), to allow user application to release GL ressources. Issued by GLWindow (-> see windowDestroyNotify()) - X11 impl intercepts WM_DELETE_WINDOW, using Atom, MacosX impl already uses the _before_ method (VERIFY), and Windows impl uses the WM_CLOSE event (VERIFY). JOGL2 dispose/destroy .. - Added GLEventListener.dispose() to GLCanvas and GLJpanel - GL* toString() rearrangement, assumes it is issued by GLContext(), which indeed is the core information node. - Added proper destroy() methods and calls, to achieve a proper resource release at destruction. Instrumentizing almost all classes with a destroy() method, so no release function lookup is necessary. - misc changes .. JOGL2 Demos - Fixed in regards to the above changes git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1867 232f8b59-042b-4e1e-8c03-345bb8c30851 --- src/classes/javax/media/opengl/awt/GLCanvas.java | 95 +++++++++++++++++++++--- 1 file changed, 84 insertions(+), 11 deletions(-) (limited to 'src/classes/javax/media/opengl/awt/GLCanvas.java') diff --git a/src/classes/javax/media/opengl/awt/GLCanvas.java b/src/classes/javax/media/opengl/awt/GLCanvas.java index 42700b9e8..040e78733 100644 --- a/src/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/classes/javax/media/opengl/awt/GLCanvas.java @@ -50,6 +50,10 @@ import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; +import java.awt.Container; +import java.awt.Window; +import java.awt.event.WindowEvent; +import java.awt.event.WindowAdapter; import java.awt.geom.*; import java.beans.*; import java.lang.reflect.*; @@ -156,7 +160,34 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { context.setSynchronized(true); } } - + + protected interface DestroyMethod { + public void destroyMethod(); + } + + protected final static Object addClosingListener(Component c, final DestroyMethod d) { + WindowAdapter cl = null; + Window w = getWindow(c); + if(null!=w) { + cl = new WindowAdapter() { + public void windowClosing(WindowEvent e) { + // we have to issue this call rigth away, + // otherwise the window gets destroyed + d.destroyMethod(); + } + }; + w.addWindowListener(cl); + } + return cl; + } + + protected final static Window getWindow(Component c) { + while ( c!=null && ! ( c instanceof Window ) ) { + c = c.getParent(); + } + return (Window)c; + } + /** * Overridden to choose a GraphicsConfiguration on a parent container's * GraphicsDevice because both devices @@ -252,9 +283,27 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { public void setRealized(boolean realized) { } + private Object closingListener = null; + private Object closingListenerLock = new Object(); + public void display() { maybeDoSingleThreadedWorkaround(displayOnEventDispatchThreadAction, displayAction); + if(null==closingListener) { + synchronized(closingListenerLock) { + if(null==closingListener) { + closingListener=addClosingListener(this, new DestroyMethod() { + public void destroyMethod() { destroy(); } }); + } + } + } + } + + /** + * Just an alias for removeNotify + */ + public void destroy() { + removeNotify(); } /** Overridden to cause OpenGL rendering to be performed during @@ -302,9 +351,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { disableBackgroundErase(); drawable.setRealized(true); } - if (DEBUG) { - System.err.println("GLCanvas.addNotify()"); - } } /** Overridden to track when this component is removed from a @@ -315,6 +361,12 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { Overrides:
removeNotify in class java.awt.Component
*/ public void removeNotify() { + if(DEBUG) { + Exception ex1 = new Exception("removeNotify - start"); + ex1.printStackTrace(); + } + drawableHelper.invokeGL(drawable, context, disposeAction, null); + if (Beans.isDesignTime()) { super.removeNotify(); } else { @@ -337,13 +389,16 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { destroyAction.run(); } } finally { - drawable.setRealized(false); - super.removeNotify(); - if (DEBUG) { - System.err.println("GLCanvas.removeNotify()"); + if(null!=drawable) { + drawable.setRealized(false); } + drawable=null; + super.removeNotify(); } } + if(DEBUG) { + System.out.println("removeNotify - end"); + } } /** Overridden to cause {@link GLDrawableHelper#reshape} to be @@ -423,10 +478,21 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { return drawable.getFactory(); } + public String toString() { + return "AWT-GLCanvas[ "+((null!=drawable)?drawable.getClass().getName():"null-drawable")+", "+drawableHelper+"]"; + } + //---------------------------------------------------------------------- // Internals only below this point // + class DisposeAction implements Runnable { + public void run() { + drawableHelper.dispose(GLCanvas.this); + } + } + private DisposeAction disposeAction = new DisposeAction(); + private void maybeDoSingleThreadedWorkaround(Runnable eventDispatchThreadAction, Runnable invokeGLAction) { if (Threading.isSingleThreaded() && @@ -488,11 +554,18 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { class DestroyAction implements Runnable { public void run() { + if(DEBUG) { + Exception ex1 = new Exception("DestroyAction - start"); + ex1.printStackTrace(); + } GLContext current = GLContext.getCurrent(); - if (current == context) { - context.release(); + if(null!=current) { + context.destroy(); + context = null; + } + if(DEBUG) { + System.out.println("DestroyAction - end"); } - context.destroy(); } } private DestroyAction destroyAction = new DestroyAction(); -- cgit v1.2.3