1 /* 2 * Copyright (c) 2003, 2019, 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 4632143 28 @summary Unit test for the RFE window/frame/dialog always on top 29 @author dom@sparc.spb.su: area=awt.toplevel 30 @run main/othervm/timeout=600 AutoTestOnTop 31 */ 32 33 import java.awt.AWTEvent; 34 import java.awt.AWTException; 35 import java.awt.Component; 36 import java.awt.Dialog; 37 import java.awt.EventQueue; 38 import java.awt.Frame; 39 import java.awt.IllegalComponentStateException; 40 import java.awt.Point; 41 import java.awt.Robot; 42 import java.awt.Toolkit; 43 import java.awt.Window; 44 import java.awt.event.AWTEventListener; 45 import java.awt.event.FocusEvent; 46 import java.awt.event.InputEvent; 47 import java.awt.event.MouseEvent; 48 import java.awt.event.PaintEvent; 49 import java.awt.event.WindowAdapter; 50 import java.awt.event.WindowEvent; 51 import java.lang.reflect.InvocationTargetException; 52 import java.lang.reflect.Method; 53 import java.util.Vector; 54 55 import javax.swing.JDialog; 56 import javax.swing.JFrame; 57 import javax.swing.JWindow; 58 59 /** 60 * @author tav@sparc.spb.su 61 * @author dom@sparc.spb.su 62 * Tests that always-on-top windows combine correctly with different kinds of window in different styles and conditions. 63 * 64 * !!! WARNING !!! 65 * The test fails sometimes because the toFront() method doesn't guarantee 66 * that after its invocation the frame will be placed above all other windows. 67 */ 68 public class AutoTestOnTop { 69 private static final int X = 300; 70 private static final int Y = 300; 71 72 static Window topw; 73 static Frame parentw = new Frame(); 74 static Window f; 75 static Frame parentf = new Frame(); 76 77 static final Object uncheckedSrc = new Object(); // used when no need to check event source 78 static volatile Object eventSrc = uncheckedSrc; 79 static boolean dispatchedCond; 80 81 static Semaphore STATE_SEMA = new Semaphore(); 82 static Semaphore VIS_SEMA = new Semaphore(); 83 static Vector errors = new Vector(); 84 85 static boolean isUnix = false; 86 87 static StringBuffer msgError = new StringBuffer(); 88 static StringBuffer msgCase = new StringBuffer(); 89 static StringBuffer msgAction = new StringBuffer(); 90 static StringBuffer msgFunc = new StringBuffer(); 91 static StringBuffer msgVisibility = new StringBuffer(); 92 93 static volatile int stageNum; 94 static volatile int actNum; 95 static volatile int testResult = 0; 96 97 static volatile boolean doCheckEvents; 98 static volatile boolean eventsCheckPassed; 99 static boolean[] eventsCheckInitVals = new boolean[] { // Whether events are checked for abcence or precence 100 true, true, true, true, true, false, false, false, false 101 }; 102 static String[] msgEventsChecks = new String[] { 103 null, null, null, null, null, 104 "expected WindowEvent.WINDOW_STATE_CHANGED hasn't been generated", 105 "expected WindowEvent.WINDOW_STATE_CHANGED hasn't been generated", 106 "expected WindowEvent.WINDOW_STATE_CHANGED hasn't been generated", 107 "expected WindowEvent.WINDOW_STATE_CHANGED hasn't been generated", 108 }; 109 110 static final int stagesCount = 7; 111 static final int actionsCount = 9; 112 113 static Method[] preActions = new Method[actionsCount]; 114 static Method[] postActions = new Method[actionsCount]; 115 static Method[] isActionsAllowed = new Method[actionsCount]; 116 static Method[] checksActionEvents = new Method[actionsCount]; 117 118 static Robot robot; 119 120 static boolean doStartTest; 121 static String osName = System.getProperty("os.name"); 122 123 124 public static void main(String[] args) { 125 checkTesting(); 126 127 } 128 129 public static void performTesting() { 130 isUnix = osName.equals("Linux") || osName.equals("SunOS"); 131 132 Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { 133 public void eventDispatched(AWTEvent e) { 134 if (e.getID() == MouseEvent.MOUSE_CLICKED) { 135 if (eventSrc != null & eventSrc != uncheckedSrc && e.getSource() != eventSrc) { 136 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + msgAction + ": " + msgError); 137 testResult = -1; 138 } 139 if (eventSrc != null){ 140 synchronized (eventSrc) { 141 dispatchedCond = true; 142 eventSrc.notify(); 143 } 144 } 145 } 146 147 if (doCheckEvents && (e.getSource() == topw || e.getSource() == f)) { 148 149 //System.err.println("AWTEventListener: catched the event " + e); 150 151 try { 152 checksActionEvents[actNum].invoke(null, new Object[] {e}); 153 } catch (InvocationTargetException ite) { 154 ite.printStackTrace(); 155 } catch (IllegalAccessException iae) { 156 iae.printStackTrace(); 157 } 158 return; 159 } 160 } 161 }, 0xffffffffffffffffL); 162 163 Method[] allMethods; 164 165 try { 166 allMethods = AutoTestOnTop.class.getDeclaredMethods(); 167 } catch (SecurityException se) { 168 throw new RuntimeException(se); 169 } 170 171 for (int i = 0; i < allMethods.length; i++) { 172 String name = allMethods[i].getName(); 173 if (name.startsWith("preAction")) { 174 preActions[name.charAt(name.length() - 1) - '0'] = allMethods[i]; 175 } else if (name.startsWith("postAction")) { 176 postActions[name.charAt(name.length() - 1) - '0'] = allMethods[i]; 177 } else if (name.startsWith("isActionAllowed")) { 178 isActionsAllowed[name.charAt(name.length() - 1) - '0'] = allMethods[i]; 179 } else if (name.startsWith("checkActionEvents")) { 180 checksActionEvents[name.charAt(name.length() - 1) - '0'] = allMethods[i]; 181 } 182 } 183 184 f = new Frame("Auxiliary Frame"); 185 f.setBounds(X, Y, 650, 100); 186 f.setVisible(true); 187 waitTillShown(f); 188 189 try { 190 robot = new Robot(); 191 robot.setAutoDelay(100); 192 } catch (AWTException e) { 193 throw new RuntimeException("Error: unable to create robot", e); 194 } 195 196 mainTest(); 197 198 if (testResult != 0) { 199 System.err.println("The following errors were encountered: "); 200 for (int i = 0; i < errors.size(); i++) { 201 System.err.println(errors.get(i).toString()); 202 } 203 throw new RuntimeException("Test failed."); 204 } else { 205 System.err.println("Test PASSED."); 206 } 207 } 208 209 public static void mainTest() { 210 // stageNum = 0; 211 // for (int i = 0; i < 5; i++) { 212 // actNum = 2; 213 // System.err.println("************************* A C T I O N " + actNum + " *************************"); 214 // doStage(stageNum, actNum); 215 // // pause(500); 216 // actNum = 3; 217 // System.err.println("************************* A C T I O N " + actNum + " *************************"); 218 // doStage(stageNum, actNum); 219 // // pause(500); 220 // } 221 for (stageNum = 0; stageNum < stagesCount; stageNum++) { 222 System.err.println("************************* S T A G E " + stageNum + " *************************"); 223 for (actNum = 0; actNum < actionsCount; actNum++) { 224 System.err.println("************************* A C T I O N " + actNum + " *************************"); 225 doStage(stageNum, actNum); 226 } // for thru actNum 227 } // fow thru stageNum 228 229 eventSrc = null; 230 } 231 232 private static void doStage(int stageNum, int actNum) { 233 try { 234 235 if (!((Boolean)isActionsAllowed[actNum].invoke(null, new Object[0])).booleanValue()) { 236 System.err.println("Action skipped due to a platform limitations"); 237 return; 238 } 239 240 STATE_SEMA.reset(); 241 createWindow(stageNum); 242 243 //************************* 244 // Set window always-on-top 245 //************************* 246 247 preActions[actNum].invoke(null, new Object[0]); 248 setAlwaysOnTop(topw, true); 249 waitForIdle(true); 250 251 if (!topw.isAlwaysOnTopSupported()) return; 252 253 postActions[actNum].invoke(null, new Object[0]); 254 waitForIdle(false); 255 256 STATE_SEMA.reset(); 257 258 testForAlwaysOnTop(); 259 260 //***************************** 261 // Set window not always-on-top 262 //***************************** 263 264 preActions[actNum].invoke(null, new Object[0]); 265 setAlwaysOnTop(topw, false); 266 waitForIdle(true); 267 postActions[actNum].invoke(null, new Object[0]); 268 waitForIdle(false); 269 STATE_SEMA.reset(); 270 271 testForNotAlwaysOnTop(); 272 273 } catch (InvocationTargetException ite) { 274 ite.printStackTrace(); 275 } catch (Exception ex) { 276 throw new RuntimeException(ex); 277 } 278 } 279 280 private static void checkTesting() { 281 if (Toolkit.getDefaultToolkit().isAlwaysOnTopSupported()) { 282 performTesting(); 283 } 284 } 285 286 public static void testForAlwaysOnTop() { 287 System.err.println("Checking for always-on-top " + topw); 288 289 ensureInitialWinPosition(topw); 290 291 // Check that always-on-top window is topmost. 292 // - Click on always-on-top window on the windows cross area. 293 clickOn(topw, f, 10, 50, "setting " + msgVisibility + 294 " window (1) always-on-top didn't make it topmost"); 295 296 // Check that we can't change z-order of always-on-top window. 297 // - a) Try to put the other window on the top. 298 f.toFront(); 299 clickOn(uncheckedSrc, f, 450, 50, ""); // coz toFront() works not always 300 pause(300); 301 302 // - b) Click on always-on-top window on the windows cross area. 303 clickOn(topw, f, 10, 50, "setting " + msgVisibility + 304 " window (1) always-on-top didn't make it such"); 305 306 // Ask for always-on-top property 307 if (isAlwaysOnTop(topw) != true) 308 error("Test failed: stage #" + stageNum + ", action #" + actNum + ": " + msgCase + ": " + msgAction + 309 ": isAlwaysOnTop() returned 'false' for window (1) set always-on-top at state " 310 + msgVisibility); 311 } 312 313 public static void testForNotAlwaysOnTop() { 314 System.err.println("Checking for non always-on-top of " + topw); 315 ensureInitialWinPosition(topw); 316 317 if (msgVisibility.equals("visible") && actNum != 2) { 318 // Check that the window remains topmost. 319 // - click on the window on the windows cross area. 320 clickOn(topw, f, 10, 50, "setting " + msgVisibility + 321 " window (1) not always-on-top didn't keep it topmost"); 322 } 323 324 // Check that we can change z-order of not always-on-top window. 325 // - a) try to put the other window on the top. 326 f.toFront(); 327 clickOn(uncheckedSrc, f, 450, 50, ""); // coz toFront() works not always 328 pause(300); 329 330 // - b) click on not always-on-top window on the windows cross area. 331 clickOn(f, f, 10, 50, "setting " + msgVisibility + 332 " window (1) not always-on-top didn't make it such"); 333 334 // Ask for always-on-top property 335 if (isAlwaysOnTop(topw) != false) 336 error("Test failed: stage #" + stageNum + ", action #" + actNum + ": " + msgCase + ": " + msgAction + 337 ": isAlwaysOnTop() returned 'true' for window (1) set not always-on-top at state " 338 + msgVisibility); 339 } 340 341 342 private static void createWindow(int stageNum) { 343 // Free native resourses 344 if (topw != null) { 345 topw.dispose(); 346 } 347 348 switch (stageNum) { 349 case 0: 350 topw = new Frame("Top Frame"); 351 msgCase.replace(0, msgCase.length(), "Frame (1) over Frame (2)"); 352 break; 353 case 1: 354 topw = new JFrame("Top JFrame"); 355 msgCase.replace(0, msgCase.length(), "JFrame (1) over Frame (2)"); 356 break; 357 case 2: 358 topw = new Dialog(parentw, "Top Dialog"); 359 msgCase.replace(0, msgCase.length(), "Dialog (1) over Frame (2)"); 360 break; 361 case 3: 362 topw = new JDialog(parentw, "Top JDialog"); 363 msgCase.replace(0, msgCase.length(), "JDialog (1) over Frame (2)"); 364 break; 365 case 4: 366 topw = new Frame("Top Frame"); 367 f.dispose(); 368 f = new Dialog(parentf, "Auxiliary Dialog"); 369 f.setBounds(X, Y, 650, 100); 370 f.setVisible(true); 371 waitTillShown(f); 372 msgCase.replace(0, msgCase.length(), "Frame (1) over Dialog (2)"); 373 break; 374 case 5: 375 topw = new Window(parentw); 376 msgCase.replace(0, msgCase.length(), "Window (1) over Frame (2)"); 377 break; 378 case 6: 379 topw = new JWindow(parentw); 380 msgCase.replace(0, msgCase.length(), "JWindow (1) over Frame (2)"); 381 break; 382 } 383 topw.addWindowStateListener(new WindowAdapter() { 384 public void windowStateChanged(WindowEvent e) { 385 System.err.println("* " + e); 386 STATE_SEMA.raise(); 387 } 388 }); 389 topw.setSize(300, 100); 390 } 391 392 /** 393 * 0: setting always-on-top to invisible window 394 * 1: setting always-on-top to visible window 395 * 2: always-on-top on visible non-focusable window 396 * 3: always-on-top on visible, dragging topw after that 397 * 4: always-on-top on visible, dragging f after that 398 * 5: always-on-top on (visible, maximized), make normal after that 399 * 6: always-on-top on (visible, iconified), make normal after that 400 * 7: always-on-top on visible, iconify/deiconify after that 401 * 8: always-on-top on visible, maximize/restore after that 402 */ 403 public static void preAction_0() { 404 topw.setVisible(false); 405 } 406 public static void postAction_0() { 407 if (topw.isShowing()) { 408 error("Test failed: stage #" + stageNum + ", action #" + actNum + ": " + msgCase + 409 ": no actions with windows: changing always-on-top property at window (1) state 'invisible' makes window (1) visible"); 410 } 411 setWindowVisible("no actions with windows", "invisible"); 412 } 413 public static boolean isActionAllowed_0() { 414 // Window on Linux is always always-on-top! 415 return !((stageNum == 5 || stageNum == 6) && isUnix) && (stageNum < stagesCount); 416 } 417 public static void checkActionEvents_0(AWTEvent e) { 418 System.err.println(e.toString()); 419 } 420 421 public static void preAction_1() { 422 setWindowVisible("no actions with windows", "visible"); 423 } 424 public static void postAction_1() {} 425 public static boolean isActionAllowed_1() { 426 return !((stageNum == 5 || stageNum == 6) && isUnix) && (stageNum < stagesCount ); 427 } 428 public static void checkActionEvents_1(AWTEvent e) { 429 System.err.println(e.toString()); 430 if (e instanceof PaintEvent) { 431 return; 432 } 433 eventsCheckPassed = false; 434 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + msgAction + ": after call " + msgFunc + 435 ": unexpected event " + e + " was generated"); 436 } 437 438 public static void preAction_2() { 439 setWindowVisible("when window (1) set not focusable", "visible"); 440 topw.setFocusableWindowState(false); 441 f.toFront(); 442 pause(300); 443 } 444 public static void postAction_2() {} 445 public static boolean isActionAllowed_2() { 446 return !((stageNum == 5 || stageNum == 6) && isUnix) && (stageNum < stagesCount); 447 } 448 public static void checkActionEvents_2(AWTEvent e) { 449 System.err.println(e.toString()); 450 if ( (e.getID() >= FocusEvent.FOCUS_FIRST && e.getID() <= FocusEvent.FOCUS_LAST) || 451 (e.getID() == WindowEvent.WINDOW_LOST_FOCUS && e.getID() == WindowEvent.WINDOW_GAINED_FOCUS)) { 452 eventsCheckPassed = false; 453 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + 454 msgAction + ": after call " + msgFunc + 455 ": unexpected event " + e + " was generated"); 456 } 457 } 458 459 public static void preAction_3() { 460 setWindowVisible("after dragging", "visible"); 461 } 462 public static void postAction_3() { 463 Point p = topw.getLocationOnScreen(); 464 int x = p.x + 150, y = p.y + 5; 465 466 try { // Take a pause to avoid double click 467 Thread.sleep(500); // when called one after another. 468 } catch (InterruptedException ie) { 469 ie.printStackTrace(); 470 } catch (IllegalComponentStateException e) { 471 e.printStackTrace(); 472 } 473 474 // Drag the window. 475 robot.mouseMove(x, y); 476 robot.mousePress(InputEvent.BUTTON1_MASK); 477 robot.mouseMove(X + 150, Y + 100); 478 robot.mouseMove(x, y); 479 robot.mouseRelease(InputEvent.BUTTON1_MASK); 480 } 481 public static boolean isActionAllowed_3() { 482 return (stageNum < 5); 483 } 484 public static void checkActionEvents_3(AWTEvent e) { 485 System.err.println(e.toString()); 486 } 487 488 public static void preAction_4() { 489 setWindowVisible("after dragging window (2)", "visible"); 490 } 491 public static void postAction_4() { 492 Point p = f.getLocationOnScreen(); 493 int x = p.x + 400, y = p.y + 5; 494 495 try { // Take a pause to avoid double click 496 Thread.sleep(500); // when called one after another. 497 } catch (InterruptedException ie) { 498 ie.printStackTrace(); 499 } catch (IllegalComponentStateException e) { 500 e.printStackTrace(); 501 } 502 503 // Drag the window. 504 robot.mouseMove(x, y); 505 robot.mousePress(InputEvent.BUTTON1_MASK); 506 robot.mouseMove(X + 400, Y + 100); 507 robot.mouseMove(x, y); 508 robot.mouseRelease(InputEvent.BUTTON1_MASK); 509 510 ensureInitialWinPosition(f); 511 } 512 public static boolean isActionAllowed_4() { 513 return !((stageNum == 5 || stageNum == 6) && isUnix); 514 } 515 public static void checkActionEvents_4(AWTEvent e) { 516 System.err.println(e.toString()); 517 } 518 519 // Metacity has a bug not allowing to set a window to NORMAL state!!! 520 521 public static void preAction_5() { 522 setWindowVisible("at state 'maximized'", "visible"); 523 ((Frame)topw).setExtendedState(Frame.MAXIMIZED_BOTH); 524 waitForStateChange(); 525 } 526 public static void postAction_5() { 527 ((Frame)topw).setExtendedState(Frame.NORMAL); 528 waitForStateChange(); 529 } 530 public static boolean isActionAllowed_5() { 531 return (stageNum < 2); 532 } 533 public static void checkActionEvents_5(AWTEvent e) { 534 System.err.println("=" + e.toString()); 535 if (e.getID() == WindowEvent.WINDOW_STATE_CHANGED) { 536 eventsCheckPassed = true; 537 } 538 } 539 540 public static void preAction_6() { 541 setWindowVisible("at state 'iconified'", "visible"); 542 System.err.println("Iconifying " + topw); 543 ((Frame)topw).setExtendedState(Frame.ICONIFIED); 544 if (!waitForStateChange()) { 545 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + msgAction + ": after call " + msgFunc + 546 ": state change to ICONIFIED hasn't been generated"); 547 } 548 } 549 public static void postAction_6() { 550 System.err.println("Restoring " + topw); 551 ((Frame)topw).setExtendedState(Frame.NORMAL); 552 if (!waitForStateChange()) { 553 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + msgAction + ": after call " + msgFunc + 554 ": state change to NORMAL hasn't been generated"); 555 } 556 } 557 public static boolean isActionAllowed_6() { 558 return (stageNum < 2 ); 559 } 560 public static void checkActionEvents_6(AWTEvent e) { 561 System.err.println("+" + e.toString()); 562 if (e.getID() == WindowEvent.WINDOW_STATE_CHANGED) { 563 eventsCheckPassed = true; 564 } 565 } 566 567 public static void preAction_7() { 568 setWindowVisible("before state 'iconified'", "visible"); 569 } 570 public static void postAction_7() { 571 System.err.println("Setting iconified"); 572 ((Frame)topw).setExtendedState(Frame.ICONIFIED); 573 if (!waitForStateChange()) { 574 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + msgAction + ": after call " + msgFunc + 575 ": state change to ICONIFIED hasn't been generated"); 576 } 577 System.err.println("Setting normal"); 578 ((Frame)topw).setExtendedState(Frame.NORMAL); 579 if (!waitForStateChange()) { 580 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + msgAction + ": after call " + msgFunc + 581 ": state change to NORMAL hasn't been generated"); 582 } 583 } 584 public static boolean isActionAllowed_7() { 585 return (stageNum < 2); 586 } 587 public static void checkActionEvents_7(AWTEvent e) { 588 System.err.println(e.toString()); 589 if (e.getID() == WindowEvent.WINDOW_STATE_CHANGED) { 590 eventsCheckPassed = true; 591 } 592 } 593 594 public static void preAction_8() { 595 setWindowVisible("before state 'maximized'", "visible"); 596 } 597 public static void postAction_8() { 598 ((Frame)topw).setExtendedState(Frame.MAXIMIZED_BOTH); 599 if (!waitForStateChange()) { 600 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + msgAction + ": after call " + msgFunc + 601 ": state change to MAXIMIZED hasn't been generated"); 602 } 603 ((Frame)topw).setExtendedState(Frame.NORMAL); 604 if (!waitForStateChange()) { 605 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + msgAction + ": after call " + msgFunc + 606 ": state change to NORMAL hasn't been generated"); 607 } 608 } 609 public static boolean isActionAllowed_8() { 610 return (stageNum < 2); 611 } 612 public static void checkActionEvents_8(AWTEvent e) { 613 System.err.println(e.toString()); 614 if (e.getID() == WindowEvent.WINDOW_STATE_CHANGED) { 615 eventsCheckPassed = true; 616 } 617 } 618 619 //*************************************************************************** 620 621 private static void setWindowVisible(String mAction, String mVisibility) { 622 msgAction.replace(0, msgAction.length(), mAction); 623 msgVisibility.replace(0, msgVisibility.length(), mVisibility); 624 625 topw.setVisible(true); 626 pause(100); // Needs for Sawfish 627 topw.setLocation(X, Y); 628 waitTillShown(topw); 629 f.toFront(); 630 pause(300); 631 } 632 633 private static void clickOn(Object src, Window relwin, int x, int y, String errorStr) { 634 Point p = relwin.getLocationOnScreen(); 635 int counter = 10; 636 while (--counter > 0) { 637 eventSrc = src; 638 msgError.replace(0, msgError.length(), errorStr); 639 640 robot.mouseMove(p.x + x, p.y + y); 641 robot.mousePress(InputEvent.BUTTON1_MASK); 642 robot.mouseRelease(InputEvent.BUTTON1_MASK); 643 644 synchronized (eventSrc) { 645 if (!dispatchedCond) { 646 try { 647 eventSrc.wait(1000); 648 } catch (InterruptedException e) { 649 e.printStackTrace(); 650 } 651 } 652 if (!dispatchedCond) { 653 //System.err.println("clickOn: MOUSE_CLICKED event losed, trying to generate it again..."); 654 continue; 655 } 656 dispatchedCond = false; 657 } 658 break; 659 } // end while 660 if (counter <= 0) { 661 eventSrc = uncheckedSrc; 662 error("Test: internal error: could't catch MOUSE_CLICKED event. Skip testing this stage"); 663 } 664 } 665 666 private static void setAlwaysOnTop(Window w, boolean value) { 667 System.err.println("Setting always on top on " + w + " to " + value); 668 robot.mouseMove(X - 50, Y - 50); // Move out of the window 669 msgFunc.replace(0, msgCase.length(), "setAlwaysOnTop()"); 670 try { 671 w.setAlwaysOnTop(value); 672 } catch (Exception e) { 673 error("Test failed: stage#" + stageNum + "action #" + actNum + ": " + msgCase + ": " + msgAction + 674 ": setAlwaysOnTop(" + value + ") called at state " + msgVisibility + 675 " threw exeption " + e); 676 } 677 } 678 679 private static boolean isAlwaysOnTop(Window w) { 680 robot.mouseMove(X - 50, Y - 50); // Move out of the window 681 msgFunc.replace(0, msgCase.length(), "isAlwaysOnTop()"); 682 boolean result = false; 683 try { 684 result = w.isAlwaysOnTop(); 685 } catch (Exception e) { 686 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + msgAction + 687 ": isAlwaysOnTop() called at state " + msgVisibility + 688 " threw exeption " + e); 689 } 690 return result; 691 } 692 693 private static void waitTillShown(Component c) { 694 while (true) { 695 try { 696 Thread.sleep(100); 697 c.getLocationOnScreen(); 698 break; 699 } catch (InterruptedException e) { 700 e.printStackTrace(); 701 break; 702 } 703 } 704 } 705 706 private static void waitForIdle(boolean doCheck) { 707 try { 708 robot.waitForIdle(); 709 EventQueue.invokeAndWait( new Runnable() { 710 public void run() {} // Dummy implementation 711 } ); 712 } catch(InterruptedException ite) { 713 System.err.println("waitForIdle, non-fatal exception caught:"); 714 ite.printStackTrace(); 715 } catch(InvocationTargetException ine) { 716 System.err.println("waitForIdle, non-fatal exception caught:"); 717 ine.printStackTrace(); 718 } 719 doCheckEvents = doCheck; 720 721 if (doCheck) { 722 eventsCheckPassed = eventsCheckInitVals[actNum]; // Initialize 723 } else if (!eventsCheckPassed && 724 msgEventsChecks[actNum] != null) { 725 726 727 // Some expected event hasn't been catched, 728 // so give it one more chance... 729 doCheckEvents = true; 730 pause(500); 731 doCheckEvents = false; 732 733 if (!eventsCheckPassed) { 734 testResult = -1; 735 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + msgAction + ": after call " 736 + msgFunc + ": " + msgEventsChecks[actNum]); 737 } 738 } 739 } 740 741 private static boolean waitForStateChange() { 742 System.err.println("------- Waiting for state change"); 743 try { 744 STATE_SEMA.doWait(3000); 745 } catch (InterruptedException ie) { 746 System.err.println("Wait interrupted: " + ie); 747 } 748 boolean state = STATE_SEMA.getState(); 749 STATE_SEMA.reset(); 750 robot.delay(1000); // animation normal <--> maximized states 751 return state; 752 } 753 754 private static void ensureInitialWinPosition(Window w) { 755 int counter = 30; 756 while (w.getLocationOnScreen().y != Y && --counter > 0) { 757 try { 758 Thread.sleep(100); 759 } catch (InterruptedException e) { 760 e.printStackTrace(); 761 break; 762 } 763 } 764 if (counter <= 0) { 765 w.setLocation(X, Y); 766 pause(100); 767 System.err.println("Test: window set to initial position forcedly"); 768 } 769 } 770 771 private static void pause(int mls) { 772 try { 773 Thread.sleep(mls); 774 } catch (InterruptedException e) { 775 e.printStackTrace(); 776 } 777 } 778 779 private static void error(String msg) { 780 errors.add(msg); 781 System.err.println(msg); 782 } 783 } 784 785 class Semaphore { 786 boolean state = false; 787 int waiting = 0; 788 public Semaphore() { 789 } 790 public synchronized void doWait() throws InterruptedException { 791 if (state) { 792 return; 793 } 794 waiting++; 795 wait(); 796 waiting--; 797 } 798 public synchronized void doWait(int timeout) throws InterruptedException { 799 if (state) { 800 return; 801 } 802 waiting++; 803 wait(timeout); 804 waiting--; 805 } 806 public synchronized void raise() { 807 state = true; 808 if (waiting > 0) { 809 notifyAll(); 810 } 811 } 812 813 public synchronized void doNotify() { 814 notifyAll(); 815 } 816 public synchronized boolean getState() { 817 return state; 818 } 819 820 public synchronized void reset() { 821 state = false; 822 } 823 }