1 /* 2 * Copyright (c) 2007, 2018, 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 toolkitClassName = Toolkit.getDefaultToolkit().getClass().getName(); 73 } 74 75 void recreateGUI() { 76 if (focusedFrame != null) { 77 focusedFrame.dispose(); 78 frame.dispose(); 79 frame2.dispose(); 80 window.dispose(); 81 ownedWindow.dispose(); 82 ownedDialog.dispose(); 83 dialog.dispose(); 84 } 85 86 focusedFrame = new Frame("Base Frame"); 87 focusOwner = new Button("button"); 88 89 frame = new Frame("Test Frame"); 90 frameButton = new Button("button"); 91 92 frame2 = new Frame("Test Frame"); 93 frameButton2 = new Button("button"); 94 95 window = new Window(focusedFrame); 96 winButton = new Button("button"); 97 98 ownedWindow = new Window(frame) { 99 /* 100 * When 'frame' is shown along with the 'ownedWindow' 101 * (i.e. showWithParent==true) then it can appear 102 * that the 'ownedWindow' is shown too early and 103 * it can't be focused due to its owner can't be 104 * yet activated. So, to avoid this race, we pospone 105 * a little the showing of the 'ownedWindow'. 106 */ 107 public void show() { 108 robot.delay(100); 109 super.show(); 110 } 111 }; 112 ownWinButton = new Button("button"); 113 114 ownedDialog = new Dialog(frame2); 115 ownDlgButton = new Button("button"); 116 117 dialog = new Dialog(focusedFrame, "Test Dialog"); 118 dlgButton = new Button("button"); 119 120 focusedFrame.add(focusOwner); 121 focusedFrame.setBounds(100, 100, 300, 300); 122 123 frame.setBounds(140, 140, 220, 220); 124 frame.add(frameButton); 125 126 frame2.setBounds(140, 140, 220, 220); 127 frame2.add(frameButton2); 128 129 window.setBounds(140, 140, 220, 220); 130 window.add(winButton); 131 132 ownedWindow.setBounds(180, 180, 140, 140); 133 ownedWindow.add(ownWinButton); 134 135 ownedDialog.setBounds(180, 180, 140, 140); 136 ownedDialog.add(ownDlgButton); 137 138 dialog.setBounds(140, 140, 220, 220); 139 dialog.add(dlgButton); 140 } 141 142 public void start() { 143 144 /////////////////////////////////////////////////////// 145 // 1. Show Frame with owned modal Dialog without delay. 146 // Check that the Dialog takes focus. 147 /////////////////////////////////////////////////////// 148 149 recreateGUI(); 150 151 System.out.println("Stage 1 in progress..."); 152 153 dialog.setModal(true); 154 dialog.setAutoRequestFocus(false); 155 setVisible(focusedFrame, true); 156 157 TestHelper.invokeLaterAndWait(new Runnable() { 158 public void run() { 159 dialog.setVisible(true); 160 } 161 }, robot); 162 163 if (focusOwner.hasFocus()) { 164 throw new TestFailedException("the modal dialog must gain focus but it didn't!"); 165 } 166 setVisible(dialog, false); 167 168 ////////////////////////////////////////////////// 169 // 2. Show Frame, activate, auto hide, auto show. 170 // Check that the Frame takes focus. 171 ////////////////////////////////////////////////// 172 173 recreateGUI(); 174 175 System.out.println("Stage 2 in progress..."); 176 177 setVisible(focusedFrame, false); 178 179 focusedFrame.setAutoRequestFocus(false); 180 setVisible(focusedFrame, true); 181 182 Util.clickOnTitle(focusedFrame, robot); 183 Util.waitForIdle(robot); 184 185 if (!focusedFrame.isFocused()) { 186 throw new Error("Test error: the frame couldn't be focused."); 187 } 188 189 focusedFrame.setExtendedState(Frame.ICONIFIED); 190 Util.waitForIdle(robot); 191 focusedFrame.setExtendedState(Frame.NORMAL); 192 Util.waitForIdle(robot); 193 194 if (!focusedFrame.isFocused()) { 195 throw new TestFailedException("the restored frame must gain focus but it didn't!"); 196 } 197 198 199 //////////////////////// 200 // 3.1 Show Frame normal. 201 //////////////////////// 202 203 recreateGUI(); 204 205 test("Stage 3.1 in progress...", frame, frameButton); 206 207 208 // 3.2. Show Frame maximized both. 209 ///////////////////////////////// 210 211 if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) { 212 System.out.println("Stage 3.2: Frame.MAXIMIZED_BOTH not supported. Skipping."); 213 } else { 214 frame.setExtendedState(Frame.MAXIMIZED_BOTH); 215 216 test("Stage 3.2 in progress...", frame, frameButton); 217 } 218 219 220 // 3.3. Show Frame maximized vertically. 221 /////////////////////////////////////// 222 223 if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_VERT)) { 224 System.out.println("Stage 3.3: Frame.MAXIMIZED_VERT not supported. Skipping."); 225 } else { 226 frame.setExtendedState(Frame.MAXIMIZED_VERT); 227 228 test("Stage 3.3 in progress...", frame, frameButton); 229 } 230 231 232 // 3.4. Show Frame maximized horizontally. 233 ///////////////////////////////////////// 234 235 if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_HORIZ)) { 236 System.out.println("Stage 3.4: Frame.MAXIMIZED_HORIZ not supported. Skipping."); 237 } else { 238 frame.setExtendedState(Frame.MAXIMIZED_HORIZ); 239 240 test("Stage 3.4 in progress...", frame, frameButton); 241 } 242 243 244 // 3.5. Show Frame iconified. 245 //////////////////////////// 246 247 if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.ICONIFIED)) { 248 System.out.println("Stage 3.5: Frame.ICONIFIED not supported. Skipping."); 249 } else { 250 frame.setExtendedState(Frame.ICONIFIED); 251 252 test("Stage 3.5 in progress...", frame, frameButton); 253 } 254 255 256 /////////////////// 257 // 4.1 Show Window. 258 /////////////////// 259 recreateGUI(); 260 test("Stage 4.1 in progress...", window, winButton); 261 262 263 // 4.2 Show Dialog. 264 ////////////////// 265 266 test("Stage 4.2 in progress...", dialog, dlgButton); 267 268 269 // 4.3. Show modal Dialog. 270 ///////////////////////// 271 272 dialog.setModal(true); 273 test("Stage 4.3 in progress...", dialog, dlgButton, true); 274 275 276 /////////////////////////////////// 277 // 5.1 Show Frame with owned Window. 278 /////////////////////////////////// 279 280 // On Windows, an owned Window will not be focused on its showing 281 // if the owner is not currently active. 282 if ("sun.awt.windows.WToolkit".equals(toolkitClassName)) { 283 System.out.println("Stage 5.1 - Skiping."); 284 } else { 285 setVisible(ownedWindow, true); 286 setVisible(frame, false); // 'ownedWindow' will be shown along with the owner. 287 288 test("Stage 5.1 in progress...", frame, ownedWindow, ownWinButton, true); 289 } 290 291 292 // 5.2 Show Frame with owned Dialog. 293 /////////////////////////////////// 294 295 setVisible(ownedDialog, true); 296 setVisible(frame2, false); // 'ownedDialog' will be shown along with the owner. 297 298 test("Stage 5.2 in progress...", frame2, ownedDialog, ownDlgButton, true); 299 300 301 /////////////////////////////////// 302 // 6. Show unblocking modal Dialog. 303 /////////////////////////////////// 304 305 if ("sun.awt.motif.MToolkit".equals(toolkitClassName)) { 306 System.out.println("Stage 6 - Skiping."); 307 } else { 308 System.out.println("Stage 6 in progress..."); 309 310 // --- 311 // Testing the bug of activating invisible modal Dialog (awt_Window::SetAndActivateModalBlocker). 312 // Having some window not excluded from modality, so that it would be blocked. 313 Frame f = new Frame("Aux. Frame"); 314 f.setSize(100, 100); 315 setVisible(f, true); 316 // --- 317 318 setVisible(focusedFrame, true); 319 if (!focusOwner.hasFocus()) { 320 Util.clickOnComp(focusOwner, robot); 321 Util.waitForIdle(robot); 322 if (!focusOwner.hasFocus()) { 323 throw new Error("Test error: the frame couldn't be focused."); 324 } 325 } 326 327 dialog.setModal(true); 328 dialog.setAutoRequestFocus(false); 329 focusedFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE); 330 331 TestHelper.invokeLaterAndWait(new Runnable() { 332 public void run() { 333 dialog.setVisible(true); 334 } 335 }, robot); 336 337 if (dialog.isFocused()) { 338 throw new TestFailedException("the unblocking dialog shouldn't gain focus but it did!"); 339 } 340 setVisible(dialog, false); 341 } 342 343 System.out.println("Test passed."); 344 } 345 346 /* 347 * @param msg notifies test stage number 348 * @param showWindow a window to show/test (if ownedWindow == null) 349 * @param ownedWindow an owned window to show/test, or null if showWindow should be tested 350 * @param clickButton a button of the window (owner or owned) expected to be on the top of stack order 351 * @param shouldFocusChange true the test window should gain focus 352 */ 353 void test(String msg, final Window showWindow, Window ownedWindow, final Button clickButton, boolean shouldFocusChange) { 354 Window testWindow = (ownedWindow == null ? showWindow : ownedWindow); 355 356 System.out.println(msg); 357 358 if (showWindow.isVisible()) { 359 showWindow.dispose(); 360 Util.waitForIdle(robot); 361 } 362 if (!focusedFrame.isVisible()) { 363 setVisible(focusedFrame, true); 364 } 365 if (!focusOwner.hasFocus()) { 366 Util.clickOnComp(focusOwner, robot); 367 Util.waitForIdle(robot); 368 if (!focusOwner.hasFocus()) { 369 throw new Error("Test error: the frame couldn't be focused."); 370 } 371 } 372 373 ////////////////////////////////////////// 374 // Test focus change on showing the window 375 ////////////////////////////////////////// 376 377 final Runnable showAction = new Runnable() { 378 public void run() { 379 showWindow.setAutoRequestFocus(false); 380 showWindow.setVisible(true); 381 } 382 }; 383 384 final Runnable trackerAction = new Runnable() { 385 public void run() { 386 if (showWindow instanceof Dialog && ((Dialog)showWindow).isModal()) { 387 TestHelper.invokeLaterAndWait(showAction, robot); 388 } else { 389 showAction.run(); 390 } 391 } 392 }; 393 394 if (shouldFocusChange) { 395 trackerAction.run(); 396 Util.waitForIdle(robot); 397 398 if (!testWindow.isFocused()) { 399 throw new TestFailedException("the window must gain focus but it didn't!"); 400 } 401 402 } else if (TestHelper.trackFocusChangeFor(trackerAction, robot)) { 403 throw new TestFailedException("the window shouldn't gain focus but it did!"); 404 } 405 406 407 //////////////////////////////////////////// 408 // Test that the window was shown on the top. 409 // Test that it can be focused. 410 //////////////////////////////////////////// 411 412 if (!(testWindow instanceof Frame) || 413 ((Frame)testWindow).getExtendedState() != Frame.ICONIFIED) 414 { 415 boolean performed = Util.trackActionPerformed(clickButton, new Runnable() { 416 public void run() { 417 /* 418 * If 'showWindow' is not on the top then 419 * 'focusOwner' button completely overlaps 'clickButton' 420 * and we won't catch the action. 421 */ 422 Util.clickOnComp(clickButton, robot); 423 } 424 }, 1000, false); 425 426 if (!performed) { 427 // In case of loosing ACTION_PERFORMED, try once more. 428 System.out.println("(ACTION_EVENT was not generated. One more attemp.)"); 429 performed = Util.trackActionPerformed(clickButton, new Runnable() { 430 public void run() { 431 Util.clickOnComp(clickButton, robot); 432 } 433 }, 1000, false); 434 435 if (!performed) { 436 throw new TestFailedException("the window shown is not on the top!"); 437 } 438 } 439 } 440 441 recreateGUI(); 442 } 443 444 void test(String msg, final Window showWindow, Button clickButton) { 445 test(msg, showWindow, null, clickButton, false); 446 } 447 void test(String msg, final Window showWindow, Button clickButton, boolean shouldFocusChange) { 448 test(msg, showWindow, null, clickButton, shouldFocusChange); 449 } 450 void test(String msg, final Window showWindow, Window ownedWindow, Button clickButton) { 451 test(msg, showWindow, ownedWindow, clickButton, false); 452 } 453 454 private static void setVisible(Window w, boolean b) { 455 w.setVisible(b); 456 try { 457 Util.waitForIdle(robot); 458 } catch (RuntimeException rte) { // InfiniteLoop 459 rte.printStackTrace(); 460 } 461 robot.delay(200); 462 } 463 } 464 465 class TestFailedException extends RuntimeException { 466 TestFailedException(String msg) { 467 super("Test failed: " + msg); 468 } 469 }