From ded3ab06cc51e8e7d12f9fbfeb12e87c04f26a5a Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sun, 26 Sep 2010 20:18:31 +0200 Subject: NEWT/AWT focus tests: Enhance, use robot and programatic. Start with a focus on an AWT device. Wait until TO or event received. --- .../test/junit/newt/TestFocus01SwingAWT.java | 165 ++++++------ .../test/junit/newt/TestFocus02SwingAWT.java | 286 +++++++++++++++++++++ .../jogamp/test/junit/util/AWTFocusAdapter.java | 58 +++++ .../com/jogamp/test/junit/util/AWTKeyAdapter.java | 51 ++++ .../com/jogamp/test/junit/util/AWTRobotUtil.java | 100 +++++++ .../jogamp/test/junit/util/NEWTFocusAdapter.java | 59 +++++ .../com/jogamp/test/junit/util/NEWTKeyAdapter.java | 53 ++++ .../test/junit/util/TestEventCountAdapter.java | 36 +++ 8 files changed, 718 insertions(+), 90 deletions(-) create mode 100644 src/junit/com/jogamp/test/junit/newt/TestFocus02SwingAWT.java create mode 100644 src/junit/com/jogamp/test/junit/util/AWTFocusAdapter.java create mode 100644 src/junit/com/jogamp/test/junit/util/AWTKeyAdapter.java create mode 100644 src/junit/com/jogamp/test/junit/util/AWTRobotUtil.java create mode 100644 src/junit/com/jogamp/test/junit/util/NEWTFocusAdapter.java create mode 100644 src/junit/com/jogamp/test/junit/util/NEWTKeyAdapter.java create mode 100644 src/junit/com/jogamp/test/junit/util/TestEventCountAdapter.java (limited to 'src/junit/com') diff --git a/src/junit/com/jogamp/test/junit/newt/TestFocus01SwingAWT.java b/src/junit/com/jogamp/test/junit/newt/TestFocus01SwingAWT.java index 1dac6edad..3a85b4795 100644 --- a/src/junit/com/jogamp/test/junit/newt/TestFocus01SwingAWT.java +++ b/src/junit/com/jogamp/test/junit/newt/TestFocus01SwingAWT.java @@ -1,11 +1,15 @@ package com.jogamp.test.junit.newt; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Test; import java.awt.AWTException; import java.awt.BorderLayout; +import java.awt.Button; import java.awt.Robot; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; @@ -29,6 +33,8 @@ import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.util.Animator; import com.jogamp.test.junit.jogl.demos.es1.RedSquare; +import com.jogamp.test.junit.util.*; + public class TestFocus01SwingAWT { static { @@ -49,7 +55,18 @@ public class TestFocus01SwingAWT { } @Test - public void testNewtCanvasAWTRequestFocus() throws AWTException, + public void testFocus01ProgrFocus() throws AWTException, InterruptedException, InvocationTargetException { + testFocus01ProgrFocusImpl(null); + } + + @Test + public void testFocus02RobotFocus() throws AWTException, InterruptedException, InvocationTargetException { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + testFocus01ProgrFocusImpl(robot); + } + + private void testFocus01ProgrFocusImpl(Robot robot) throws AWTException, InvocationTargetException, InterruptedException { // Create a window. GLWindow glWindow1 = GLWindow.create(glCaps); @@ -57,70 +74,98 @@ public class TestFocus01SwingAWT { GLEventListener demo1 = new RedSquare(); TestListenerCom01AWT.setDemoFields(demo1, glWindow1, false); glWindow1.addGLEventListener(demo1); + NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1"); + glWindow1.addWindowListener(glWindow1FA); // Monitor NEWT focus and keyboard events. - NewtKeyAdapter newtKeyAdapter = new NewtKeyAdapter(); + NEWTKeyAdapter newtKeyAdapter = new NEWTKeyAdapter("GLWindow1"); glWindow1.addKeyListener(newtKeyAdapter); - NewtFocusAdapter newtFocusAdapter = new NewtFocusAdapter(); - glWindow1.addWindowListener(newtFocusAdapter); // Wrap the window in a canvas. final NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); // Monitor AWT focus and keyboard events. - AWTKeyAdapter awtKeyAdapter = new AWTKeyAdapter(); + AWTKeyAdapter awtKeyAdapter = new AWTKeyAdapter("NewtCanvasAWT"); newtCanvasAWT.addKeyListener(awtKeyAdapter); - AWTFocusAdapter awtFocusAdapter = new AWTFocusAdapter(); - newtCanvasAWT.addFocusListener(awtFocusAdapter); + AWTFocusAdapter newtCanvasAWTFA = new AWTFocusAdapter("NewtCanvasAWT"); + newtCanvasAWT.addFocusListener(newtCanvasAWTFA); // Add the canvas to a frame, and make it all visible. JFrame frame1 = new JFrame("Swing AWT Parent Frame: " + glWindow1.getTitle()); frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER); + Button button = new Button("Click me .."); + AWTFocusAdapter buttonFA = new AWTFocusAdapter("Button"); + button.addFocusListener(buttonFA); + frame1.getContentPane().add(button, BorderLayout.NORTH); frame1.setSize(width, height); frame1.setVisible(true); - // Request the focus, which should automatically provide the window - // with focus. - newtCanvasAWT.requestFocus(); + int wait=0; + while(wait<10 && glWindow1.getTotalFrames()<1) { Thread.sleep(100); wait++; } + System.out.println("Frames for initial setVisible(true): "+glWindow1.getTotalFrames()); + Assert.assertTrue(0 < glWindow1.getTotalFrames()); + // Continuous animation .. Animator animator = new Animator(glWindow1); animator.start(); - // Wait for the window to initialize and receive focus. - // TODO Eliminate the need for this delay. - while (glWindow1.getDuration() < durationPerTest) { + // Button Focus + Thread.sleep(100); // allow event sync + System.err.println("FOCUS AWT Button request"); + AWTRobotUtil.requestFocus(robot, button); + for (wait=0; wait<10 && !button.hasFocus(); wait++) { + Thread.sleep(100); + } + Assert.assertTrue(button.hasFocus()); + Assert.assertFalse(newtCanvasAWT.getNEWTChild().hasFocus()); + Assert.assertFalse(newtCanvasAWT.hasFocus()); + Assert.assertEquals(0, glWindow1FA.getCount()); + Assert.assertEquals(0, newtCanvasAWTFA.getCount()); + Assert.assertEquals(1, buttonFA.getCount()); + System.err.println("FOCUS AWT Button sync"); + + // Request the AWT focus, which should automatically provide the NEWT window with focus. + Thread.sleep(100); // allow event sync + System.err.println("FOCUS NEWT Canvas/GLWindow request"); + AWTRobotUtil.requestFocus(robot, newtCanvasAWT); + for (wait=0; wait<10 && !newtCanvasAWT.getNEWTChild().hasFocus(); wait++) { Thread.sleep(100); } - // Verify focus status. - assertFalse("AWT parent canvas has focus", newtCanvasAWT.hasFocus()); - assertTrue(newtCanvasAWT.getNEWTChild().hasFocus()); + Assert.assertFalse("AWT parent canvas has focus", newtCanvasAWT.hasFocus()); + Assert.assertTrue(newtCanvasAWT.getNEWTChild().hasFocus()); + Assert.assertFalse(button.hasFocus()); + Assert.assertEquals(1, glWindow1FA.getCount()); + Assert.assertEquals(0, newtCanvasAWTFA.getCount()); + Assert.assertEquals(0, buttonFA.getCount()); + System.err.println("FOCUS NEWT Canvas/GLWindow sync"); // Type two keys, which should be directed to the focused window. - Robot robot = new Robot(); + if(null == robot) { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + } robot.keyPress(java.awt.event.KeyEvent.VK_A); robot.keyRelease(java.awt.event.KeyEvent.VK_A); robot.keyPress(java.awt.event.KeyEvent.VK_B); robot.keyRelease(java.awt.event.KeyEvent.VK_B); - // Wait for the events to be processed. - // TODO Eliminate the need for this delay. - while (glWindow1.getDuration() < 2 * durationPerTest) { + // Wait for the key events to be processed. + for (wait=0; wait<10 && newtKeyAdapter.getCount()<2; wait++) { Thread.sleep(100); } - assertEquals(1, awtFocusAdapter.focusLost); - assertEquals(1, newtFocusAdapter.focusGained); - assertEquals("AWT parent canvas received keyboard events", 0, - awtKeyAdapter.keyTyped); - assertEquals(2, newtKeyAdapter.keyTyped); + Assert.assertEquals(0, newtCanvasAWTFA.getCount()); + Assert.assertEquals(1, glWindow1FA.getCount()); + Assert.assertEquals("AWT parent canvas received keyboard events", 0, awtKeyAdapter.getCount()); + Assert.assertEquals(2, newtKeyAdapter.getCount()); // Remove listeners to avoid logging during dispose/destroy. glWindow1.removeKeyListener(newtKeyAdapter); - glWindow1.removeWindowListener(newtFocusAdapter); + glWindow1.removeWindowListener(glWindow1FA); newtCanvasAWT.removeKeyListener(awtKeyAdapter); - newtCanvasAWT.removeFocusListener(awtFocusAdapter); + newtCanvasAWT.removeFocusListener(newtCanvasAWTFA); // Shutdown the test. animator.stop(); @@ -128,66 +173,6 @@ public class TestFocus01SwingAWT { glWindow1.destroy(true); } - private static final class NewtFocusAdapter extends WindowAdapter { - - int focusGained = 0; - - int focusLost = 0; - - @Override - public void windowGainedFocus(WindowEvent e) { - System.out.println(e); - ++focusGained; - } - - @Override - public void windowLostFocus(WindowEvent e) { - System.out.println(e); - ++focusLost; - } - } - - private static final class AWTFocusAdapter implements FocusListener { - - int focusGained = 0; - - int focusLost = 0; - - @Override - public void focusGained(FocusEvent e) { - System.out.println(e); - ++focusGained; - } - - @Override - public void focusLost(FocusEvent e) { - System.out.println(e); - ++focusLost; - } - } - - private static final class NewtKeyAdapter extends KeyAdapter { - - int keyTyped; - - @Override - public void keyTyped(KeyEvent e) { - System.out.println(e); - ++keyTyped; - } - } - - private static final class AWTKeyAdapter extends java.awt.event.KeyAdapter { - - int keyTyped; - - @Override - public void keyTyped(java.awt.event.KeyEvent e) { - System.out.println(e); - ++keyTyped; - } - } - static int atoi(String a) { int i=0; try { diff --git a/src/junit/com/jogamp/test/junit/newt/TestFocus02SwingAWT.java b/src/junit/com/jogamp/test/junit/newt/TestFocus02SwingAWT.java new file mode 100644 index 000000000..c7948540f --- /dev/null +++ b/src/junit/com/jogamp/test/junit/newt/TestFocus02SwingAWT.java @@ -0,0 +1,286 @@ +/** + * 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.test.junit.newt; + +import java.lang.reflect.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Test; + +import java.awt.AWTException; +import java.awt.Button; +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Container; +import java.awt.Frame; +import java.awt.Dimension; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.Robot; +import java.awt.Point; +import java.awt.Rectangle; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +import javax.media.opengl.*; +import javax.media.nativewindow.*; + +import com.jogamp.opengl.util.Animator; +import com.jogamp.newt.*; +import com.jogamp.newt.event.*; +import com.jogamp.newt.opengl.*; +import com.jogamp.newt.awt.NewtCanvasAWT; + +import java.io.IOException; + +import com.jogamp.test.junit.util.*; +import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears; + +public class TestFocus02SwingAWT { + static int width, height; + static long durationPerTest = 800; + static long waitReparent = 0; + static GLCapabilities glCaps; + + @BeforeClass + public static void initClass() throws AWTException { + width = 640; + height = 480; + + JFrame f = new JFrame(); + f.setSize(100,100); + f.setVisible(true); + f.dispose(); + f=null; + + GLProfile.initSingleton(); + glCaps = new GLCapabilities(null); + } + + + private void testFocus01ProgrFocusImpl(Robot robot) throws InterruptedException, InvocationTargetException { + int x = 0; + int y = 0; + + /** + * JFrame . JPanel . Container . NewtCanvasAWT . GLWindow + */ + GLWindow glWindow1 = GLWindow.create(glCaps); + glWindow1.setTitle("testWindowParenting01CreateVisibleDestroy"); + GLEventListener demo1 = new Gears(); + glWindow1.addGLEventListener(demo1); + NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1"); + glWindow1.addWindowListener(glWindow1FA); + + NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow1); + AWTFocusAdapter newtCanvasAWTFA = new AWTFocusAdapter("NewtCanvasAWT"); + newtCanvasAWT.addFocusListener(newtCanvasAWTFA); + + Button buttonNorthInner = new Button("north"); + AWTFocusAdapter buttonNorthInnerFA = new AWTFocusAdapter("ButtonNorthInner"); + buttonNorthInner.addFocusListener(buttonNorthInnerFA); + Container container1 = new Container(); + container1.setLayout(new BorderLayout()); + container1.add(buttonNorthInner, BorderLayout.NORTH); + container1.add(new Button("south"), BorderLayout.SOUTH); + container1.add(new Button("east"), BorderLayout.EAST); + container1.add(new Button("west"), BorderLayout.WEST); + container1.add(newtCanvasAWT, BorderLayout.CENTER); + + Button buttonNorthOuter = new Button("north"); + AWTFocusAdapter buttonNorthOuterFA = new AWTFocusAdapter("ButtonNorthOuter"); + buttonNorthOuter.addFocusListener(buttonNorthOuterFA); + JPanel jPanel1 = new JPanel(); + jPanel1.setLayout(new BorderLayout()); + jPanel1.add(buttonNorthOuter, BorderLayout.NORTH); + jPanel1.add(new Button("south"), BorderLayout.SOUTH); + jPanel1.add(new Button("east"), BorderLayout.EAST); + jPanel1.add(new Button("west"), BorderLayout.WEST); + jPanel1.add(container1, BorderLayout.CENTER); + + JFrame jFrame1 = new JFrame("Swing Parent JFrame"); + AWTFocusAdapter jFrame1FA = new AWTFocusAdapter("JFrame1"); + jFrame1.addFocusListener(jFrame1FA); + // jFrame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + jFrame1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // equivalent to Frame, use windowClosing event! + jFrame1.setContentPane(jPanel1); + jFrame1.setSize(width, height); + jFrame1.setVisible(true); // from here on, we need to run modifications on EDT + + int wait=0; + while(wait<10 && glWindow1.getTotalFrames()<1) { Thread.sleep(100); wait++; } + System.err.println("Frames for initial setVisible(true): "+glWindow1.getTotalFrames()); + Assert.assertTrue(0 < glWindow1.getTotalFrames()); + + // Continuous animation .. + Animator animator1 = new Animator(glWindow1); + animator1.start(); + + // Button Outer Focus + Thread.sleep(100); // allow event sync + System.err.println("FOCUS AWT Button Outer request"); + AWTRobotUtil.requestFocus(robot, buttonNorthOuter); + for (wait=0; wait<10 && !buttonNorthOuter.hasFocus(); wait++) { + Thread.sleep(100); + } + Assert.assertTrue(buttonNorthOuter.hasFocus()); + Assert.assertFalse(newtCanvasAWT.getNEWTChild().hasFocus()); + Assert.assertFalse(newtCanvasAWT.hasFocus()); + Assert.assertEquals(0, glWindow1FA.getCount()); + Assert.assertEquals(0, newtCanvasAWTFA.getCount()); + Assert.assertEquals(1, buttonNorthOuterFA.getCount()); + Assert.assertEquals(0, buttonNorthInnerFA.getCount()); + Assert.assertEquals(0, jFrame1FA.getCount()); + System.err.println("FOCUS AWT Button Outer sync"); + + // NEWT Focus + Thread.sleep(100); // allow event sync + System.err.println("FOCUS NEWT Canvas/GLWindow request"); + AWTRobotUtil.requestFocus(robot, newtCanvasAWT); + for (wait=0; wait<10 && !newtCanvasAWT.getNEWTChild().hasFocus(); wait++) { + Thread.sleep(100); + } + Assert.assertTrue(newtCanvasAWT.getNEWTChild().hasFocus()); + Assert.assertFalse("AWT Frame has focus", jFrame1.hasFocus()); + Assert.assertFalse("AWT Button Inner has focus", buttonNorthInner.hasFocus()); + Assert.assertFalse("AWT Button Outer has focus", buttonNorthOuter.hasFocus()); + Assert.assertFalse("AWT parent canvas has focus", newtCanvasAWT.hasFocus()); + Assert.assertEquals(1, glWindow1FA.getCount()); + Assert.assertEquals(0, newtCanvasAWTFA.getCount()); + Assert.assertEquals(0, buttonNorthInnerFA.getCount()); + Assert.assertEquals(0, buttonNorthOuterFA.getCount()); + Assert.assertEquals(0, jFrame1FA.getCount()); + System.err.println("FOCUS NEWT Canvas/GLWindow sync"); + + // Button Inner Focus + Thread.sleep(100); // allow event sync + System.err.println("FOCUS AWT Button request"); + AWTRobotUtil.requestFocus(robot, buttonNorthInner); + for (wait=0; wait<10 && !buttonNorthInner.hasFocus(); wait++) { + Thread.sleep(100); + } + Assert.assertTrue(buttonNorthInner.hasFocus()); + Assert.assertFalse(buttonNorthOuter.hasFocus()); + Assert.assertFalse(newtCanvasAWT.getNEWTChild().hasFocus()); + Assert.assertFalse(newtCanvasAWT.hasFocus()); + Assert.assertEquals(0, glWindow1FA.getCount()); + Assert.assertEquals(0, newtCanvasAWTFA.getCount()); + Assert.assertEquals(1, buttonNorthInnerFA.getCount()); + Assert.assertEquals(0, buttonNorthOuterFA.getCount()); + Assert.assertEquals(0, jFrame1FA.getCount()); + System.err.println("FOCUS AWT Button sync"); + + // NEWT Focus + Thread.sleep(100); // allow event sync + System.err.println("FOCUS NEWT Canvas/GLWindow request"); + AWTRobotUtil.requestFocus(robot, newtCanvasAWT); + for (wait=0; wait<10 && !newtCanvasAWT.getNEWTChild().hasFocus(); wait++) { + Thread.sleep(100); + } + Assert.assertTrue(newtCanvasAWT.getNEWTChild().hasFocus()); + Assert.assertFalse("AWT Frame has focus", jFrame1.hasFocus()); + Assert.assertFalse("AWT Button has focus", buttonNorthInner.hasFocus()); + Assert.assertFalse("AWT Button Outer has focus", buttonNorthOuter.hasFocus()); + Assert.assertFalse("AWT parent canvas has focus", newtCanvasAWT.hasFocus()); + Assert.assertEquals(1, glWindow1FA.getCount()); + Assert.assertEquals(0, newtCanvasAWTFA.getCount()); + Assert.assertEquals(0, buttonNorthInnerFA.getCount()); + Assert.assertEquals(0, buttonNorthOuterFA.getCount()); + Assert.assertEquals(0, jFrame1FA.getCount()); + System.err.println("FOCUS NEWT Canvas/GLWindow sync"); + + animator1.stop(); + Assert.assertEquals(false, animator1.isAnimating()); + + final JFrame _jFrame1 = jFrame1; + final JPanel _jPanel1 = jPanel1; + final Container _container1 = container1; + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + _jFrame1.setVisible(false); + _jPanel1.remove(_container1); + _jFrame1.dispose(); + } }); + + glWindow1.destroy(true); + } + + @Test + public void testFocus01ProgrFocus() throws InterruptedException, InvocationTargetException { + testFocus01ProgrFocusImpl(null); + } + + @Test + public void testFocus02RobotFocus() throws AWTException, InterruptedException, InvocationTargetException { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + testFocus01ProgrFocusImpl(robot); + } + + static int atoi(String a) { + int i=0; + try { + i = Integer.parseInt(a); + } catch (Exception ex) { ex.printStackTrace(); } + return i; + } + + public static void main(String args[]) throws IOException { + for(int i=0; i