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.setVisible() method. 29 @author anton.tarasov: area=awt.focus 30 @library ../../regtesthelpers 31 @build Util 32 @run main AutoRequestFocusSetVisibleTest 33 */ 34 35 import java.awt.*; 36 import java.awt.event.*; 37 import java.applet.Applet; 38 import java.util.concurrent.atomic.AtomicBoolean; 39 import java.lang.reflect.InvocationTargetException; 40 import test.java.awt.regtesthelpers.Util; 41 42 public class AutoRequestFocusSetVisibleTest extends Applet { 43 static Frame focusedFrame; 44 static Button focusOwner; 45 static Frame frame; 46 static Button frameButton; 47 static Frame frame2; 48 static Button frameButton2; 49 static Window window; 50 static Button winButton; 51 static Window ownedWindow; 52 static Button ownWinButton; 53 static Dialog ownedDialog; 54 static Button ownDlgButton; 55 static Dialog dialog; 56 static Button dlgButton; 57 58 static String toolkitClassName; 59 static Robot robot = Util.createRobot(); 60 61 public static void main(String[] args) { 62 AutoRequestFocusSetVisibleTest app = new AutoRequestFocusSetVisibleTest(); 63 app.init(); 64 app.start(); 65 } 66 67 public void init() { 68 // Create instructions for the user here, as well as set up 69 // the environment -- set the layout manager, add buttons, 70 // etc. 71 this.setLayout (new BorderLayout ()); 72 Sysout.createDialogWithInstructions(new String[] 73 {"This is an automatic test. Simply wait until it is done." 74 }); 75 toolkitClassName = Toolkit.getDefaultToolkit().getClass().getName(); 76 } 77 78 void recreateGUI() { 79 if (focusedFrame != null) { 80 focusedFrame.dispose(); 81 frame.dispose(); 82 frame2.dispose(); 83 window.dispose(); 84 ownedWindow.dispose(); 85 ownedDialog.dispose(); 86 dialog.dispose(); 87 } 88 89 focusedFrame = new Frame("Base Frame"); 90 focusOwner = new Button("button"); 91 92 frame = new Frame("Test Frame"); 93 frameButton = new Button("button"); 94 95 frame2 = new Frame("Test Frame"); 96 frameButton2 = new Button("button"); 97 98 window = new Window(focusedFrame); 99 winButton = new Button("button"); 100 101 ownedWindow = new Window(frame) { 102 /* 103 * When 'frame' is shown along with the 'ownedWindow' 104 * (i.e. showWithParent==true) then it can appear 105 * that the 'ownedWindow' is shown too early and 106 * it can't be focused due to its owner can't be 107 * yet activated. So, to avoid this race, we pospone 108 * a little the showing of the 'ownedWindow'. 109 */ 110 public void show() { 111 robot.delay(100); 112 super.show(); 113 } 114 }; 115 ownWinButton = new Button("button"); 116 117 ownedDialog = new Dialog(frame2); 118 ownDlgButton = new Button("button"); 119 120 dialog = new Dialog(focusedFrame, "Test Dialog"); 121 dlgButton = new Button("button"); 122 123 focusedFrame.add(focusOwner); 124 focusedFrame.setBounds(100, 100, 300, 300); 125 126 frame.setBounds(140, 140, 220, 220); 127 frame.add(frameButton); 128 129 frame2.setBounds(140, 140, 220, 220); 130 frame2.add(frameButton2); 131 132 window.setBounds(140, 140, 220, 220); 133 window.add(winButton); 134 135 ownedWindow.setBounds(180, 180, 140, 140); 136 ownedWindow.add(ownWinButton); 137 138 ownedDialog.setBounds(180, 180, 140, 140); 139 ownedDialog.add(ownDlgButton); 140 141 dialog.setBounds(140, 140, 220, 220); 142 dialog.add(dlgButton); 143 } 144 145 public void start() { 146 147 /////////////////////////////////////////////////////// 148 // 1. Show Frame with owned modal Dialog without delay. 149 // Check that the Dialog takes focus. 150 /////////////////////////////////////////////////////// 151 152 recreateGUI(); 153 154 Sysout.println("Stage 1 in progress..."); 155 156 dialog.setModal(true); 157 dialog.setAutoRequestFocus(false); 158 setVisible(focusedFrame, true); 159 160 TestHelper.invokeLaterAndWait(new Runnable() { 161 public void run() { 162 dialog.setVisible(true); 163 } 164 }, robot); 165 166 if (focusOwner.hasFocus()) { 167 throw new TestFailedException("the modal dialog must gain focus but it didn't!"); 168 } 169 setVisible(dialog, false); 170 171 ////////////////////////////////////////////////// 172 // 2. Show Frame, activate, auto hide, auto show. 173 // Check that the Frame takes focus. 174 ////////////////////////////////////////////////// 175 176 recreateGUI(); 177 178 Sysout.println("Stage 2 in progress..."); 179 180 setVisible(focusedFrame, false); 181 182 focusedFrame.setAutoRequestFocus(false); 183 setVisible(focusedFrame, true); 184 185 Util.clickOnTitle(focusedFrame, robot); 186 Util.waitForIdle(robot); 187 188 if (!focusedFrame.isFocused()) { 189 throw new Error("Test error: the frame couldn't be focused."); 190 } 191 192 focusedFrame.setExtendedState(Frame.ICONIFIED); 193 Util.waitForIdle(robot); 194 focusedFrame.setExtendedState(Frame.NORMAL); 195 Util.waitForIdle(robot); 196 197 if (!focusedFrame.isFocused()) { 198 throw new TestFailedException("the restored frame must gain focus but it didn't!"); 199 } 200 201 202 //////////////////////// 203 // 3.1 Show Frame normal. 204 //////////////////////// 205 206 recreateGUI(); 207 208 test("Stage 3.1 in progress...", frame, frameButton); 209 210 211 // 3.2. Show Frame maximized both. 212 ///////////////////////////////// 213 214 if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) { 215 System.out.println("Stage 3.2: Frame.MAXIMIZED_BOTH not supported. Skipping."); 216 } else { 217 frame.setExtendedState(Frame.MAXIMIZED_BOTH); 218 219 test("Stage 3.2 in progress...", frame, frameButton); 220 } 221 222 223 // 3.3. Show Frame maximized vertically. 224 /////////////////////////////////////// 225 226 if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_VERT)) { 227 System.out.println("Stage 3.3: Frame.MAXIMIZED_VERT not supported. Skipping."); 228 } else { 229 frame.setExtendedState(Frame.MAXIMIZED_VERT); 230 231 test("Stage 3.3 in progress...", frame, frameButton); 232 } 233 234 235 // 3.4. Show Frame maximized horizontally. 236 ///////////////////////////////////////// 237 238 if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_HORIZ)) { 239 System.out.println("Stage 3.4: Frame.MAXIMIZED_HORIZ not supported. Skipping."); 240 } else { 241 frame.setExtendedState(Frame.MAXIMIZED_HORIZ); 242 243 test("Stage 3.4 in progress...", frame, frameButton); 244 } 245 246 247 // 3.5. Show Frame iconified. 248 //////////////////////////// 249 250 if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.ICONIFIED)) { 251 System.out.println("Stage 3.5: Frame.ICONIFIED not supported. Skipping."); 252 } else { 253 frame.setExtendedState(Frame.ICONIFIED); 254 255 test("Stage 3.5 in progress...", frame, frameButton); 256 } 257 258 259 /////////////////// 260 // 4.1 Show Window. 261 /////////////////// 262 recreateGUI(); 263 test("Stage 4.1 in progress...", window, winButton); 264 265 266 // 4.2 Show Dialog. 267 ////////////////// 268 269 test("Stage 4.2 in progress...", dialog, dlgButton); 270 271 272 // 4.3. Show modal Dialog. 273 ///////////////////////// 274 275 dialog.setModal(true); 276 test("Stage 4.3 in progress...", dialog, dlgButton, true); 277 278 279 /////////////////////////////////// 280 // 5.1 Show Frame with owned Window. 281 /////////////////////////////////// 282 283 // On Windows, an owned Window will not be focused on its showing 284 // if the owner is not currently active. 285 if ("sun.awt.windows.WToolkit".equals(toolkitClassName)) { 286 Sysout.println("Stage 5.1 - Skiping."); 287 } else { 288 setVisible(ownedWindow, true); 289 setVisible(frame, false); // 'ownedWindow' will be shown along with the owner. 290 291 test("Stage 5.1 in progress...", frame, ownedWindow, ownWinButton, true); 292 } 293 294 295 // 5.2 Show Frame with owned Dialog. 296 /////////////////////////////////// 297 298 setVisible(ownedDialog, true); 299 setVisible(frame2, false); // 'ownedDialog' will be shown along with the owner. 300 301 test("Stage 5.2 in progress...", frame2, ownedDialog, ownDlgButton, true); 302 303 304 /////////////////////////////////// 305 // 6. Show unblocking modal Dialog. 306 /////////////////////////////////// 307 308 if ("sun.awt.motif.MToolkit".equals(toolkitClassName)) { 309 Sysout.println("Stage 6 - Skiping."); 310 } else { 311 Sysout.println("Stage 6 in progress..."); 312 313 // --- 314 // Testing the bug of activating invisible modal Dialog (awt_Window::SetAndActivateModalBlocker). 315 // Having some window not excluded from modality, so that it would be blocked. 316 Frame f = new Frame("Aux. Frame"); 317 f.setSize(100, 100); 318 setVisible(f, true); 319 // --- 320 321 setVisible(focusedFrame, true); 322 if (!focusOwner.hasFocus()) { 323 Util.clickOnComp(focusOwner, robot); 324 Util.waitForIdle(robot); 325 if (!focusOwner.hasFocus()) { 326 throw new Error("Test error: the frame couldn't be focused."); 327 } 328 } 329 330 dialog.setModal(true); 331 dialog.setAutoRequestFocus(false); 332 focusedFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE); 333 334 TestHelper.invokeLaterAndWait(new Runnable() { 335 public void run() { 336 dialog.setVisible(true); 337 } 338 }, robot); 339 340 if (dialog.isFocused()) { 341 throw new TestFailedException("the unblocking dialog shouldn't gain focus but it did!"); 342 } 343 setVisible(dialog, false); 344 } 345 346 Sysout.println("Test passed."); 347 } 348 349 /* 350 * @param msg notifies test stage number 351 * @param showWindow a window to show/test (if ownedWindow == null) 352 * @param ownedWindow an owned window to show/test, or null if showWindow should be tested 353 * @param clickButton a button of the window (owner or owned) expected to be on the top of stack order 354 * @param shouldFocusChange true the test window should gain focus 355 */ 356 void test(String msg, final Window showWindow, Window ownedWindow, final Button clickButton, boolean shouldFocusChange) { 357 Window testWindow = (ownedWindow == null ? showWindow : ownedWindow); 358 359 Sysout.println(msg); 360 361 if (showWindow.isVisible()) { 362 showWindow.dispose(); 363 Util.waitForIdle(robot); 364 } 365 if (!focusedFrame.isVisible()) { 366 setVisible(focusedFrame, true); 367 } 368 if (!focusOwner.hasFocus()) { 369 Util.clickOnComp(focusOwner, robot); 370 Util.waitForIdle(robot); 371 if (!focusOwner.hasFocus()) { 372 throw new Error("Test error: the frame couldn't be focused."); 373 } 374 } 375 376 ////////////////////////////////////////// 377 // Test focus change on showing the window 378 ////////////////////////////////////////// 379 380 final Runnable showAction = new Runnable() { 381 public void run() { 382 showWindow.setAutoRequestFocus(false); 383 showWindow.setVisible(true); 384 } 385 }; 386 387 final Runnable trackerAction = new Runnable() { 388 public void run() { 389 if (showWindow instanceof Dialog && ((Dialog)showWindow).isModal()) { 390 TestHelper.invokeLaterAndWait(showAction, robot); 391 } else { 392 showAction.run(); 393 } 394 } 395 }; 396 397 if (shouldFocusChange) { 398 trackerAction.run(); 399 Util.waitForIdle(robot); 400 401 if (!testWindow.isFocused()) { 402 throw new TestFailedException("the window must gain focus but it didn't!"); 403 } 404 405 } else if (TestHelper.trackFocusChangeFor(trackerAction, robot)) { 406 throw new TestFailedException("the window shouldn't gain focus but it did!"); 407 } 408 409 410 //////////////////////////////////////////// 411 // Test that the window was shown on the top. 412 // Test that it can be focused. 413 //////////////////////////////////////////// 414 415 if (!(testWindow instanceof Frame) || 416 ((Frame)testWindow).getExtendedState() != Frame.ICONIFIED) 417 { 418 boolean performed = Util.trackActionPerformed(clickButton, new Runnable() { 419 public void run() { 420 /* 421 * If 'showWindow' is not on the top then 422 * 'focusOwner' button completely overlaps 'clickButton' 423 * and we won't catch the action. 424 */ 425 Util.clickOnComp(clickButton, robot); 426 } 427 }, 1000, false); 428 429 if (!performed) { 430 // In case of loosing ACTION_PERFORMED, try once more. 431 Sysout.println("(ACTION_EVENT was not generated. One more attemp.)"); 432 performed = Util.trackActionPerformed(clickButton, new Runnable() { 433 public void run() { 434 Util.clickOnComp(clickButton, robot); 435 } 436 }, 1000, false); 437 438 if (!performed) { 439 throw new TestFailedException("the window shown is not on the top!"); 440 } 441 } 442 } 443 444 recreateGUI(); 445 } 446 447 void test(String msg, final Window showWindow, Button clickButton) { 448 test(msg, showWindow, null, clickButton, false); 449 } 450 void test(String msg, final Window showWindow, Button clickButton, boolean shouldFocusChange) { 451 test(msg, showWindow, null, clickButton, shouldFocusChange); 452 } 453 void test(String msg, final Window showWindow, Window ownedWindow, Button clickButton) { 454 test(msg, showWindow, ownedWindow, clickButton, false); 455 } 456 457 private static void setVisible(Window w, boolean b) { 458 w.setVisible(b); 459 try { 460 Util.waitForIdle(robot); 461 } catch (RuntimeException rte) { // InfiniteLoop 462 rte.printStackTrace(); 463 } 464 robot.delay(200); 465 } 466 } 467 468 class TestFailedException extends RuntimeException { 469 TestFailedException(String msg) { 470 super("Test failed: " + msg); 471 } 472 } 473 474 /**************************************************** 475 Standard Test Machinery 476 DO NOT modify anything below -- it's a standard 477 chunk of code whose purpose is to make user 478 interaction uniform, and thereby make it simpler 479 to read and understand someone else's test. 480 ****************************************************/ 481 482 /** 483 This is part of the standard test machinery. 484 It creates a dialog (with the instructions), and is the interface 485 for sending text messages to the user. 486 To print the instructions, send an array of strings to Sysout.createDialog 487 WithInstructions method. Put one line of instructions per array entry. 488 To display a message for the tester to see, simply call Sysout.println 489 with the string to be displayed. 490 This mimics System.out.println but works within the test harness as well 491 as standalone. 492 */ 493 494 class Sysout 495 { 496 static TestDialog dialog; 497 498 public static void createDialogWithInstructions( String[] instructions ) 499 { 500 dialog = new TestDialog( new Frame(), "Instructions" ); 501 dialog.printInstructions( instructions ); 502 // dialog.setVisible(true); 503 println( "Any messages for the tester will display here." ); 504 } 505 506 public static void createDialog( ) 507 { 508 dialog = new TestDialog( new Frame(), "Instructions" ); 509 String[] defInstr = { "Instructions will appear here. ", "" } ; 510 dialog.printInstructions( defInstr ); 511 // dialog.setVisible(true); 512 println( "Any messages for the tester will display here." ); 513 } 514 515 516 public static void printInstructions( String[] instructions ) 517 { 518 dialog.printInstructions( instructions ); 519 } 520 521 522 public static void println( String messageIn ) 523 { 524 dialog.displayMessage( messageIn ); 525 } 526 527 }// Sysout class 528 529 /** 530 This is part of the standard test machinery. It provides a place for the 531 test instructions to be displayed, and a place for interactive messages 532 to the user to be displayed. 533 To have the test instructions displayed, see Sysout. 534 To have a message to the user be displayed, see Sysout. 535 Do not call anything in this dialog directly. 536 */ 537 class TestDialog extends Dialog 538 { 539 540 TextArea instructionsText; 541 TextArea messageText; 542 int maxStringLength = 80; 543 544 //DO NOT call this directly, go through Sysout 545 public TestDialog( Frame frame, String name ) 546 { 547 super( frame, name ); 548 int scrollBoth = TextArea.SCROLLBARS_BOTH; 549 instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); 550 add( "North", instructionsText ); 551 552 messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); 553 add("Center", messageText); 554 555 pack(); 556 557 // setVisible(true); 558 }// TestDialog() 559 560 //DO NOT call this directly, go through Sysout 561 public void printInstructions( String[] instructions ) 562 { 563 //Clear out any current instructions 564 instructionsText.setText( "" ); 565 566 //Go down array of instruction strings 567 568 String printStr, remainingStr; 569 for( int i=0; i < instructions.length; i++ ) 570 { 571 //chop up each into pieces maxSringLength long 572 remainingStr = instructions[ i ]; 573 while( remainingStr.length() > 0 ) 574 { 575 //if longer than max then chop off first max chars to print 576 if( remainingStr.length() >= maxStringLength ) 577 { 578 //Try to chop on a word boundary 579 int posOfSpace = remainingStr. 580 lastIndexOf( ' ', maxStringLength - 1 ); 581 582 if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; 583 584 printStr = remainingStr.substring( 0, posOfSpace + 1 ); 585 remainingStr = remainingStr.substring( posOfSpace + 1 ); 586 } 587 //else just print 588 else 589 { 590 printStr = remainingStr; 591 remainingStr = ""; 592 } 593 594 instructionsText.append( printStr + "\n" ); 595 596 }// while 597 598 }// for 599 600 }//printInstructions() 601 602 //DO NOT call this directly, go through Sysout 603 public void displayMessage( String messageIn ) 604 { 605 messageText.append( messageIn + "\n" ); 606 System.out.println(messageIn); 607 } 608 609 }// TestDialog class