diff options
Diffstat (limited to 'src/test/com')
8 files changed, 777 insertions, 150 deletions
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/GLContextDrawableSwitchBase.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/GLContextDrawableSwitchBase.java new file mode 100644 index 000000000..f26a96a90 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/GLContextDrawableSwitchBase.java @@ -0,0 +1,276 @@ +/** + * Copyright 2013 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.jogl.acore.glels; + +import java.awt.Dimension; +import java.awt.Frame; + +import javax.media.opengl.GLAnimatorControl; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLOffscreenAutoDrawable; +import javax.media.opengl.GLProfile; +import javax.media.opengl.awt.GLCanvas; + +import jogamp.nativewindow.jawt.JAWTUtil; +import jogamp.opengl.GLEventListenerState; + +import com.jogamp.newt.opengl.GLWindow; + +import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; +import com.jogamp.opengl.test.junit.util.AWTRobotUtil; +import com.jogamp.opengl.test.junit.util.GLEventListenerCounter; +import com.jogamp.opengl.test.junit.util.UITestCase; + +import org.junit.Assert; +import org.junit.Assume; +import org.junit.BeforeClass; + +/** + * Test re-association of GLContext/GLDrawables, + * here GLContext's survival of GLDrawable destruction + * and reuse w/ new or recreated GLDrawable. + * <p> + * Test utilizes {@link GLEventListenerState} for preserving the + * GLAutoDrawable state, i.e. GLContext, all GLEventListener + * and the GLAnimatorControl association. + * </p> + * <p> + * See Bug 665 - https://jogamp.org/bugzilla/show_bug.cgi?id=665. + * </p> + */ +public abstract class GLContextDrawableSwitchBase extends UITestCase { + static protected enum GLADType { GLCanvasOnscreen, GLCanvasOffscreen, GLWindow, GLOffscreen }; + + // default period for 1 GLAD cycle + static long duration = 1000; // ms + + static int width, height; + + static GLCapabilities getCaps(String profile) { + if( !GLProfile.isAvailable(profile) ) { + System.err.println("Profile "+profile+" n/a"); + return null; + } + return new GLCapabilities(GLProfile.get(profile)); + } + + @BeforeClass + public static void initClass() { + width = 256; + height = 256; + } + + static void setGLCanvasSize(final GLCanvas glc, final Dimension new_sz) { + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + glc.setMinimumSize(new_sz); + glc.setPreferredSize(new_sz); + glc.setSize(new_sz); + } } ); + } catch( Throwable throwable ) { + throwable.printStackTrace(); + Assume.assumeNoException( throwable ); + } + } + + static void setFrameVisible(final Frame frame) throws InterruptedException { + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame.pack(); + frame.setVisible(true); + }}); + } catch( Throwable throwable ) { + throwable.printStackTrace(); + Assume.assumeNoException( throwable ); + } + } + + static void destroyFrame(final Frame frame) throws InterruptedException { + try { + javax.swing.SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + frame.dispose(); + }}); + } catch( Throwable throwable ) { + throwable.printStackTrace(); + Assume.assumeNoException( throwable ); + } + } + + private GLOffscreenAutoDrawable createGLOffscreenAutoDrawable(GLCapabilities caps, int width, int height) throws InterruptedException { + final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile()); + return factory.createOffscreenAutoDrawable(null, caps, null, width, height, null); + } + + protected static boolean validateOnOffscreenLayer(GLADType gladType1, GLADType gladType2) { + final boolean useOffscreenLayer = GLADType.GLCanvasOffscreen == gladType1 || GLADType.GLCanvasOffscreen == gladType2 ; + final boolean useOnscreenLayer = GLADType.GLCanvasOnscreen == gladType1 || GLADType.GLCanvasOnscreen == gladType2 ; + if( useOffscreenLayer ) { + if( !JAWTUtil.isOffscreenLayerSupported() ) { + System.err.println("Platform doesn't support offscreen rendering."); + return false; + } + } else if( useOnscreenLayer ) { + if( JAWTUtil.isOffscreenLayerRequired() ) { + System.err.println("Platform requires offscreen rendering."); + return false; + } + } + return true; + } + + protected void testGLADOneLifecycle(GLCapabilities caps, GLADType gladType, int width, int height, + GLEventListenerCounter glelTracker, SnapshotGLEventListener snapshotGLEventListener, + GLEventListenerState glelsIn, GLEventListenerState glelsOut[], GLAnimatorControl animator) + throws InterruptedException { + + final Frame frame; + final GLAutoDrawable glad; + if( GLADType.GLCanvasOnscreen == gladType ) { + if( jogamp.nativewindow.jawt.JAWTUtil.isOffscreenLayerRequired() ) { + throw new InternalError("Platform requires offscreen rendering, but onscreen requested: "+gladType); + } + frame = new Frame("AWT GLCanvas"); + + glad = new GLCanvas(caps); + setGLCanvasSize((GLCanvas)glad, new Dimension(width, height)); + frame.add((GLCanvas)glad); + } else if( GLADType.GLCanvasOffscreen == gladType ) { + if( !jogamp.nativewindow.jawt.JAWTUtil.isOffscreenLayerSupported() ) { + throw new InternalError("Platform doesn't support offscreen rendering: "+gladType); + } + frame = new Frame("AWT GLCanvas"); + + glad = new GLCanvas(caps); + ((GLCanvas)glad).setShallUseOffscreenLayer(true); + setGLCanvasSize((GLCanvas)glad, new Dimension(width, height)); + frame.add((GLCanvas)glad); + } else if( GLADType.GLWindow == gladType ) { + frame = null; + + glad = GLWindow.create(caps); + ((GLWindow)glad).setTitle("Newt GLWindow"); + ((GLWindow)glad).setSize(width, height); + } else if( GLADType.GLOffscreen == gladType ) { + frame = null; + + glad = this.createGLOffscreenAutoDrawable(caps, width, height); + } else { + throw new InternalError("Unsupported: "+gladType); + } + + if( null == glelsIn ) { + if( null != animator ) { + animator.add(glad); + } + glad.addGLEventListener(glelTracker); + glad.addGLEventListener(new GearsES2(1)); + glad.addGLEventListener(snapshotGLEventListener); + } + snapshotGLEventListener.setMakeSnapshot(); + + if( GLADType.GLCanvasOnscreen == gladType || GLADType.GLCanvasOffscreen == gladType ) { + setFrameVisible(frame); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true)); + } else if( GLADType.GLWindow == gladType ) { + ((GLWindow)glad).setVisible(true); + } + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glad, true)); + Assert.assertNotNull(glad.getContext()); + Assert.assertTrue(glad.isRealized()); + + if( null != glelsIn ) { + Assert.assertEquals(0, glad.getGLEventListenerCount()); + glelsIn.moveTo(glad); + + Assert.assertEquals(1, glelTracker.initCount); + Assert.assertTrue(1 <= glelTracker.reshapeCount); + Assert.assertTrue(1 <= glelTracker.displayCount); + Assert.assertEquals(0, glelTracker.disposeCount); + Assert.assertEquals(3, glad.getGLEventListenerCount()); + + Assert.assertEquals(glelsIn.context, glad.getContext()); + Assert.assertEquals(glelsIn.listenerCount(), glad.getGLEventListenerCount()); + Assert.assertEquals(glelsIn.context.getGLReadDrawable(), glad.getDelegatedDrawable()); + Assert.assertEquals(glelsIn.context.getGLDrawable(), glad.getDelegatedDrawable()); + Assert.assertEquals(false, glelsIn.isOwner()); + } + + final long t0 = System.currentTimeMillis(); + long t1 = t0; + + while( ( t1 - t0 ) < duration ) { + Thread.sleep(100); + t1 = System.currentTimeMillis(); + } + + Assert.assertEquals(1, glelTracker.initCount); + Assert.assertTrue(1 <= glelTracker.reshapeCount); + Assert.assertTrue(1 <= glelTracker.displayCount); + Assert.assertEquals(0, glelTracker.disposeCount); + + if( null != glelsOut ) { + final GLContext context1 = glad.getContext(); + final GLEventListenerState _gllsOut = GLEventListenerState.moveFrom(glad); + + Assert.assertEquals(context1, _gllsOut.context); + Assert.assertNull(context1.getGLReadDrawable()); + Assert.assertNull(context1.getGLDrawable()); + Assert.assertEquals(3, _gllsOut.listenerCount()); + Assert.assertEquals(true, _gllsOut.isOwner()); + Assert.assertEquals(null, glad.getContext()); + Assert.assertEquals(0, glad.getGLEventListenerCount()); + + glelsOut[0] = _gllsOut; + } + if( GLADType.GLCanvasOnscreen == gladType || GLADType.GLCanvasOffscreen == gladType ) { + destroyFrame(frame); + Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, false)); + } else if( GLADType.GLWindow == gladType ) { + glad.destroy(); + } else if( GLADType.GLOffscreen == gladType ) { + glad.destroy(); + } + Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glad, false)); + + Assert.assertEquals(1, glelTracker.initCount); + Assert.assertTrue(1 <= glelTracker.reshapeCount); + Assert.assertTrue(1 <= glelTracker.displayCount); + if( null != glelsOut ) { + Assert.assertEquals(0, glelTracker.disposeCount); + } else { + Assert.assertEquals(1, glelTracker.disposeCount); + } + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch01NEWT.java index cce4149ba..5f2b9fb53 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch01NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch01NEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.opengl.test.junit.jogl.acore; +package com.jogamp.opengl.test.junit.jogl.acore.glels; import java.io.IOException; @@ -153,9 +153,9 @@ public class TestGLContextDrawableSwitch01NEWT extends UITestCase { { final GLContext newCtx = glad1.createContext(null); Assert.assertNotNull(newCtx); - final GLContext oldCtx = glad1.setContext(newCtx); + final GLContext oldCtx = glad1.setContext(newCtx, true); Assert.assertNotNull(oldCtx); - oldCtx.destroy(); + Assert.assertFalse(oldCtx.isCreated()); final int res = newCtx.makeCurrent(); Assert.assertTrue(GLContext.CONTEXT_CURRENT_NEW==res || GLContext.CONTEXT_CURRENT==res); newCtx.release(); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch11NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch10NEWT.java index 2ef797fba..a1611992e 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLContextDrawableSwitch11NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch10NEWT.java @@ -26,7 +26,7 @@ * or implied, of JogAmp Community. */ -package com.jogamp.opengl.test.junit.jogl.acore; +package com.jogamp.opengl.test.junit.jogl.acore.glels; import java.io.IOException; @@ -36,7 +36,6 @@ import com.jogamp.newt.event.WindowAdapter; import com.jogamp.newt.event.WindowEvent; import com.jogamp.newt.event.WindowListener; import com.jogamp.newt.event.WindowUpdateEvent; -import com.jogamp.newt.opengl.GLWindow; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLCapabilities; @@ -62,13 +61,24 @@ import org.junit.Test; /** * Test re-association of GLContext/GLDrawables, - * here GLContext's survival of GLDrawable desctruction + * here GLContext's survival of GLDrawable destruction * and reuse w/ new or recreated GLDrawable. * <p> + * Test utilizes {@link GLEventListenerState} for preserving the + * GLAutoDrawable state, i.e. GLContext, all GLEventListener + * and the GLAnimatorControl association. + * </p> + * <p> + * This test is using NEWT's plain Window w/ GLAutoDrawableDelegate. + * </p> + * <p> * See Bug 665 - https://jogamp.org/bugzilla/show_bug.cgi?id=665. * </p> */ -public class TestGLContextDrawableSwitch11NEWT extends UITestCase { +public class TestGLContextDrawableSwitch10NEWT extends UITestCase { + // default period for 1 GLAD cycle + static long duration = 1000; // ms + static int width, height; static GLCapabilities getCaps(String profile) { @@ -134,33 +144,31 @@ public class TestGLContextDrawableSwitch11NEWT extends UITestCase { public void test01GLADDelegateGL2ES2() throws InterruptedException { final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES2); if(null == reqGLCaps) return; - test01GLADDelegateImpl(reqGLCaps); + testGLADDelegateImpl(reqGLCaps); } @Test(timeout=30000) - public void test01GLADDelegateGLES2() throws InterruptedException { + public void test02GLADDelegateGLES2() throws InterruptedException { final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); if(null == reqGLCaps) return; - test01GLADDelegateImpl(reqGLCaps); + testGLADDelegateImpl(reqGLCaps); } - private void test01GLADDelegateImpl(GLCapabilities caps) throws InterruptedException { - final QuitAdapter quitAdapter = new QuitAdapter(); - + private void testGLADDelegateImpl(GLCapabilities caps) throws InterruptedException { final GLEventListenerCounter glelCounter = new GLEventListenerCounter(); final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener(); final Animator animator = new Animator(); animator.start(); - final long t0 = System.currentTimeMillis(); final GLEventListenerState glls1; // - create glad1 w/o context // - create context using glad1 and assign it to glad1 { + final QuitAdapter quitAdapter = new QuitAdapter(); final GLAutoDrawable glad1 = createGLAutoDrawableWithoutContext(caps, 64, 64, width, height, quitAdapter); final GLContext context1 = glad1.createContext(null); - glad1.setContext(context1); + glad1.setContext(context1, true); animator.add(glad1); glad1.addGLEventListener(glelCounter); @@ -168,9 +176,10 @@ public class TestGLContextDrawableSwitch11NEWT extends UITestCase { glad1.addGLEventListener(snapshotGLEventListener); snapshotGLEventListener.setMakeSnapshot(); - long t1 = System.currentTimeMillis(); + final long t0 = System.currentTimeMillis(); + long t1 = t0; - while( !quitAdapter.shouldQuit() && ( t1 - t0 ) < duration/2 ) { + while( !quitAdapter.shouldQuit() && ( t1 - t0 ) < duration ) { Thread.sleep(100); t1 = System.currentTimeMillis(); } @@ -209,6 +218,7 @@ public class TestGLContextDrawableSwitch11NEWT extends UITestCase { // - create glad2 w/ survived context { + final QuitAdapter quitAdapter = new QuitAdapter(); final GLAutoDrawable glad2 = createGLAutoDrawableWithoutContext(caps, 2*64+width, 64, width+100, height+100, quitAdapter); snapshotGLEventListener.setMakeSnapshot(); @@ -229,9 +239,10 @@ public class TestGLContextDrawableSwitch11NEWT extends UITestCase { Assert.assertEquals(glls1.context.getGLDrawable(), glad2.getDelegatedDrawable()); Assert.assertEquals(false, glls1.isOwner()); - long t1 = System.currentTimeMillis(); + final long t0 = System.currentTimeMillis(); + long t1 = t0; - while( !quitAdapter.shouldQuit() && ( t1 - t0 ) < duration/1 ) { + while( !quitAdapter.shouldQuit() && ( t1 - t0 ) < duration ) { Thread.sleep(100); t1 = System.currentTimeMillis(); } @@ -245,129 +256,6 @@ public class TestGLContextDrawableSwitch11NEWT extends UITestCase { animator.stop(); } - @Test(timeout=30000) - public void test02GLWindowGL2ES2() throws InterruptedException { - final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES2); - if(null == reqGLCaps) return; - test02GLWindowImpl(reqGLCaps); - } - - @Test(timeout=30000) - public void test02GLWindowGLES2() throws InterruptedException { - final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); - if(null == reqGLCaps) return; - test02GLWindowImpl(reqGLCaps); - } - - private void test02GLWindowImpl(GLCapabilities caps) throws InterruptedException { - final QuitAdapter quitAdapter = new QuitAdapter(); - - final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener(); - final GLEventListenerCounter glelTracker = new GLEventListenerCounter(); - final Animator animator = new Animator(); - animator.start(); - - final long t0 = System.currentTimeMillis(); - final GLEventListenerState glls1; - - // - create glad1 w/o context - // - create context using glad1 and assign it to glad1 - { - final GLWindow glad1 = GLWindow.create(caps); - glad1.setSize(width, height); - glad1.setPosition(64, 64); - glad1.addWindowListener(quitAdapter); - animator.add(glad1); - - glad1.addGLEventListener(glelTracker); - glad1.addGLEventListener(new GearsES2(1)); - glad1.addGLEventListener(snapshotGLEventListener); - snapshotGLEventListener.setMakeSnapshot(); - - glad1.setVisible(true); - - long t1 = System.currentTimeMillis(); - - while( !quitAdapter.shouldQuit() && ( t1 - t0 ) < duration/2 ) { - Thread.sleep(100); - t1 = System.currentTimeMillis(); - } - - // - dis-associate context from glad1 - // - destroy glad1 - Assert.assertEquals(1, glelTracker.initCount); - Assert.assertTrue(1 <= glelTracker.reshapeCount); - Assert.assertTrue(1 <= glelTracker.displayCount); - Assert.assertEquals(0, glelTracker.disposeCount); - Assert.assertEquals(3, glad1.getGLEventListenerCount()); - Assert.assertEquals(glad1.getContext().getGLReadDrawable(), glad1.getDelegatedDrawable()); - Assert.assertEquals(glad1.getContext().getGLDrawable(), glad1.getDelegatedDrawable()); - - final GLContext context1 = glad1.getContext(); - glls1 = GLEventListenerState.moveFrom(glad1); - - Assert.assertEquals(1, glelTracker.initCount); - Assert.assertTrue(1 <= glelTracker.reshapeCount); - Assert.assertTrue(1 <= glelTracker.displayCount); - Assert.assertEquals(0, glelTracker.disposeCount); - Assert.assertEquals(context1, glls1.context); - Assert.assertNull(context1.getGLReadDrawable()); - Assert.assertNull(context1.getGLDrawable()); - Assert.assertEquals(3, glls1.listenerCount()); - Assert.assertEquals(true, glls1.isOwner()); - Assert.assertEquals(null, glad1.getContext()); - Assert.assertEquals(0, glad1.getGLEventListenerCount()); - - glad1.destroy(); - Assert.assertEquals(1, glelTracker.initCount); - Assert.assertTrue(1 <= glelTracker.reshapeCount); - Assert.assertTrue(1 <= glelTracker.displayCount); - Assert.assertEquals(0, glelTracker.disposeCount); - } - - // - create glad2 w/ survived context - { - final GLWindow glad2 = GLWindow.create(caps); - glad2.setSize(width+100, height+100); - glad2.setPosition(2*64+width, 64); - glad2.addWindowListener(quitAdapter); - snapshotGLEventListener.setMakeSnapshot(); - glad2.setVisible(true); - - Assert.assertNotNull(glad2.getContext()); - Assert.assertEquals(0, glad2.getGLEventListenerCount()); - - glls1.moveTo(glad2); - - Assert.assertEquals(1, glelTracker.initCount); - Assert.assertTrue(1 <= glelTracker.reshapeCount); - Assert.assertTrue(1 <= glelTracker.displayCount); - Assert.assertEquals(0, glelTracker.disposeCount); - Assert.assertEquals(glls1.context, glad2.getContext()); - Assert.assertEquals(3, glad2.getGLEventListenerCount()); - Assert.assertEquals(glls1.context.getGLReadDrawable(), glad2.getDelegatedDrawable()); - Assert.assertEquals(glls1.context.getGLDrawable(), glad2.getDelegatedDrawable()); - Assert.assertEquals(false, glls1.isOwner()); - - long t1 = System.currentTimeMillis(); - - while( !quitAdapter.shouldQuit() && ( t1 - t0 ) < duration/1 ) { - Thread.sleep(100); - t1 = System.currentTimeMillis(); - } - - glad2.destroy(); - Assert.assertEquals(1, glelTracker.initCount); - Assert.assertTrue(1 <= glelTracker.reshapeCount); - Assert.assertTrue(1 <= glelTracker.displayCount); - Assert.assertEquals(1, glelTracker.disposeCount); - } - animator.stop(); - } - - // default timing for 2 switches - static long duration = 2200; // ms - public static void main(String args[]) throws IOException { for(int i=0; i<args.length; i++) { if(args[i].equals("-time")) { @@ -381,6 +269,6 @@ public class TestGLContextDrawableSwitch11NEWT extends UITestCase { BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); System.err.println("Press enter to continue"); System.err.println(stdin.readLine()); */ - org.junit.runner.JUnitCore.main(TestGLContextDrawableSwitch11NEWT.class.getName()); + org.junit.runner.JUnitCore.main(TestGLContextDrawableSwitch10NEWT.class.getName()); } } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch11NewtAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch11NewtAWT.java new file mode 100644 index 000000000..9ad89c4be --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch11NewtAWT.java @@ -0,0 +1,118 @@ +/** + * Copyright 2013 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.jogl.acore.glels; + +import java.io.IOException; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; + +import jogamp.opengl.GLEventListenerState; + +import com.jogamp.opengl.util.Animator; + +import com.jogamp.opengl.test.junit.util.GLEventListenerCounter; + +import org.junit.Test; + +/** + * Test re-association of GLContext/GLDrawables, + * here GLContext's survival of GLDrawable destruction + * and reuse w/ new or recreated GLDrawable. + * <p> + * Test utilizes {@link GLEventListenerState} for preserving the + * GLAutoDrawable state, i.e. GLContext, all GLEventListener + * and the GLAnimatorControl association. + * </p> + * <p> + * This test is using JOGL's NEWT GLWindow. + * </p> + * <p> + * See Bug 665 - https://jogamp.org/bugzilla/show_bug.cgi?id=665. + * </p> + */ +public class TestGLContextDrawableSwitch11NewtAWT extends GLContextDrawableSwitchBase { + + @Test(timeout=30000) + public void test21GLWindowGL2ES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES2); + if(null == reqGLCaps) return; + testGLWindowImpl(reqGLCaps); + } + + @Test(timeout=30000) + public void test22GLWindowGLES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + testGLWindowImpl(reqGLCaps); + } + + private void testGLWindowImpl(GLCapabilities caps) throws InterruptedException { + final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener(); + final GLEventListenerCounter glelTracker = new GLEventListenerCounter(); + final Animator animator = new Animator(); + animator.start(); + + final GLEventListenerState glels[] = new GLEventListenerState[1]; + + // - create glad1 w/o context + // - create context using glad1 and assign it to glad1 + { + testGLADOneLifecycle(caps, GLADType.GLWindow, width, height, + glelTracker, snapshotGLEventListener, + null, + glels, animator); + } + + // - create glad2 w/ survived context + { + testGLADOneLifecycle(caps, GLADType.GLWindow, width+100, height+100, + glelTracker, snapshotGLEventListener, + glels[0], + null, null); + } + animator.stop(); + } + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + try { + duration = Integer.parseInt(args[i]); + } catch (Exception ex) { ex.printStackTrace(); } + } + } + /** + BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); + System.err.println("Press enter to continue"); + System.err.println(stdin.readLine()); */ + org.junit.runner.JUnitCore.main(TestGLContextDrawableSwitch11NewtAWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch12AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch12AWT.java new file mode 100644 index 000000000..aa75fa1b1 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch12AWT.java @@ -0,0 +1,144 @@ +/** + * Copyright 2013 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.jogl.acore.glels; + +import java.io.IOException; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; + +import jogamp.nativewindow.jawt.JAWTUtil; +import jogamp.opengl.GLEventListenerState; + +import com.jogamp.opengl.util.Animator; + +import com.jogamp.opengl.test.junit.util.GLEventListenerCounter; + +import org.junit.Test; + +/** + * Test re-association of GLContext/GLDrawables, + * here GLContext's survival of GLDrawable destruction + * and reuse w/ new or recreated GLDrawable. + * <p> + * Test utilizes {@link GLEventListenerState} for preserving the + * GLAutoDrawable state, i.e. GLContext, all GLEventListener + * and the GLAnimatorControl association. + * </p> + * <p> + * This test is using JOGL's AWT GLCanvas + * </p> + * <p> + * See Bug 665 - https://jogamp.org/bugzilla/show_bug.cgi?id=665. + * </p> + */ +public class TestGLContextDrawableSwitch12AWT extends GLContextDrawableSwitchBase { + + @Test(timeout=30000) + public void test01GLCanvasOnscreenGL2ES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES2); + if(null == reqGLCaps) return; + testGLCanvasImpl(reqGLCaps, false); + } + + @Test(timeout=30000) + public void test02GLCanvasOnscreenGLES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + testGLCanvasImpl(reqGLCaps, false); + } + + @Test(timeout=30000) + public void test11GLCanvasOffscreenGL2ES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES2); + if(null == reqGLCaps) return; + testGLCanvasImpl(reqGLCaps, true); + } + + @Test(timeout=30000) + public void test12GLCanvasOffscreenGLES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + testGLCanvasImpl(reqGLCaps, true); + } + + private void testGLCanvasImpl(GLCapabilities caps, boolean offscreenLayer) throws InterruptedException { + if( offscreenLayer ) { + if( !JAWTUtil.isOffscreenLayerSupported() ) { + System.err.println("Platform doesn't support offscreen rendering."); + return; + } + } else { + if( JAWTUtil.isOffscreenLayerRequired() ) { + System.err.println("Platform requires offscreen rendering."); + return; + } + } + final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener(); + final GLEventListenerCounter glelTracker = new GLEventListenerCounter(); + final Animator animator = new Animator(); + animator.start(); + + final GLEventListenerState glels[] = new GLEventListenerState[1]; + + // - create glad1 w/o context + // - create context using glad1 and assign it to glad1 + { + testGLADOneLifecycle(caps, offscreenLayer ? GLADType.GLCanvasOffscreen : GLADType.GLCanvasOnscreen, width, height, + glelTracker, snapshotGLEventListener, + null, + glels, animator); + } + + // - create glad2 w/ survived context + { + testGLADOneLifecycle(caps, offscreenLayer ? GLADType.GLCanvasOffscreen : GLADType.GLCanvasOnscreen, width+100, height+100, + glelTracker, snapshotGLEventListener, + glels[0], + null, null); + } + animator.stop(); + } + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + try { + duration = Integer.parseInt(args[i]); + } catch (Exception ex) { ex.printStackTrace(); } + } + } + /** + BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); + System.err.println("Press enter to continue"); + System.err.println(stdin.readLine()); */ + org.junit.runner.JUnitCore.main(TestGLContextDrawableSwitch12AWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch21Newt2AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch21Newt2AWT.java new file mode 100644 index 000000000..d56054886 --- /dev/null +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch21Newt2AWT.java @@ -0,0 +1,165 @@ +/** + * Copyright 2013 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.jogl.acore.glels; + +import java.io.IOException; + +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLProfile; + +import jogamp.opengl.GLEventListenerState; + +import com.jogamp.opengl.util.Animator; + +import com.jogamp.opengl.test.junit.util.GLEventListenerCounter; + +import org.junit.Test; + +/** + * Test re-association of GLContext/GLDrawables, + * here GLContext's survival of GLDrawable destruction + * and reuse w/ new or recreated GLDrawable. + * <p> + * Test utilizes {@link GLEventListenerState} for preserving the + * GLAutoDrawable state, i.e. GLContext, all GLEventListener + * and the GLAnimatorControl association. + * </p> + * <p> + * This test moves the {@link GLEventListenerState} from a + * NEWT GLWindow before it's destruction to an AWT GLCanvas after it's creation + * and vice versa + * </p> + * <p> + * See Bug 665 - https://jogamp.org/bugzilla/show_bug.cgi?id=665. + * </p> + */ +public class TestGLContextDrawableSwitch21Newt2AWT extends GLContextDrawableSwitchBase { + + @Test(timeout=30000) + public void test01GLCanvasOnScrn2GLWindowGL2ES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES2); + if(null == reqGLCaps) return; + testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLCanvasOnscreen, GLADType.GLWindow); + } + + @Test(timeout=30000) + public void test02GLCanvasOnScrn2GLWindowGLES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLCanvasOnscreen, GLADType.GLWindow); + } + + @Test(timeout=30000) + public void test11GLWindow2GLCanvasOnScrnGL2ES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES2); + if(null == reqGLCaps) return; + testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLWindow, GLADType.GLCanvasOnscreen); + } + + @Test(timeout=30000) + public void test12GLWindow2GLCanvasOnScrnGLES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLWindow, GLADType.GLCanvasOnscreen); + } + + @Test(timeout=30000) + public void test21GLCanvasOffScrn2GLWindowGL2ES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES2); + if(null == reqGLCaps) return; + testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLCanvasOffscreen, GLADType.GLWindow); + } + + @Test(timeout=30000) + public void test22GLCanvasOffScrn2GLWindowGLES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLCanvasOffscreen, GLADType.GLWindow); + } + + @Test(timeout=30000) + public void test31GLWindow2GLCanvasOffScrnGL2ES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GL2ES2); + if(null == reqGLCaps) return; + testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLWindow, GLADType.GLCanvasOffscreen); + } + + @Test(timeout=30000) + public void test32GLWindow2GLCanvasOffScrnGLES2() throws InterruptedException { + final GLCapabilities reqGLCaps = getCaps(GLProfile.GLES2); + if(null == reqGLCaps) return; + testGLCanvas2GLWindowImpl(reqGLCaps, GLADType.GLWindow, GLADType.GLCanvasOffscreen); + } + + private void testGLCanvas2GLWindowImpl(GLCapabilities caps, GLADType gladType1, GLADType gladType2) throws InterruptedException { + if( !validateOnOffscreenLayer(gladType1, gladType2) ) { + return; + } + final SnapshotGLEventListener snapshotGLEventListener = new SnapshotGLEventListener(); + final GLEventListenerCounter glelTracker = new GLEventListenerCounter(); + final Animator animator = new Animator(); + animator.start(); + + final GLEventListenerState glels[] = new GLEventListenerState[1]; + + // - create glad1 w/o context + // - create context using glad1 and assign it to glad1 + { + testGLADOneLifecycle(caps, gladType1, width, height, + glelTracker, snapshotGLEventListener, + null, + glels, animator); + } + + // - create glad2 w/ survived context + { + testGLADOneLifecycle(caps, gladType2, width+100, height+100, + glelTracker, snapshotGLEventListener, + glels[0], + null, null); + } + animator.stop(); + } + + public static void main(String args[]) throws IOException { + for(int i=0; i<args.length; i++) { + if(args[i].equals("-time")) { + i++; + try { + duration = Integer.parseInt(args[i]); + } catch (Exception ex) { ex.printStackTrace(); } + } + } + /** + BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); + System.err.println("Press enter to continue"); + System.err.println(stdin.readLine()); */ + org.junit.runner.JUnitCore.main(TestGLContextDrawableSwitch21Newt2AWT.class.getName()); + } +} diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java index ad2165301..fd99b4f61 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NewtCanvasAWT.java @@ -57,6 +57,7 @@ import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; import javax.media.nativewindow.util.Dimension; +import javax.media.nativewindow.util.InsetsImmutable; import javax.media.nativewindow.util.Point; import javax.media.nativewindow.util.PointImmutable; import javax.media.nativewindow.util.DimensionImmutable; @@ -247,7 +248,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { animator.setModeBits(false, Animator.MODE_EXPECT_AWT_RENDERING_THREAD); animator.setExclusiveContext(exclusiveContext); - QuitAdapter quitAdapter = new QuitAdapter(); + final QuitAdapter quitAdapter = new QuitAdapter(); //glWindow.addKeyListener(new TraceKeyAdapter(quitAdapter)); //glWindow.addWindowListener(new TraceWindowAdapter(quitAdapter)); glWindow.addKeyListener(quitAdapter); @@ -265,6 +266,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { glWindow.addKeyListener(new KeyAdapter() { public void keyTyped(KeyEvent e) { if(e.getKeyChar()=='f') { + quitAdapter.enable(false); new Thread() { public void run() { final Thread t = glWindow.setExclusiveContextThread(null); @@ -272,7 +274,32 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { glWindow.setFullscreen(!glWindow.isFullscreen()); System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets()); glWindow.setExclusiveContextThread(t); + quitAdapter.clear(); + quitAdapter.enable(true); } }.start(); + } else if(e.getKeyChar()=='r') { + quitAdapter.enable(false); + if(glWindow.getParent()==null) { + System.err.println("XXX glWin to home"); + glWindow.reparentWindow(newtCanvasAWT.getNativeWindow()); + } else { + final InsetsImmutable nInsets = glWindow.getInsets(); + java.awt.Insets aInsets = frame.getInsets(); + System.err.println("XXX glWin to TOP - insets " + nInsets + ", " + aInsets); + glWindow.reparentWindow(null); + int dx, dy; + if(nInsets.getTotalHeight()==0) { + dx = aInsets.left; + dy = aInsets.top; + } else { + dx = nInsets.getLeftWidth(); + dy = nInsets.getTopHeight(); + } + glWindow.setPosition(frame.getX()+frame.getWidth()+dx, frame.getY()+dy); + } + glWindow.requestFocus(); + quitAdapter.clear(); + quitAdapter.enable(true); } } }); @@ -308,7 +335,7 @@ public class TestGearsES2NewtCanvasAWT extends UITestCase { System.err.println("window resize "+rwsize+" -> pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets()); } - while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) { + while(!quitAdapter.shouldQuit() && animator.getTotalFPSDuration()<duration) { Thread.sleep(100); } diff --git a/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java index 42d68dadb..59e243171 100644 --- a/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java +++ b/src/test/com/jogamp/opengl/test/junit/util/QuitAdapter.java @@ -32,18 +32,27 @@ import com.jogamp.newt.event.*; public class QuitAdapter extends WindowAdapter implements WindowListener, KeyListener { boolean shouldQuit = false; + boolean enabled = true; + public void enable(boolean v) { enabled = v; } + + public void clear() { shouldQuit = false; } + public boolean shouldQuit() { return shouldQuit; } public void windowDestroyNotify(WindowEvent e) { - System.err.println("QUIT Window "+Thread.currentThread()); - shouldQuit = true; + if( enabled ) { + System.err.println("QUIT Window "+Thread.currentThread()); + shouldQuit = true; + } } public void keyTyped(KeyEvent e) { - if(e.getKeyChar()=='q') { - System.err.println("QUIT Key "+Thread.currentThread()); - shouldQuit = true; + if( enabled ) { + if(e.getKeyChar()=='q') { + System.err.println("QUIT Key "+Thread.currentThread()); + shouldQuit = true; + } } } public void keyPressed(KeyEvent e) {} |