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