diff options
author | Sven Gothel <[email protected]> | 2010-12-19 14:54:08 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-12-19 14:54:08 +0100 |
commit | 2cbab63bd6c230d31b8ae6f1d794ad49bf23bb53 (patch) | |
tree | 9da105f466b81424ae089e59e4bd67fce7c32d54 /src/test | |
parent | 2323c30c23b6f9eb7d7ccf94e6cdcbcb3d2f34a6 (diff) |
JOGL/NEWT: Introduce WindowClosingProtocol (solves Bug/Request 444)
Similar to JFrame's closing behavior,
the following components window closing follow the new WindowClosingProtocol:
- GLCanvas
- GLJPanel
- NEWT Window, GLWindow
- NEWT NewtCanvasAWT
The implementation obeys either
1) the user value set by this interface,
2) an underlying toolkit set user value (JFrame, ..)
3) or it's default, eg. {@link #DO_NOTHING_ON_CLOSE DO_NOTHING_ON_CLOSE} within an AWT environment.
If none of the above determines the operation,
this protocol default behavior {@link #DISPOSE_ON_CLOSE DISPOSE_ON_CLOSE} shall be used.
Diffstat (limited to 'src/test')
8 files changed, 555 insertions, 42 deletions
diff --git a/src/test/com/jogamp/newt/impl/WindowImplAccess.java b/src/test/com/jogamp/newt/impl/WindowImplAccess.java new file mode 100644 index 000000000..5a90c8094 --- /dev/null +++ b/src/test/com/jogamp/newt/impl/WindowImplAccess.java @@ -0,0 +1,52 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.newt.impl; + +import com.jogamp.newt.Window; +import com.jogamp.newt.opengl.GLWindow; + +/** + * Allows access to protected methods of WindowImpl + */ +public class WindowImplAccess { + public static final void windowDestroyNotify(Window win) { + WindowImpl winImpl = null; + if(win instanceof GLWindow) { + GLWindow glwin = (GLWindow) win; + winImpl = (WindowImpl) glwin.getWindow(); + } else if(win instanceof WindowImpl) { + winImpl = (WindowImpl) win; + } else { + throw new RuntimeException("Given Window not a GLWindow, not WindowImpl, but "+win.getClass()); + } + winImpl.windowDestroyNotify(); + } +} + + diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java index 8cad4f0ed..509a0af15 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java @@ -45,6 +45,7 @@ import com.jogamp.newt.awt.NewtCanvasAWT; import com.jogamp.newt.event.WindowAdapter; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; import com.jogamp.opengl.test.junit.util.UITestCase; public class TestCloseNewtAWT extends UITestCase { @@ -124,11 +125,7 @@ public class TestCloseNewtAWT extends UITestCase { }); Thread.sleep(1000); - // programatically issue windowClosing - Toolkit tk = Toolkit.getDefaultToolkit(); - EventQueue evtQ = tk.getSystemEventQueue(); - evtQ.postEvent(new java.awt.event.WindowEvent(frame, java.awt.event.WindowEvent.WINDOW_CLOSING)); - Thread.sleep(200); + AWTRobotUtil.closeWindow(frame); GLProfile.shutdown(); } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java index 96ea861a7..6b501e31d 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java @@ -49,6 +49,7 @@ public class TestRemoteGLWindows01NEWT extends UITestCase { static GLProfile glp; static int width, height; static long durationPerTest = 100; // ms + static String remoteDisplay = "nowhere:0.0"; @BeforeClass public static void initClass() { @@ -59,7 +60,7 @@ public class TestRemoteGLWindows01NEWT extends UITestCase { glp = GLProfile.getDefault(); } - static GLWindow createWindow(Screen screen, GLCapabilities caps) + static GLWindow createWindow(Screen screen, GLCapabilities caps, GLEventListener demo) throws InterruptedException { Assert.assertNotNull(caps); @@ -74,8 +75,7 @@ public class TestRemoteGLWindows01NEWT extends UITestCase { glWindow = GLWindow.create(caps); Assert.assertNotNull(glWindow); } - - GLEventListener demo = new Gears(); + glWindow.addGLEventListener(demo); glWindow.setSize(512, 512); @@ -96,42 +96,49 @@ public class TestRemoteGLWindows01NEWT extends UITestCase { @Test public void testRemoteWindow01() throws InterruptedException { + Animator animator = new Animator(); GLCapabilities caps = new GLCapabilities(glp); Assert.assertNotNull(caps); - GLWindow window1 = createWindow(null, caps); // local + GLWindow window1 = createWindow(null, caps, new Gears(1)); // local with vsync Assert.assertEquals(true,window1.isNativeValid()); Assert.assertEquals(true,window1.isVisible()); AbstractGraphicsDevice device1 = window1.getScreen().getDisplay().getGraphicsDevice(); System.err.println("GLProfiles window1: "+device1.getConnection()+": "+GLProfile.glAvailabilityToString(device1)); - Animator animator1 = new Animator(window1); - animator1.start(); + animator.add(window1); + // Remote Display/Device/Screen/Window .. // Eager initialization of NEWT Display -> AbstractGraphicsDevice -> GLProfile (device) - Display display2 = NewtFactory.createDisplay("charelle:0.0"); // remote display + Display display2; // remote display + AbstractGraphicsDevice device2; + Screen screen2; + GLWindow window2; try { - display2.createNative(); + display2 = NewtFactory.createDisplay(remoteDisplay); // remote display + display2.createNative(); + System.err.println(display2); + device2 = display2.getGraphicsDevice(); + System.err.println(device2); + GLProfile.initProfiles(device2); // just to make sure + System.err.println(""); + System.err.println("GLProfiles window2: "+device2.getConnection()+": "+GLProfile.glAvailabilityToString(device2)); + screen2 = NewtFactory.createScreen(display2, 0); // screen 0 + window2 = createWindow(screen2, caps, new Gears(0)); // remote, no vsync } catch (NativeWindowException nwe) { System.err.println(nwe); Assume.assumeNoException(nwe); destroyWindow(window1); return; } - AbstractGraphicsDevice device2 = display2.getGraphicsDevice(); - GLProfile.initProfiles(device2); // just to make sure - System.err.println(""); - System.err.println("GLProfiles window2: "+device2.getConnection()+": "+GLProfile.glAvailabilityToString(device2)); - Screen screen2 = NewtFactory.createScreen(display2, 0); // screen 0 - GLWindow window2 = createWindow(screen2, caps); // remote Assert.assertEquals(true,window2.isNativeValid()); Assert.assertEquals(true,window2.isVisible()); - Animator animator2 = new Animator(window2); - animator2.start(); + animator.add(window2); + animator.start(); - for(int state=0; state*100<durationPerTest; state++) { + while(animator.getDuration()<durationPerTest) { Thread.sleep(100); } @@ -151,9 +158,12 @@ public class TestRemoteGLWindows01NEWT extends UITestCase { for(int i=0; i<args.length; i++) { if(args[i].equals("-time")) { durationPerTest = atoi(args[++i]); + } else if(args[i].equals("-display")) { + remoteDisplay = args[++i]; } } System.out.println("durationPerTest: "+durationPerTest); + System.out.println("display: "+remoteDisplay); String tstname = TestRemoteGLWindows01NEWT.class.getName(); org.junit.runner.JUnitCore.main(tstname); } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java index f0cd3b89f..9c44545f2 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java @@ -43,6 +43,7 @@ import com.jogamp.opengl.test.junit.util.UITestCase; public class TestRemoteWindow01NEWT extends UITestCase { static int width, height; + static String remoteDisplay = "nowhere:0.0"; @BeforeClass public static void initClass() { @@ -109,18 +110,23 @@ public class TestRemoteWindow01NEWT extends UITestCase { Assert.assertEquals(true,window1.isNativeValid()); Assert.assertEquals(true,window1.isVisible()); - Display display2 = NewtFactory.createDisplay("charelle:0.0"); // remote display + // Remote Display/Device/Screen/Window .. + Display display2; + AbstractGraphicsDevice device2; + Screen screen2; + Window window2; try { + display2 = NewtFactory.createDisplay(remoteDisplay); display2.createNative(); + screen2 = NewtFactory.createScreen(display2, 0); // screen 0 + window2 = createWindow(screen2, caps, width, height, true /* onscreen */, false /* undecorated */); + window2.setVisible(true); } catch (NativeWindowException nwe) { System.err.println(nwe); Assume.assumeNoException(nwe); destroyWindow(display1, screen1, window1); return; } - Screen screen2 = NewtFactory.createScreen(display2, 0); // screen 0 - Window window2 = createWindow(screen2, caps, width, height, true /* onscreen */, false /* undecorated */); - window2.setVisible(true); Assert.assertEquals(true,window2.isNativeValid()); Assert.assertEquals(true,window2.isVisible()); @@ -132,6 +138,12 @@ public class TestRemoteWindow01NEWT extends UITestCase { } public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-display")) { + remoteDisplay = args[++i]; + } + } + System.out.println("display: "+remoteDisplay); String tstname = TestRemoteWindow01NEWT.class.getName(); org.junit.runner.JUnitCore.main(tstname); } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol01AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol01AWT.java new file mode 100644 index 000000000..c7ac00934 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol01AWT.java @@ -0,0 +1,155 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.newt; + +import org.junit.Test; +import org.junit.Assert; + +import java.lang.reflect.InvocationTargetException; +import java.awt.Frame; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +import javax.media.nativewindow.WindowClosingProtocol; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; +import javax.media.opengl.awt.GLCanvas; + +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; + +public class TestWindowClosingProtocol01AWT extends UITestCase { + + @Test + public void testCloseFrameGLCanvas() throws InterruptedException, InvocationTargetException { + final Frame frame = new Frame("testCloseFrameGLCanvas AWT"); + + GLProfile glp = GLProfile.getDefault(); + GLCapabilities caps = new GLCapabilities(glp); + GLCanvas glCanvas = new GLCanvas(caps); + glCanvas.addGLEventListener(new Gears()); + frame.add(glCanvas); + frame.pack(); + frame.setSize(512, 512); + frame.validate(); + frame.setVisible(true); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); + + // + // close with op: DO_NOTHING_ON_CLOSE -> NOP (default) + // + int op = glCanvas.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DO_NOTHING_ON_CLOSE, op); + + AWTRobotUtil.closeWindow(frame); + Assert.assertEquals(true, frame.isVisible()); + Assert.assertEquals(true, frame.isDisplayable()); + Assert.assertEquals(true, glCanvas.isValid()); + Assert.assertEquals(true, glCanvas.isVisible()); + Assert.assertEquals(true, glCanvas.isDisplayable()); + + // + // close with op (GLCanvas): DISPOSE_ON_CLOSE -> dispose + // + glCanvas.setDefaultCloseOperation(WindowClosingProtocol.DISPOSE_ON_CLOSE); + op = glCanvas.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DISPOSE_ON_CLOSE, op); + + AWTRobotUtil.closeWindow(frame); + Assert.assertEquals(true, frame.isVisible()); + Assert.assertEquals(true, frame.isDisplayable()); + Assert.assertEquals(false, glCanvas.isValid()); + Assert.assertEquals(true, glCanvas.isVisible()); + Assert.assertEquals(false, glCanvas.isDisplayable()); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + frame.dispose(); + } }); + } + + @Test + public void testCloseJFrameGLCanvas() throws InterruptedException, InvocationTargetException { + final JFrame frame = new JFrame("testCloseJFrameGLCanvas AWT"); + + GLProfile glp = GLProfile.getDefault(); + GLCapabilities caps = new GLCapabilities(glp); + GLCanvas glCanvas = new GLCanvas(caps); + glCanvas.addGLEventListener(new Gears()); + frame.getContentPane().add(glCanvas); + frame.pack(); + frame.setSize(512, 512); + frame.validate(); + frame.setVisible(true); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); + + // + // close with op: DO_NOTHING_ON_CLOSE -> NOP / HIDE (default) + // + Assert.assertEquals(JFrame.HIDE_ON_CLOSE, frame.getDefaultCloseOperation()); + int op = glCanvas.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DO_NOTHING_ON_CLOSE, op); + + AWTRobotUtil.closeWindow(frame); + Assert.assertEquals(false, frame.isVisible()); + Assert.assertEquals(true, frame.isDisplayable()); + Assert.assertEquals(true, glCanvas.isValid()); + Assert.assertEquals(true, glCanvas.isVisible()); + Assert.assertEquals(true, glCanvas.isDisplayable()); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + frame.setVisible(true); + } }); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); + + // + // close with op (JFrame): DISPOSE_ON_CLOSE -- GLCanvas --> dispose + // + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + Assert.assertEquals(JFrame.DISPOSE_ON_CLOSE, frame.getDefaultCloseOperation()); + op = glCanvas.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DISPOSE_ON_CLOSE, op); + + AWTRobotUtil.closeWindow(frame); + Assert.assertEquals(false, frame.isVisible()); + Assert.assertEquals(false, frame.isDisplayable()); + Assert.assertEquals(false, glCanvas.isValid()); + Assert.assertEquals(true, glCanvas.isVisible()); + Assert.assertEquals(false, glCanvas.isDisplayable()); + } + + public static void main(String[] args) { + String tstname = TestWindowClosingProtocol01AWT.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol02NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol02NEWT.java new file mode 100644 index 000000000..f9a6003e7 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol02NEWT.java @@ -0,0 +1,116 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.newt; + +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.event.WindowEvent; +import java.lang.reflect.InvocationTargetException; + +import org.junit.Test; +import org.junit.Assert; + +import javax.media.nativewindow.WindowClosingProtocol; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; + +import com.jogamp.newt.opengl.GLWindow; + +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; + +public class TestWindowClosingProtocol02NEWT extends UITestCase { + + static class NEWTWindowClosingAdapter extends WindowAdapter { + volatile boolean windowDestroyNotifyReached = false; + + public void reset() { + windowDestroyNotifyReached = false; + } + public boolean windowDestroyNotifyReached() { + return windowDestroyNotifyReached; + } + public void windowDestroyNotify(WindowEvent e) { + windowDestroyNotifyReached = true; + } + } + + @Test + public void testCloseGLWindow() throws InterruptedException, InvocationTargetException { + GLProfile glp = GLProfile.getDefault(); + GLCapabilities caps = new GLCapabilities(glp); + final GLWindow glWindow = GLWindow.create(caps); + final NEWTWindowClosingAdapter newtWindowClosingAdapter = new NEWTWindowClosingAdapter(); + + glWindow.addWindowListener(newtWindowClosingAdapter); + glWindow.addGLEventListener(new Gears()); + glWindow.setSize(512, 512); + glWindow.setVisible(true); + Assert.assertEquals(true, glWindow.isVisible()); + + // CHECK DEFAULT .. + int op = glWindow.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DISPOSE_ON_CLOSE, op); + + // + // close with op: DO_NOTHING_ON_CLOSE -> NOP + // + glWindow.setDefaultCloseOperation(WindowClosingProtocol.DO_NOTHING_ON_CLOSE); + op = glWindow.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DO_NOTHING_ON_CLOSE, op); + + AWTRobotUtil.closeWindow(glWindow); + Assert.assertEquals(true, glWindow.isValid()); + Assert.assertEquals(true, glWindow.isVisible()); + Assert.assertEquals(true, glWindow.isNativeValid()); + Assert.assertEquals(true, newtWindowClosingAdapter.windowDestroyNotifyReached()); + newtWindowClosingAdapter.reset(); + + // + // close with op (GLCanvas): DISPOSE_ON_CLOSE -> dispose + // + glWindow.setDefaultCloseOperation(WindowClosingProtocol.DISPOSE_ON_CLOSE); + op = glWindow.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DISPOSE_ON_CLOSE, op); + + AWTRobotUtil.closeWindow(glWindow); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(glWindow, false)); + Assert.assertEquals(true, glWindow.isValid()); + Assert.assertEquals(false, glWindow.isVisible()); + Assert.assertEquals(false, glWindow.isNativeValid()); + Assert.assertEquals(true, newtWindowClosingAdapter.windowDestroyNotifyReached()); + } + + public static void main(String[] args) { + String tstname = TestWindowClosingProtocol02NEWT.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + +} diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol03NewtAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol03NewtAWT.java new file mode 100644 index 000000000..e69aae992 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindowClosingProtocol03NewtAWT.java @@ -0,0 +1,140 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.test.junit.newt; + +import com.jogamp.newt.awt.NewtCanvasAWT; +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.event.WindowEvent; +import com.jogamp.newt.opengl.GLWindow; +import org.junit.Test; +import org.junit.Assert; + +import java.lang.reflect.InvocationTargetException; +import java.awt.Frame; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +import javax.media.nativewindow.WindowClosingProtocol; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; +import javax.media.opengl.awt.GLCanvas; + +import com.jogamp.opengl.test.junit.jogl.demos.gl2.gears.Gears; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.UITestCase; + +public class TestWindowClosingProtocol03NewtAWT extends UITestCase { + + static class NEWTWindowClosingAdapter extends WindowAdapter { + volatile boolean windowDestroyNotifyReached = false; + + public void reset() { + windowDestroyNotifyReached = false; + } + public boolean windowDestroyNotifyReached() { + return windowDestroyNotifyReached; + } + public void windowDestroyNotify(WindowEvent e) { + windowDestroyNotifyReached = true; + } + } + + @Test + public void testCloseJFrameNewtCanvasAWT() throws InterruptedException, InvocationTargetException { + final JFrame frame = new JFrame("testCloseJFrameNewtCanvasAWT"); + + GLProfile glp = GLProfile.getDefault(); + GLCapabilities caps = new GLCapabilities(glp); + final GLWindow glWindow = GLWindow.create(caps); + final NEWTWindowClosingAdapter newtWindowClosingAdapter = new NEWTWindowClosingAdapter(); + + glWindow.addWindowListener(newtWindowClosingAdapter); + glWindow.addGLEventListener(new Gears()); + + NewtCanvasAWT newtCanvas = new NewtCanvasAWT(glWindow); + + frame.getContentPane().add(newtCanvas); + frame.pack(); + frame.setSize(512, 512); + frame.validate(); + frame.setVisible(true); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); + + // + // close with op: DO_NOTHING_ON_CLOSE -> NOP / HIDE (default) + // + Assert.assertEquals(JFrame.HIDE_ON_CLOSE, frame.getDefaultCloseOperation()); + int op = newtCanvas.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DO_NOTHING_ON_CLOSE, op); + + AWTRobotUtil.closeWindow(frame); + Assert.assertEquals(false, frame.isVisible()); + Assert.assertEquals(true, frame.isDisplayable()); + Assert.assertEquals(true, newtCanvas.isValid()); + Assert.assertEquals(true, newtCanvas.isVisible()); + Assert.assertEquals(true, newtCanvas.isDisplayable()); + Assert.assertEquals(true, glWindow.isValid()); + Assert.assertEquals(false, glWindow.isVisible()); + Assert.assertEquals(true, glWindow.isNativeValid()); + Assert.assertEquals(true, newtWindowClosingAdapter.windowDestroyNotifyReached()); + newtWindowClosingAdapter.reset(); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + frame.setVisible(true); + } }); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); + + // + // close with op (JFrame): DISPOSE_ON_CLOSE -- newtCanvas -- glWindow --> dispose + // + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + Assert.assertEquals(JFrame.DISPOSE_ON_CLOSE, frame.getDefaultCloseOperation()); + op = newtCanvas.getDefaultCloseOperation(); + Assert.assertEquals(WindowClosingProtocol.DISPOSE_ON_CLOSE, op); + + AWTRobotUtil.closeWindow(frame); + Assert.assertEquals(false, frame.isVisible()); + Assert.assertEquals(false, frame.isDisplayable()); + Assert.assertEquals(false, newtCanvas.isValid()); + Assert.assertEquals(true, newtCanvas.isVisible()); + Assert.assertEquals(false, newtCanvas.isDisplayable()); + Assert.assertEquals(true, glWindow.isValid()); + Assert.assertEquals(false, glWindow.isVisible()); + Assert.assertEquals(false, glWindow.isNativeValid()); + Assert.assertEquals(true, newtWindowClosingAdapter.windowDestroyNotifyReached()); + } + + public static void main(String[] args) { + String tstname = TestWindowClosingProtocol03NewtAWT.class.getName(); + org.junit.runner.JUnitCore.main(tstname); + } + +} 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 61aa95bf8..9812be5f2 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java +++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java @@ -28,15 +28,17 @@ package com.jogamp.opengl.test.junit.util; +import com.jogamp.newt.impl.WindowImplAccess; import java.lang.reflect.InvocationTargetException; import java.awt.AWTException; import java.awt.Component; import java.awt.Container; +import java.awt.EventQueue; import java.awt.KeyboardFocusManager; import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; -import java.awt.Window; +import java.awt.Toolkit; import java.awt.event.InputEvent; import javax.swing.JFrame; @@ -92,7 +94,7 @@ public class AWTRobotUtil { * * @return True if the Window became the global focused Window within TIME_OUT */ - public static boolean toFront(Robot robot, Window window) + public static boolean toFront(Robot robot, final java.awt.Window window) throws AWTException, InterruptedException, InvocationTargetException { if(null == robot) { @@ -104,12 +106,11 @@ public class AWTRobotUtil { robot.mouseMove( (int) p0.getX(), (int) p0.getY() ); robot.delay(ROBOT_DELAY); - final Window f_window = window; javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() { - f_window.setVisible(true); - f_window.toFront(); - f_window.requestFocus(); + window.setVisible(true); + window.toFront(); + window.requestFocus(); }}); robot.delay(ROBOT_DELAY); @@ -126,22 +127,12 @@ public class AWTRobotUtil { */ public static void centerMouse(Robot robot, Object obj) throws AWTException, InterruptedException, InvocationTargetException { - Component comp = null; - com.jogamp.newt.Window win = null; if(null == robot) { robot = new Robot(); robot.setAutoWaitForIdle(true); } - if(obj instanceof com.jogamp.newt.Window) { - win = (com.jogamp.newt.Window) obj; - } else if(obj instanceof Component) { - comp = (Component) obj; - } else { - throw new RuntimeException("Neither AWT nor NEWT: "+obj); - } - Point p0 = getCenterLocation(obj, false); System.err.println("robot pos: "+p0); @@ -334,5 +325,45 @@ public class AWTRobotUtil { return false; } + /** + * + * @return True if the Component becomes <code>visible</code> within TIME_OUT + */ + public static boolean waitForVisible(Object obj, boolean visible) throws InterruptedException { + int wait; + if(obj instanceof Component) { + Component comp = (Component) obj; + for (wait=0; wait<POLL_DIVIDER && visible != comp.isVisible(); 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 && visible != win.isVisible(); 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 + * + * @param obj either an AWT Window (Frame, JFrame) or NEWT Window + * @throws InterruptedException + */ + public static void closeWindow(Object obj) throws InterruptedException { + if(obj instanceof java.awt.Window) { + 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)); + } else if(obj instanceof com.jogamp.newt.Window) { + com.jogamp.newt.Window win = (com.jogamp.newt.Window) obj; + WindowImplAccess.windowDestroyNotify(win); + } + Thread.sleep(200); + } } |