diff options
16 files changed, 158 insertions, 58 deletions
diff --git a/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java index 88b165a8d..8542820c4 100644 --- a/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java @@ -52,6 +52,10 @@ public class TraceWindowAdapter implements WindowListener { System.err.println(e); if(null!=downstream) { downstream.windowDestroyNotify(e); } } + public void windowDestroyed(WindowEvent e) { + System.err.println(e); + if(null!=downstream) { downstream.windowDestroyed(e); } + } public void windowGainedFocus(WindowEvent e) { System.err.println(e); if(null!=downstream) { downstream.windowGainedFocus(e); } diff --git a/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java index a1ad43a13..b9e487e9b 100644 --- a/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java @@ -36,6 +36,8 @@ public abstract class WindowAdapter implements WindowListener } public void windowDestroyNotify(WindowEvent e) { } + public void windowDestroyed(WindowEvent e) { + } public void windowGainedFocus(WindowEvent e) { } public void windowLostFocus(WindowEvent e) { diff --git a/src/newt/classes/com/jogamp/newt/event/WindowEvent.java b/src/newt/classes/com/jogamp/newt/event/WindowEvent.java index 2742e0d95..f3d62d8c6 100644 --- a/src/newt/classes/com/jogamp/newt/event/WindowEvent.java +++ b/src/newt/classes/com/jogamp/newt/event/WindowEvent.java @@ -46,6 +46,7 @@ public class WindowEvent extends NEWTEvent { public static final int EVENT_WINDOW_GAINED_FOCUS = 103; public static final int EVENT_WINDOW_LOST_FOCUS = 104; public static final int EVENT_WINDOW_REPAINT = 105; + public static final int EVENT_WINDOW_DESTROYED = 106; public WindowEvent(int eventType, Object source, long when) { super(eventType, source, when); @@ -54,11 +55,12 @@ public class WindowEvent extends NEWTEvent { public static String getEventTypeString(int type) { switch(type) { case EVENT_WINDOW_RESIZED: return "WINDOW_RESIZED"; - case EVENT_WINDOW_MOVED: return "WINDOW_MOVED"; - case EVENT_WINDOW_DESTROY_NOTIFY: return "EVENT_WINDOW_DESTROY_NOTIFY"; - case EVENT_WINDOW_GAINED_FOCUS: return "EVENT_WINDOW_GAINED_FOCUS"; - case EVENT_WINDOW_LOST_FOCUS: return "EVENT_WINDOW_LOST_FOCUS"; - case EVENT_WINDOW_REPAINT: return "EVENT_WINDOW_REPAINT"; + case EVENT_WINDOW_MOVED: return "WINDOW_MOVED"; + case EVENT_WINDOW_DESTROY_NOTIFY: return "EVENT_WINDOW_DESTROY_NOTIFY"; + case EVENT_WINDOW_GAINED_FOCUS: return "EVENT_WINDOW_GAINED_FOCUS"; + case EVENT_WINDOW_LOST_FOCUS: return "EVENT_WINDOW_LOST_FOCUS"; + case EVENT_WINDOW_REPAINT: return "EVENT_WINDOW_REPAINT"; + case EVENT_WINDOW_DESTROYED: return "EVENT_WINDOW_DESTROYED"; default: return "unknown (" + type + ")"; } } diff --git a/src/newt/classes/com/jogamp/newt/event/WindowListener.java b/src/newt/classes/com/jogamp/newt/event/WindowListener.java index 0d201a2a4..e841a06cf 100644 --- a/src/newt/classes/com/jogamp/newt/event/WindowListener.java +++ b/src/newt/classes/com/jogamp/newt/event/WindowListener.java @@ -44,6 +44,9 @@ public interface WindowListener extends NEWTEventListener { /** Window will be destroyed. Release of resources is recommended. */ public void windowDestroyNotify(WindowEvent e); + /** Window has been destroyed.*/ + public void windowDestroyed(WindowEvent e); + /** Window gained focus. */ public void windowGainedFocus(WindowEvent e); diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java index 8e33285bf..20c0d15d1 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java @@ -39,7 +39,7 @@ class AWTNewtEventFactory { map.setKeyNotFoundValue(-1); // n/a map.put(java.awt.event.WindowEvent.WINDOW_OPENED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_OPENED); map.put(java.awt.event.WindowEvent.WINDOW_CLOSING, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); - // n/a map.put(java.awt.event.WindowEvent.WINDOW_CLOSED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_CLOSED); + map.put(java.awt.event.WindowEvent.WINDOW_CLOSED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DESTROYED); // n/a map.put(java.awt.event.WindowEvent.WINDOW_ICONIFIED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_ICONIFIED); // n/a map.put(java.awt.event.WindowEvent.WINDOW_DEICONIFIED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DEICONIFIED); map.put(java.awt.event.WindowEvent.WINDOW_ACTIVATED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS); diff --git a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java index e04bd1208..9dace822f 100644 --- a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java +++ b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java @@ -759,11 +759,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } if(null!=lifecycleHook) { + // send synced destroy notification for proper cleanup, eg GLWindow/OpenGL lifecycleHook.destroyActionInLock(); } closeAndInvalidate(); + // send synced destroyed notification + sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROYED); + if(DEBUG_IMPLEMENTATION) { System.err.println("Window.destroy() END "+getThreadName()/*+", "+WindowImpl.this*/); } @@ -2028,6 +2032,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer case WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY: l.windowDestroyNotify(e); break; + case WindowEvent.EVENT_WINDOW_DESTROYED: + l.windowDestroyed(e); + break; case WindowEvent.EVENT_WINDOW_GAINED_FOCUS: l.windowGainedFocus(e); break; @@ -2119,7 +2126,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer System.err.println("Window.windowDestroyNotify START "+getThreadName()); } - enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); + // send synced destroy notifications + enqueueWindowEvent(true, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); if(handleDestroyNotify && DISPOSE_ON_CLOSE == defaultCloseOperation && isValid()) { destroy(); @@ -2130,13 +2138,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } - protected void windowDestroyed() { - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.windowDestroyed "+getThreadName()); - } - closeAndInvalidate(); - } - public void windowRepaint(int x, int y, int width, int height) { if(DEBUG_IMPLEMENTATION) { System.err.println("Window.windowRepaint "+getThreadName()+" - "+x+"/"+y+" "+width+"x"+height); diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java index c01139b78..e789a0dc9 100644 --- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java @@ -166,7 +166,6 @@ public class MacWindow extends WindowImpl { setWindowHandle(0); nsViewLock.unlock(); } - windowDestroyed(); // No OSX hook for DidClose, so do it here } public final long getSurfaceHandle() { diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java index 9bc4667c5..5ab0a5b79 100644 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java @@ -140,11 +140,6 @@ public class WindowsWindow extends WindowImpl { } } - protected void windowDestroyed() { - windowHandleClose = 0; - super.windowDestroyed(); - } - protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) { setVisible0(getWindowHandle(), visible, (getParentWindowHandle()==0)?true:false, x, y, width, height); visibleChanged(visible); diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java index 73c6eb351..b8f1a0c95 100644 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java @@ -87,11 +87,6 @@ public class X11Window extends WindowImpl { } } - protected void windowDestroyed() { - windowHandleClose = 0; - super.windowDestroyed(); - } - protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) { setVisible0(getDisplayHandle(), getWindowHandle(), visible, x, y, width, height); } diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c index 33af4d963..50ad22b5a 100644 --- a/src/newt/native/KDWindow.c +++ b/src/newt/native/KDWindow.c @@ -94,7 +94,6 @@ static jmethodID windowCreatedID = NULL; static jmethodID sizeChangedID = NULL; static jmethodID visibleChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; -static jmethodID windowDestroyedID = NULL; static jmethodID sendMouseEventID = NULL; static jmethodID sendKeyEventID = NULL; @@ -137,8 +136,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDDisplay_DispatchMes { DBG_PRINT( "event window close : src: %p\n", userData); (*env)->CallVoidMethod(env, javaWindow, windowDestroyNotifyID); - // Called by Window.java: DestroyWindow(wnd); - // (*env)->CallVoidMethod(env, javaWindow, windowDestroyedID); } break; case KD_EVENT_WINDOWPROPERTY_CHANGE: @@ -213,14 +210,12 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDWindow_initIDs sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(IIZ)V"); visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); - windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); if (windowCreatedID == NULL || sizeChangedID == NULL || visibleChangedID == NULL || windowDestroyNotifyID == NULL || - windowDestroyedID == NULL || sendMouseEventID == NULL || sendKeyEventID == NULL) { DBG_PRINT( "initIDs failed\n" ); diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index 2d8a84b4b..cba69498a 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -80,7 +80,6 @@ static jmethodID visibleChangedID = NULL; static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; -static jmethodID windowDestroyedID = NULL; @implementation NewtView - (void) setJNIEnv: (JNIEnv*) theEnv @@ -142,9 +141,8 @@ static jmethodID windowDestroyedID = NULL; positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); - windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); if (sendMouseEventID && sendKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID && - positionChangedID && focusChangedID && windowDestroyedID && windowDestroyNotifyID) + positionChangedID && focusChangedID && windowDestroyNotifyID) { return YES; } @@ -456,7 +454,6 @@ static jint mods2JavaMods(NSUInteger mods) (*env)->CallVoidMethod(env, javaWindowObject, windowDestroyNotifyID); // Can't issue call here - locked window state, done from Java method - // (*env)->CallVoidMethod(env, javaWindowObject, windowDestroyedID); // No OSX hook for DidClose, so do it here // EOL .. (*env)->DeleteGlobalRef(env, javaWindowObject); diff --git a/src/newt/native/WindowEvent.h b/src/newt/native/WindowEvent.h index 6274f9443..05491b43c 100644 --- a/src/newt/native/WindowEvent.h +++ b/src/newt/native/WindowEvent.h @@ -2,11 +2,12 @@ #ifndef _WINDOW_EVENT_H_ #define _WINDOW_EVENT_H_ -#define EVENT_WINDOW_RESIZED = 100; -#define EVENT_WINDOW_MOVED = 101; -#define EVENT_WINDOW_DESTROY_NOTIFY = 102; -#define EVENT_WINDOW_GAINED_FOCUS = 103; -#define EVENT_WINDOW_LOST_FOCUS = 104; -#define EVENT_WINDOW_REPAINT = 105; // TODO +#define EVENT_WINDOW_RESIZED 100 +#define EVENT_WINDOW_MOVED 101 +#define EVENT_WINDOW_DESTROY_NOTIFY 102 +#define EVENT_WINDOW_GAINED_FOCUS 103 +#define EVENT_WINDOW_LOST_FOCUS 104 +#define EVENT_WINDOW_REPAINT 105 +#define EVENT_WINDOW_DESTROYED 106 #endif diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index cafdaeef8..998743e75 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -124,7 +124,6 @@ static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; static jmethodID visibleChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; -static jmethodID windowDestroyedID = NULL; static jmethodID windowRepaintID = NULL; static jmethodID enqueueMouseEventID = NULL; static jmethodID sendMouseEventID = NULL; @@ -820,8 +819,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, // // The signal pipeline for destruction is: // Java::DestroyWindow(wnd) _or_ window-close-button -> - // WM_CLOSE -> Java::windowDestroyNotify -> W_DESTROY -> Java::windowDestroyed -> - // Java::CleanupWindowResources() + // WM_CLOSE -> Java::windowDestroyNotify -> W_DESTROY case WM_CLOSE: (*env)->CallVoidMethod(env, window, windowDestroyNotifyID); break; @@ -834,7 +832,6 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, SetWindowLongPtr(wnd, GWLP_USERDATA, (intptr_t) NULL); #endif free(wud); wud=NULL; - (*env)->CallVoidMethod(env, window, windowDestroyedID); (*env)->DeleteGlobalRef(env, window); } break; @@ -1267,7 +1264,6 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initI focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V"); visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); - windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(IIII)V"); enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZIIIIII)V"); sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); @@ -1282,7 +1278,6 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initI focusChangedID == NULL || visibleChangedID == NULL || windowDestroyNotifyID == NULL || - windowDestroyedID == NULL || windowRepaintID == NULL || enqueueMouseEventID == NULL || sendMouseEventID == NULL || diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index 15418269e..d30e5de59 100644 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -147,7 +147,6 @@ static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; static jmethodID visibleChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; -static jmethodID windowDestroyedID = NULL; static jmethodID windowRepaintID = NULL; static jmethodID windowReparentedID = NULL; static jmethodID enqueueMouseEventID = NULL; @@ -624,7 +623,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages (void*)evt.xdestroywindow.window, (void*)evt.xdestroywindow.event, evt.xdestroywindow.window != evt.xdestroywindow.event); if ( evt.xdestroywindow.window == evt.xdestroywindow.event ) { // ignore child destroy notification - (*env)->CallVoidMethod(env, jwindow, windowDestroyedID); } break; case CreateNotify: @@ -1191,7 +1189,6 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0 focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V"); visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(Z)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); - windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(IIII)V"); windowReparentedID = (*env)->GetMethodID(env, clazz, "windowReparented", "(J)V"); enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZIIIIII)V"); @@ -1206,7 +1203,6 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0 focusChangedID == NULL || visibleChangedID == NULL || windowDestroyNotifyID == NULL || - windowDestroyedID == NULL || windowRepaintID == NULL || windowReparentedID == NULL || enqueueMouseEventID == NULL || @@ -1394,8 +1390,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0 (*env)->DeleteGlobalRef(env, jwindow); DBG_PRINT( "X11: CloseWindow END\n"); - - (*env)->CallVoidMethod(env, obj, windowDestroyedID); } static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint width, jint height) diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/WindowAction.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/WindowAction.java index bb4008e57..05793b96e 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/WindowAction.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/WindowAction.java @@ -40,5 +40,8 @@ class WindowAction extends WindowAdapter { public void windowDestroyNotify(WindowEvent e) { eventFifo.put(e); } + public void windowDestroyed(WindowEvent e) { + eventFifo.put(e); + } } diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java index 9812be5f2..4a2a181ed 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java @@ -40,6 +40,7 @@ import java.awt.Rectangle; import java.awt.Robot; import java.awt.Toolkit; import java.awt.event.InputEvent; +import javax.media.opengl.awt.GLCanvas; import javax.swing.JFrame; public class AWTRobotUtil { @@ -348,22 +349,135 @@ public class AWTRobotUtil { } /** - * Programmatically issue windowClosing on AWT or NEWT + * + * @return True if the Component becomes realized (not displayable, native invalid) within TIME_OUT + */ + public static boolean waitForRealized(Object obj, boolean realized) throws InterruptedException { + int wait; + if(obj instanceof GLCanvas) { + GLCanvas comp = (GLCanvas) obj; + for (wait=0; wait<POLL_DIVIDER && realized != comp.isRealized(); wait++) { + Thread.sleep(TIME_OUT/POLL_DIVIDER); + } + } else if (obj instanceof Component) { + Component comp = (Component) obj; + for (wait=0; wait<POLL_DIVIDER && realized != comp.isDisplayable(); wait++) { + Thread.sleep(TIME_OUT/POLL_DIVIDER); + } + } else if(obj instanceof com.jogamp.newt.Window) { + com.jogamp.newt.Window win = (com.jogamp.newt.Window) obj; + for (wait=0; wait<POLL_DIVIDER && realized != win.isNativeValid(); wait++) { + Thread.sleep(TIME_OUT/POLL_DIVIDER); + } + } else { + throw new RuntimeException("Neither AWT nor NEWT: "+obj); + } + return wait<POLL_DIVIDER; + } + + /** + * Programmatically issue windowClosing on AWT or NEWT. + * Wait until the window is closing within TIME_OUT. * * @param obj either an AWT Window (Frame, JFrame) or NEWT Window + * @param willClose indicating that the window will close, hence this method waits for the window to be closed + * @return True if the Window is closing and closed (if willClose is true), each within TIME_OUT * @throws InterruptedException */ - public static void closeWindow(Object obj) throws InterruptedException { + public static boolean closeWindow(Object obj, boolean willClose) throws InterruptedException, InvocationTargetException { + WindowClosingListener closingListener = addClosingListener(obj); if(obj instanceof java.awt.Window) { - java.awt.Window win = (java.awt.Window) obj; + final java.awt.Window win = (java.awt.Window) obj; Toolkit tk = Toolkit.getDefaultToolkit(); - EventQueue evtQ = tk.getSystemEventQueue(); - evtQ.postEvent(new java.awt.event.WindowEvent(win, java.awt.event.WindowEvent.WINDOW_CLOSING)); + final EventQueue evtQ = tk.getSystemEventQueue(); + EventQueue.invokeAndWait(new Runnable() { + public void run() { + evtQ.postEvent(new java.awt.event.WindowEvent(win, java.awt.event.WindowEvent.WINDOW_CLOSING)); + } }); } else if(obj instanceof com.jogamp.newt.Window) { com.jogamp.newt.Window win = (com.jogamp.newt.Window) obj; WindowImplAccess.windowDestroyNotify(win); } - Thread.sleep(200); + int wait; + for (wait=0; wait<POLL_DIVIDER && !closingListener.isWindowClosing(); wait++) { + Thread.sleep(TIME_OUT/POLL_DIVIDER); + } + if(wait<POLL_DIVIDER && willClose) { + for (wait=0; wait<POLL_DIVIDER && !closingListener.isWindowClosed(); wait++) { + Thread.sleep(TIME_OUT/POLL_DIVIDER); + } + } + return wait<POLL_DIVIDER; } + + public static WindowClosingListener addClosingListener(Object obj) throws InterruptedException { + WindowClosingListener cl = null; + if(obj instanceof java.awt.Window) { + java.awt.Window win = (java.awt.Window) obj; + AWTWindowClosingAdapter acl = new AWTWindowClosingAdapter(); + win.addWindowListener(acl); + cl = acl; + } else if(obj instanceof com.jogamp.newt.Window) { + com.jogamp.newt.Window win = (com.jogamp.newt.Window) obj; + NEWTWindowClosingAdapter ncl = new NEWTWindowClosingAdapter(); + win.addWindowListener(ncl); + cl = ncl; + } else { + throw new RuntimeException("Neither AWT nor NEWT: "+obj); + } + return cl; + } + public static interface WindowClosingListener { + void reset(); + public boolean isWindowClosing(); + public boolean isWindowClosed(); + } + static class AWTWindowClosingAdapter + extends java.awt.event.WindowAdapter implements WindowClosingListener + { + volatile boolean closing = false; + volatile boolean closed = false; + + public void reset() { + closing = false; + closed = false; + } + public boolean isWindowClosing() { + return closing; + } + public boolean isWindowClosed() { + return closed; + } + public void windowClosing(java.awt.event.WindowEvent e) { + closing = true; + } + public void windowClosed(java.awt.event.WindowEvent e) { + closed = true; + } + } + static class NEWTWindowClosingAdapter + extends com.jogamp.newt.event.WindowAdapter implements WindowClosingListener + { + volatile boolean closing = false; + volatile boolean closed = false; + + public void reset() { + closing = false; + closed = false; + } + public boolean isWindowClosing() { + return closing; + } + public boolean isWindowClosed() { + return closed; + } + public void windowDestroyNotify(com.jogamp.newt.event.WindowEvent e) { + closing = true; + } + public void windowDestroyed(com.jogamp.newt.event.WindowEvent e) { + closed = true; + } + } + } |