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