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