1 /** 2 * Copyright 2010 JogAmp Community. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without modification, are 5 * permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, this list of 8 * conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 * of conditions and the following disclaimer in the documentation and/or other materials 12 * provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED 15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 * The views and conclusions contained in the software and documentation are those of the 25 * authors and should not be interpreted as representing official policies, either expressed 26 * or implied, of JogAmp Community. 27 */ 28 29 package com.jogamp.opengl.test.junit.newt.event; 30 31 import java.lang.reflect.*; 32 import java.util.HashSet; 33 import java.util.Iterator; 34 import java.util.Set; 35 36 import org.junit.Assert; 37 import org.junit.BeforeClass; 38 import org.junit.Test; 39 import org.junit.FixMethodOrder; 40 import org.junit.runners.MethodSorters; 41 42 import java.awt.AWTException; 43 import java.awt.AWTKeyStroke; 44 import java.awt.BorderLayout; 45 import java.awt.Button; 46 import java.awt.Dimension; 47 import java.awt.Frame; 48 import java.awt.KeyboardFocusManager; 49 import java.awt.Robot; 50 51 import com.jogamp.opengl.*; 52 53 import com.jogamp.opengl.util.Animator; 54 import com.jogamp.newt.*; 55 import com.jogamp.newt.opengl.*; 56 import com.jogamp.newt.awt.NewtCanvasAWT; 57 import com.jogamp.newt.event.KeyAdapter; 58 import com.jogamp.newt.event.KeyEvent; 59 60 import java.io.IOException; 61 62 import jogamp.newt.driver.DriverClearFocus; 63 64 import com.jogamp.opengl.test.junit.util.*; 65 import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; 66 import com.jogamp.opengl.test.junit.newt.parenting.NewtAWTReparentingKeyAdapter; 67 68 /** 69 * Testing focus <i>key</i> traversal of an AWT component tree with {@link NewtCanvasAWT} attached. 70 * <p> 71 * {@link Frame} [ Button*, {@link NewtCanvasAWT} . {@link GLWindow} ] 72 * </p> 73 */ 74 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 75 public class TestParentingFocus03KeyTraversalAWT extends UITestCase { 76 static Dimension glSize, fSize; 77 static int numFocus = 8; 78 static long durationPerTest = numFocus * 200; 79 static GLCapabilities glCaps; 80 static boolean manual = false; 81 static boolean forceGL3 = false; 82 83 @BeforeClass initClass()84 public static void initClass() { 85 glSize = new Dimension(200,200); 86 fSize = new Dimension(300,300); 87 glCaps = new GLCapabilities( forceGL3 ? GLProfile.get(GLProfile.GL3) : null ); 88 } 89 90 @Test testWindowParentingAWTFocusTraversal01Onscreen()91 public void testWindowParentingAWTFocusTraversal01Onscreen() throws InterruptedException, InvocationTargetException, AWTException { 92 testWindowParentingAWTFocusTraversal(true); 93 } 94 95 @Test testWindowParentingAWTFocusTraversal02Offscreen()96 public void testWindowParentingAWTFocusTraversal02Offscreen() throws InterruptedException, InvocationTargetException, AWTException { 97 testWindowParentingAWTFocusTraversal(false); 98 } 99 testWindowParentingAWTFocusTraversal(final boolean onscreen)100 public void testWindowParentingAWTFocusTraversal(final boolean onscreen) throws InterruptedException, InvocationTargetException, AWTException { 101 final Robot robot = new Robot(); 102 103 // Bug 4908075 - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4908075 104 // Bug 6463168 - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6463168 105 { 106 final KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); 107 final Set<AWTKeyStroke> bwdKeys = kfm.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); 108 final AWTKeyStroke newBack = AWTKeyStroke.getAWTKeyStroke(java.awt.event.KeyEvent.VK_BACK_SPACE, 0, false); 109 Assert.assertNotNull(newBack); 110 final Set<AWTKeyStroke> bwdKeys2 = new HashSet<AWTKeyStroke>(bwdKeys); 111 bwdKeys2.add(newBack); 112 kfm.setDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, bwdKeys2); 113 } 114 { 115 final KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); 116 final Set<AWTKeyStroke> fwdKeys = kfm.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS); 117 final Set<AWTKeyStroke> bwdKeys = kfm.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS); 118 Iterator<AWTKeyStroke> iter; 119 for(iter = fwdKeys.iterator(); iter.hasNext(); ) { 120 System.err.println("FTKL.fwd-keys: "+iter.next()); 121 } 122 for(iter = bwdKeys.iterator(); iter.hasNext(); ) { 123 System.err.println("FTKL.bwd-keys: "+iter.next()); 124 } 125 } 126 127 final Frame frame1 = new Frame("AWT Parent Frame"); 128 final Button cWest = new Button("WEST"); 129 final Button cEast = new Button("EAST"); 130 final GLWindow glWindow1 = GLWindow.create(glCaps); 131 glWindow1.setUpdateFPSFrames(1, null); 132 final NewtCanvasAWT newtCanvasAWT1 = new NewtCanvasAWT(glWindow1); 133 newtCanvasAWT1.setPreferredSize(glSize); 134 newtCanvasAWT1.setShallUseOffscreenLayer(!onscreen); 135 newtCanvasAWT1.setFocusable(true); 136 137 // Test FocusAdapter 138 final NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1"); 139 glWindow1.addWindowListener(glWindow1FA); 140 final AWTFocusAdapter bWestFA = new AWTFocusAdapter("WEST"); 141 cWest.addFocusListener(bWestFA); 142 final AWTFocusAdapter bEastFA = new AWTFocusAdapter("EAST"); 143 cEast.addFocusListener(bEastFA); 144 145 // Test KeyAdapter 146 final NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1"); 147 glWindow1.addKeyListener(glWindow1KA); 148 final AWTKeyAdapter bWestKA = new AWTKeyAdapter("West"); 149 cWest.addKeyListener(bWestKA); 150 final AWTKeyAdapter bEastKA = new AWTKeyAdapter("East"); 151 cEast.addKeyListener(bEastKA); 152 153 // demo .. 154 final GLEventListener demo1 = new GearsES2(1); 155 setDemoFields(demo1, glWindow1, false); 156 glWindow1.addGLEventListener(demo1); 157 glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1)); 158 glWindow1.addKeyListener(new KeyAdapter() { 159 public void keyReleased(final KeyEvent e) { 160 if( !e.isPrintableKey() || e.isAutoRepeat() ) { 161 return; 162 } 163 if(e.getKeyChar()=='c') { 164 System.err.println("Focus Clear"); 165 if(glWindow1.getDelegatedWindow() instanceof DriverClearFocus) { 166 ((DriverClearFocus)glWindow1.getDelegatedWindow()).clearFocus(); 167 } 168 } else if(e.getKeyChar()=='e') { 169 System.err.println("Focus East"); 170 try { 171 java.awt.EventQueue.invokeLater(new Runnable() { 172 public void run() { 173 cEast.requestFocusInWindow(); 174 } 175 }); 176 } catch (final Exception ex) { ex.printStackTrace(); } 177 } else if(e.getKeyChar()=='w') { 178 System.err.println("Focus West"); 179 try { 180 java.awt.EventQueue.invokeLater(new Runnable() { 181 public void run() { 182 cWest.requestFocusInWindow(); 183 } 184 }); 185 } catch (final Exception ex) { ex.printStackTrace(); } 186 } 187 } 188 }); 189 final GLAnimatorControl animator1 = new Animator(glWindow1); 190 animator1.start(); 191 192 // make frame 193 frame1.setLayout(new BorderLayout()); 194 frame1.setLayout(new BorderLayout()); 195 frame1.add(cWest, BorderLayout.WEST); 196 frame1.add(newtCanvasAWT1, BorderLayout.CENTER); 197 frame1.add(cEast, BorderLayout.EAST); 198 199 javax.swing.SwingUtilities.invokeAndWait(new Runnable() { 200 public void run() { 201 frame1.setLocation(0, 0); 202 frame1.setSize(fSize); 203 frame1.validate(); 204 frame1.setVisible(true); 205 }}); 206 Assert.assertEquals(true, AWTRobotUtil.waitForVisible(glWindow1, true)); 207 Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow1, true)); 208 Assert.assertEquals(newtCanvasAWT1.getNativeWindow(),glWindow1.getParent()); 209 AWTRobotUtil.clearAWTFocus(robot); 210 Assert.assertTrue(AWTRobotUtil.toFrontAndRequestFocus(robot, frame1)); 211 212 Assert.assertEquals(true, animator1.isAnimating()); 213 // Assert.assertEquals(false, animator1.isPaused()); 214 Assert.assertNotNull(animator1.getThread()); 215 216 if(manual) { 217 Thread.sleep(durationPerTest); 218 } else { 219 // 220 // initial focus on bWest 221 // 222 AWTRobotUtil.assertRequestFocusAndWait(robot, cWest, cWest, bWestFA, null); 223 Thread.sleep(durationPerTest/numFocus); 224 225 // 226 // forth 227 // 228 229 // bWest -> glWin 230 AWTRobotUtil.keyType(0, robot, java.awt.event.KeyEvent.VK_TAB, cWest, null); 231 Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(glWindow1, glWindow1FA, bWestFA)); 232 Assert.assertEquals(true, glWindow1FA.focusGained()); 233 Assert.assertEquals(true, bWestFA.focusLost()); 234 Thread.sleep(durationPerTest/numFocus); 235 236 // glWin -> bEast 237 AWTRobotUtil.keyType(0, robot, java.awt.event.KeyEvent.VK_TAB, glWindow1, null); 238 Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(cEast, bEastFA, glWindow1FA)); 239 Assert.assertEquals(true, bEastFA.focusGained()); 240 Assert.assertEquals(true, glWindow1FA.focusLost()); 241 Thread.sleep(durationPerTest/numFocus); 242 243 // 244 // back (using custom back traversal key 'backspace') 245 // 246 // bEast -> glWin 247 AWTRobotUtil.keyType(0, robot, java.awt.event.KeyEvent.VK_BACK_SPACE, cEast, null); 248 Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(glWindow1, glWindow1FA, bEastFA)); 249 Assert.assertEquals(true, glWindow1FA.focusGained()); 250 Assert.assertEquals(true, bEastFA.focusLost()); 251 Thread.sleep(durationPerTest/numFocus); 252 253 AWTRobotUtil.keyType(0, robot, java.awt.event.KeyEvent.VK_BACK_SPACE, glWindow1, null); 254 Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(cWest, bWestFA, glWindow1FA)); 255 Assert.assertEquals(true, bWestFA.focusGained()); 256 Assert.assertEquals(true, glWindow1FA.focusLost()); 257 Thread.sleep(durationPerTest/numFocus); 258 259 System.err.println("Test: Direct NewtCanvasAWT focus"); 260 try { 261 java.awt.EventQueue.invokeAndWait(new Runnable() { 262 public void run() { 263 newtCanvasAWT1.requestFocus(); 264 } 265 }); 266 } catch (final Exception ex) { ex.printStackTrace(); } 267 Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(glWindow1, glWindow1FA, bWestFA)); 268 Assert.assertEquals(true, glWindow1FA.focusGained()); 269 Assert.assertEquals(true, bWestFA.focusLost()); 270 Thread.sleep(durationPerTest/numFocus); 271 272 System.err.println("Test: Direct AWT Button-West focus"); 273 try { 274 java.awt.EventQueue.invokeAndWait(new Runnable() { 275 public void run() { 276 cWest.requestFocus(); 277 } 278 }); 279 } catch (final Exception ex) { ex.printStackTrace(); } 280 Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(cWest, bWestFA, glWindow1FA)); 281 Assert.assertEquals(true, bWestFA.focusGained()); 282 Assert.assertEquals(true, glWindow1FA.focusLost()); 283 Thread.sleep(durationPerTest/numFocus); 284 285 System.err.println("Test: Direct NEWT-Child request focus"); 286 glWindow1.requestFocus(); 287 { 288 // Short: Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(glWindow1, glWindow1FA, bWestFA)); 289 // More verbose: 290 final boolean ok = AWTRobotUtil.waitForFocus(glWindow1, glWindow1FA, bWestFA); 291 System.err.println("glWindow hasFocus "+glWindow1.hasFocus()); 292 System.err.println("glWindow1FA "+glWindow1FA); 293 System.err.println("bWestFA "+bWestFA); 294 Assert.assertTrue("Did not gain focus", ok); 295 } 296 Assert.assertEquals(true, glWindow1FA.focusGained()); 297 Assert.assertEquals(true, bWestFA.focusLost()); 298 Thread.sleep(durationPerTest/numFocus); 299 } 300 301 animator1.stop(); 302 Assert.assertEquals(false, animator1.isAnimating()); 303 Assert.assertEquals(false, animator1.isPaused()); 304 Assert.assertEquals(null, animator1.getThread()); 305 306 javax.swing.SwingUtilities.invokeAndWait(new Runnable() { 307 public void run() { 308 frame1.dispose(); 309 } } ); 310 glWindow1.destroy(); 311 } 312 setDemoFields(final GLEventListener demo, final GLWindow glWindow, final boolean debug)313 public static void setDemoFields(final GLEventListener demo, final GLWindow glWindow, final boolean debug) { 314 Assert.assertNotNull(demo); 315 Assert.assertNotNull(glWindow); 316 final Window window = glWindow.getDelegatedWindow(); 317 if(debug) { 318 MiscUtils.setFieldIfExists(demo, "glDebug", true); 319 MiscUtils.setFieldIfExists(demo, "glTrace", true); 320 } 321 if(!MiscUtils.setFieldIfExists(demo, "window", window)) { 322 MiscUtils.setFieldIfExists(demo, "glWindow", glWindow); 323 } 324 } 325 atoi(final String a)326 static int atoi(final String a) { 327 int i=0; 328 try { 329 i = Integer.parseInt(a); 330 } catch (final Exception ex) { ex.printStackTrace(); } 331 return i; 332 } 333 main(final String args[])334 public static void main(final String args[]) throws IOException { 335 for(int i=0; i<args.length; i++) { 336 if(args[i].equals("-time")) { 337 durationPerTest = atoi(args[++i]); 338 } else if(args[i].equals("-manual")) { 339 manual = true; 340 } else if(args[i].equals("-gl3")) { 341 forceGL3 = true; 342 } 343 } 344 final String tstname = TestParentingFocus03KeyTraversalAWT.class.getName(); 345 /* 346 org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] { 347 tstname, 348 "filtertrace=true", 349 "haltOnError=false", 350 "haltOnFailure=false", 351 "showoutput=true", 352 "outputtoformatters=true", 353 "logfailedtests=true", 354 "logtestlistenerevents=true", 355 "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter", 356 "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); */ 357 org.junit.runner.JUnitCore.main(tstname); 358 } 359 360 } 361