1 /* 2 * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 @test 26 @key headful 27 @bug 6187066 28 @summary Tests the Window.autoRequestFocus property for the Window.toFront() method. 29 @author anton.tarasov: area=awt.focus 30 @library /java/awt/patchlib ../../regtesthelpers 31 @build java.desktop/java.awt.Helper 32 @build Util 33 @run main AutoRequestFocusToFrontTest 34 */ 35 36 import java.awt.*; 37 import java.awt.event.*; 38 import java.applet.Applet; 39 import java.util.concurrent.atomic.AtomicBoolean; 40 import java.lang.reflect.InvocationTargetException; 41 import test.java.awt.regtesthelpers.Util; 42 43 public class AutoRequestFocusToFrontTest extends Applet { 44 static boolean haveDelays; 45 46 static Frame auxFrame; 47 static Frame frame; 48 static Button frameButton; 49 static Frame frame2; 50 static Button frameButton2; 51 static Frame frame3; 52 static Button frameButton3; 53 static Window window; 54 static Button winButton; 55 static Dialog dialog; 56 static Button dlgButton; 57 static Window ownedWindow; 58 static Button ownWinButton; 59 static Dialog ownedDialog; 60 static Button ownDlgButton; 61 static Dialog modalDialog; 62 static Button modalDlgButton; 63 64 static String toolkitClassName; 65 static Robot robot = Util.createRobot(); 66 67 public static void main(String[] args) { 68 69 if (args.length != 0) { 70 haveDelays = "delay".equals(args[0]) ? true : false; 71 } 72 73 AutoRequestFocusToFrontTest app = new AutoRequestFocusToFrontTest(); 74 app.init(); 75 app.start(); 76 } 77 78 public void init() { 79 // Create instructions for the user here, as well as set up 80 // the environment -- set the layout manager, add buttons, 81 // etc. 82 this.setLayout (new BorderLayout ()); 83 Sysout.createDialogWithInstructions(new String[] 84 {"This is an automatic test. Simply wait until it is done." 85 }); 86 toolkitClassName = Toolkit.getDefaultToolkit().getClass().getName(); 87 } 88 89 static void recreateGUI() { 90 if (auxFrame != null) { 91 auxFrame.dispose(); 92 frame.dispose(); 93 frame2.dispose(); 94 frame3.dispose(); 95 window.dispose(); 96 dialog.dispose(); 97 ownedWindow.dispose(); 98 ownedDialog.dispose(); 99 modalDialog.dispose(); 100 } 101 102 auxFrame = new Frame("Auxiliary Frame"); 103 104 frame = new Frame("Test Frame"); 105 frameButton = new Button("button"); 106 107 frame2 = new Frame("Test Frame 2"); 108 frameButton2 = new Button("button"); 109 110 frame3 = new Frame("Test Frame 3"); 111 frameButton3 = new Button("button"); 112 113 window = new Window(null); 114 winButton = new Button("button"); 115 dialog = new Dialog((Frame)null, "Test Dialog"); 116 dlgButton = new Button("button"); 117 118 ownedWindow = new Window(frame); 119 ownWinButton = new Button("button"); 120 121 ownedDialog = new Dialog(frame2, "Test Owned Dialog"); 122 ownDlgButton = new Button("button"); 123 124 modalDialog = new Dialog(frame3, "Test Modal Dialog"); 125 modalDlgButton = new Button("button"); 126 127 auxFrame.setBounds(100, 100, 300, 300); 128 129 frame.setBounds(120, 120, 260, 260); 130 frame.add(frameButton); 131 132 frame2.setBounds(120, 120, 260, 260); 133 frame2.add(frameButton2); 134 135 frame3.setBounds(120, 120, 260, 260); 136 frame3.add(frameButton3); 137 138 window.setBounds(120, 120, 260, 260); 139 window.add(winButton); 140 141 dialog.setBounds(120, 120, 260, 260); 142 dialog.add(dlgButton); 143 144 ownedWindow.setBounds(140, 140, 220, 220); 145 ownedWindow.add(ownWinButton); 146 147 ownedDialog.setBounds(140, 140, 220, 220); 148 ownedDialog.add(ownDlgButton); 149 150 modalDialog.setBounds(140, 140, 220, 220); 151 modalDialog.add(modalDlgButton); 152 modalDialog.setModal(true); 153 } 154 155 public void start() { 156 // 1. Simple Frame. 157 ////////////////// 158 159 recreateGUI(); 160 Test.setWindows(frame, null, null); 161 Test.test("Test stage 1 in progress", frameButton); 162 163 164 // 2. Ownerless Window. 165 ////////////////////// 166 167 recreateGUI(); 168 Test.setWindows(window, null, null); 169 Test.test("Test stage 2 in progress", winButton); 170 171 172 // 3. Ownerless Dialog. 173 ////////////////////// 174 175 recreateGUI(); 176 Test.setWindows(dialog, null, null); 177 Test.test("Test stage 3 in progress", dlgButton); 178 179 180 // 4.1. Owner Frame (with owned Window). 181 /////////////////////////////////////// 182 183 recreateGUI(); 184 Test.setWindows(frame, null, new Window[] {ownedWindow, frame}); 185 Test.test("Test stage 4.1 in progress", ownWinButton); 186 187 188 // 4.2. Owned Window (with owner Frame). 189 /////////////////////////////////////// 190 191 recreateGUI(); 192 Test.setWindows(ownedWindow, null, new Window[] {ownedWindow, frame}); 193 Test.test("Test stage 4.2 in progress", ownWinButton); 194 195 196 // 5.1. Owner Frame (with owned Dialog). 197 /////////////////////////////////////// 198 199 recreateGUI(); 200 Test.setWindows(frame2, null, new Window[] {ownedDialog, frame2}); 201 Test.test("Test stage 5.1 in progress", ownDlgButton); 202 203 204 // 5.2. Owned Dialog (with owner Frame). 205 /////////////////////////////////////// 206 207 recreateGUI(); 208 Test.setWindows(ownedDialog, null, new Window[] {ownedDialog, frame2}); 209 Test.test("Test stage 5.2 in progress", ownDlgButton); 210 211 212 //////////////////////////////////////////////// 213 // 6.1. Owned modal Dialog (with owner Frame). 214 // Focused frame is excluded from modality. 215 //////////////////////////////////////////////// 216 217 if (!"sun.awt.motif.MToolkit".equals(toolkitClassName)) { 218 recreateGUI(); 219 auxFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE); 220 221 Test.setWindows(modalDialog, modalDialog, new Window[] {modalDialog, frame3}); 222 Test.test("Test stage 6.1 in progress", modalDlgButton); 223 } 224 225 226 // 6.2. Owner Frame (with owned modal Dialog). 227 // Focused frame is excluded from modality. 228 //////////////////////////////////////////////// 229 230 if (!"sun.awt.motif.MToolkit".equals(toolkitClassName)) { 231 recreateGUI(); 232 auxFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE); 233 234 Test.setWindows(frame3, modalDialog, new Window[] {modalDialog, frame3}); 235 Test.test("Test stage 6.2 in progress", modalDlgButton, true); 236 } 237 238 /////////////////////////////////////////////////// 239 // 7. Calling setVisible(true) for the shown Frame. 240 /////////////////////////////////////////////////// 241 242 recreateGUI(); 243 Test.setWindows(frame, null, null); 244 Test.setTestSetVisible(); 245 Test.test("Test stage 7 in progress", frameButton); 246 247 248 Sysout.println("Test passed."); 249 } 250 251 static class Test { 252 static Window testWindow; // a window to move to front with autoRequestFocus set 253 static Window focusWindow; // a window to gain focus 254 static Window[] showWindows; // windows to show, or null if only testWindow should be shown 255 256 static boolean testSetVisible; 257 258 static void setWindows(Window _testWindow, Window _focusWindow, Window[] _showWindows) { 259 testWindow = _testWindow; 260 focusWindow = _focusWindow; 261 showWindows = _showWindows; 262 } 263 static void setTestSetVisible() { 264 testSetVisible = true; 265 } 266 267 /* 268 * @param msg notifies test stage number 269 * @param testButton a button of the window (owner or owned) that is to be on the top of stack order 270 * @param shouldFocusChange true for modal dialogs 271 */ 272 static void test(String msg, final Button testButton, boolean shouldFocusChange) { 273 Sysout.println(msg); 274 275 showWindows(testWindow, showWindows, true); 276 277 pause(100); 278 279 ///////////////////////////////////////////////////////// 280 // Test that calling toFront() doesn't cause focus change 281 // when 'autoRequestFocus' is false. 282 ///////////////////////////////////////////////////////// 283 284 Runnable action = new Runnable() { 285 public void run() { 286 testWindow.setAutoRequestFocus(false); 287 if (testSetVisible) { 288 setVisible(testWindow, true); 289 } else { 290 toFront(testWindow); 291 } 292 } 293 }; 294 295 if (shouldFocusChange) { 296 action.run(); 297 Util.waitForIdle(robot); 298 if (!focusWindow.isFocused()) { 299 throw new TestFailedException("the window must gain focus on moving to front but it didn't!"); 300 } 301 } else if (TestHelper.trackFocusChangeFor(action, robot)) { 302 throw new TestFailedException("the window shouldn't gain focus on moving to front but it did!"); 303 } 304 305 pause(100); 306 307 /////////////////////////////////////////////////////// 308 // Test that the window (or its owned window) is on top. 309 /////////////////////////////////////////////////////// 310 311 // The latest versions of Metacity (e.g. 2.16) have problems with moving a window to the front. 312 if (Util.getWMID() != Util.METACITY_WM) { 313 314 boolean performed = Util.trackActionPerformed(testButton, new Runnable() { 315 public void run() { 316 Util.clickOnComp(testButton, robot); 317 } 318 }, 1000, false); 319 320 if (!performed) { 321 // For the case when the robot failed to trigger ACTION_EVENT. 322 Sysout.println("(ACTION_EVENT was not generated. One more attemp.)"); 323 performed = Util.trackActionPerformed(testButton, new Runnable() { 324 public void run() { 325 Util.clickOnComp(testButton, robot); 326 } 327 }, 1000, false); 328 if (!performed) { 329 throw new TestFailedException("the window moved to front is not on the top!"); 330 } 331 } 332 } 333 334 showWindows(testWindow, showWindows, false); 335 336 337 ///////////////////////////////////////////////// 338 // Test that calling toFront() focuses the window 339 // when 'autoRequestFocus' is true. 340 ///////////////////////////////////////////////// 341 342 // Skip this stage for unfocusable window 343 if (!testWindow.isFocusableWindow()) { 344 return; 345 } 346 347 showWindows(testWindow, showWindows, true); 348 349 pause(100); 350 351 boolean gained = Util.trackWindowGainedFocus(testWindow, new Runnable() { 352 public void run() { 353 testWindow.setAutoRequestFocus(true); 354 if (testSetVisible) { 355 setVisible(testWindow, true); 356 } else { 357 toFront(testWindow); 358 } 359 } 360 }, 1000, false); 361 362 // Either the window or its owned window must be focused 363 if (!gained && !testButton.hasFocus()) { 364 throw new TestFailedException("the window should gain focus automatically but it didn't!"); 365 } 366 367 showWindows(testWindow, showWindows, false); 368 } 369 370 static void test(String msg, Button testButton) { 371 test(msg, testButton, false); 372 } 373 374 private static void showWindows(Window win, Window[] wins, final boolean visible) { 375 pause(100); 376 377 if (wins == null) { 378 wins = new Window[] {win}; // operate with 'win' 379 } 380 for (final Window w: wins) { 381 if (visible) { 382 if ((w instanceof Dialog) && ((Dialog)w).isModal()) { 383 TestHelper.invokeLaterAndWait(new Runnable() { 384 public void run() { 385 w.setVisible(true); 386 } 387 }, robot); 388 } else { 389 setVisible(w, true); 390 } 391 } else { 392 w.dispose(); 393 } 394 } 395 setVisible(auxFrame, visible); 396 397 if (visible) { 398 if (!auxFrame.isFocused()) { 399 Util.clickOnTitle(auxFrame, robot); 400 Util.waitForIdle(robot); 401 if (!auxFrame.isFocused()) { 402 throw new Error("Test error: the frame couldn't be focused."); 403 } 404 } 405 } 406 } 407 } 408 409 private static void setVisible(Window w, boolean b) { 410 w.setVisible(b); 411 try { 412 Util.waitForIdle(robot); 413 } catch (RuntimeException rte) { // InfiniteLoop 414 rte.printStackTrace(); 415 } 416 robot.delay(200); 417 } 418 419 private static void toFront(Window w) { 420 w.toFront(); 421 Util.waitForIdle(robot); 422 robot.delay(200); 423 } 424 425 private static void pause(int msec) { 426 if (haveDelays) { 427 robot.delay(msec); 428 } 429 } 430 } 431 432 class TestFailedException extends RuntimeException { 433 TestFailedException(String msg) { 434 super("Test failed: " + msg); 435 } 436 } 437 438 /**************************************************** 439 Standard Test Machinery 440 DO NOT modify anything below -- it's a standard 441 chunk of code whose purpose is to make user 442 interaction uniform, and thereby make it simpler 443 to read and understand someone else's test. 444 ****************************************************/ 445 446 /** 447 This is part of the standard test machinery. 448 It creates a dialog (with the instructions), and is the interface 449 for sending text messages to the user. 450 To print the instructions, send an array of strings to Sysout.createDialog 451 WithInstructions method. Put one line of instructions per array entry. 452 To display a message for the tester to see, simply call Sysout.println 453 with the string to be displayed. 454 This mimics System.out.println but works within the test harness as well 455 as standalone. 456 */ 457 458 class Sysout 459 { 460 static TestDialog dialog; 461 462 public static void createDialogWithInstructions( String[] instructions ) 463 { 464 dialog = new TestDialog( new Frame(), "Instructions" ); 465 dialog.printInstructions( instructions ); 466 // dialog.setVisible(true); 467 println( "Any messages for the tester will display here." ); 468 } 469 470 public static void createDialog( ) 471 { 472 dialog = new TestDialog( new Frame(), "Instructions" ); 473 String[] defInstr = { "Instructions will appear here. ", "" } ; 474 dialog.printInstructions( defInstr ); 475 // dialog.setVisible(true); 476 println( "Any messages for the tester will display here." ); 477 } 478 479 480 public static void printInstructions( String[] instructions ) 481 { 482 dialog.printInstructions( instructions ); 483 } 484 485 486 public static void println( String messageIn ) 487 { 488 dialog.displayMessage( messageIn ); 489 } 490 491 }// Sysout class 492 493 /** 494 This is part of the standard test machinery. It provides a place for the 495 test instructions to be displayed, and a place for interactive messages 496 to the user to be displayed. 497 To have the test instructions displayed, see Sysout. 498 To have a message to the user be displayed, see Sysout. 499 Do not call anything in this dialog directly. 500 */ 501 class TestDialog extends Dialog 502 { 503 504 TextArea instructionsText; 505 TextArea messageText; 506 int maxStringLength = 80; 507 508 //DO NOT call this directly, go through Sysout 509 public TestDialog( Frame frame, String name ) 510 { 511 super( frame, name ); 512 int scrollBoth = TextArea.SCROLLBARS_BOTH; 513 instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); 514 add( "North", instructionsText ); 515 516 messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); 517 add("Center", messageText); 518 519 pack(); 520 521 // setVisible(true); 522 }// TestDialog() 523 524 //DO NOT call this directly, go through Sysout 525 public void printInstructions( String[] instructions ) 526 { 527 //Clear out any current instructions 528 instructionsText.setText( "" ); 529 530 //Go down array of instruction strings 531 532 String printStr, remainingStr; 533 for( int i=0; i < instructions.length; i++ ) 534 { 535 //chop up each into pieces maxSringLength long 536 remainingStr = instructions[ i ]; 537 while( remainingStr.length() > 0 ) 538 { 539 //if longer than max then chop off first max chars to print 540 if( remainingStr.length() >= maxStringLength ) 541 { 542 //Try to chop on a word boundary 543 int posOfSpace = remainingStr. 544 lastIndexOf( ' ', maxStringLength - 1 ); 545 546 if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; 547 548 printStr = remainingStr.substring( 0, posOfSpace + 1 ); 549 remainingStr = remainingStr.substring( posOfSpace + 1 ); 550 } 551 //else just print 552 else 553 { 554 printStr = remainingStr; 555 remainingStr = ""; 556 } 557 558 instructionsText.append( printStr + "\n" ); 559 560 }// while 561 562 }// for 563 564 }//printInstructions() 565 566 //DO NOT call this directly, go through Sysout 567 public void displayMessage( String messageIn ) 568 { 569 messageText.append( messageIn + "\n" ); 570 System.out.println(messageIn); 571 } 572 573 }// TestDialog class