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 @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 @modules java.desktop/sun.awt
31 @run main AutoTestOnTop
32 */
33
34 import java.awt.*;
35 import java.awt.event.*;
36 import java.lang.reflect.*;
37 import javax.swing.*;
38 import java.util.Vector;
39
40 /**
41 * @author tav@sparc.spb.su
42 * @author dom@sparc.spb.su
43 * Tests that always-on-top windows combine correctly with different kinds of window in different styles and conditions.
44 *
45 * !!! WARNING !!!
46 * The test fails sometimes because the toFront() method doesn't guarantee
47 * that after its invocation the frame will be placed above all other windows.
48 */
49 public class AutoTestOnTop {
50 static Window topw;
51 static Frame parentw = new Frame();
52 static Window f;
53 static Frame parentf = new Frame();
54
55 static Object uncheckedSrc = new Object(); // used when no need to check event source
56 static Object eventSrc = uncheckedSrc;
57 static boolean dispatchedCond;
58
59 static Semaphore STATE_SEMA = new Semaphore();
60 static Semaphore VIS_SEMA = new Semaphore();
61 static Vector errors = new Vector();
62
63 static boolean isUnix = false;
64
65 static StringBuffer msgError = new StringBuffer();
66 static StringBuffer msgCase = new StringBuffer();
67 static StringBuffer msgAction = new StringBuffer();
68 static StringBuffer msgFunc = new StringBuffer();
69 static StringBuffer msgVisibility = new StringBuffer();
70
71 static volatile int stageNum;
72 static volatile int actNum;
73 static volatile int testResult = 0;
74
75 static volatile boolean doCheckEvents;
76 static volatile boolean eventsCheckPassed;
97
98 static boolean doStartTest;
99 static String osName = System.getProperty("os.name");
100
101
102 public static void main(String[] args) {
103 checkTesting();
104
105 }
106
107 public static void performTesting() {
108 isUnix = osName.equals("Linux") || osName.equals("SunOS");
109
110 Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
111 public void eventDispatched(AWTEvent e) {
112 if (e.getID() == MouseEvent.MOUSE_CLICKED) {
113 if (eventSrc != null & eventSrc != uncheckedSrc && e.getSource() != eventSrc) {
114 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + msgAction + ": " + msgError);
115 testResult = -1;
116 }
117 synchronized (eventSrc) {
118 dispatchedCond = true;
119 eventSrc.notify();
120 }
121 }
122
123 if (doCheckEvents && (e.getSource() == topw || e.getSource() == f)) {
124
125 //System.err.println("AWTEventListener: catched the event " + e);
126
127 try {
128 checksActionEvents[actNum].invoke(null, new Object[] {e});
129 } catch (InvocationTargetException ite) {
130 ite.printStackTrace();
131 } catch (IllegalAccessException iae) {
132 iae.printStackTrace();
133 }
134 return;
135 }
136 }
137 }, 0xffffffffffffffffL);
138
139 Method[] allMethods;
140
141 try {
142 allMethods = AutoTestOnTop.class.getDeclaredMethods();
143 } catch (SecurityException se) {
144 throw new RuntimeException(se);
145 }
146
147 for (int i = 0; i < allMethods.length; i++) {
148 String name = allMethods[i].getName();
149 if (name.startsWith("preAction")) {
150 preActions[name.charAt(name.length() - 1) - '0'] = allMethods[i];
151 } else if (name.startsWith("postAction")) {
152 postActions[name.charAt(name.length() - 1) - '0'] = allMethods[i];
153 } else if (name.startsWith("isActionAllowed")) {
154 isActionsAllowed[name.charAt(name.length() - 1) - '0'] = allMethods[i];
155 } else if (name.startsWith("checkActionEvents")) {
156 checksActionEvents[name.charAt(name.length() - 1) - '0'] = allMethods[i];
157 }
158 }
159
160 f = new Frame("Auxiliary Frame");
161 f.setBounds(50, 0, 400, 50);
162 f.setVisible(true);
163 waitTillShown(f);
164
165 try {
166 robot = new Robot();
167 } catch (AWTException e) {
168 throw new RuntimeException("Error: unable to create robot", e);
169 }
170
171 mainTest();
172
173 if (testResult != 0) {
174 System.err.println("The following errors were encountered: ");
175 for (int i = 0; i < errors.size(); i++) {
176 System.err.println(errors.get(i).toString());
177 }
178 throw new RuntimeException("Test failed.");
179 } else {
180 System.err.println("Test PASSED.");
181 }
182 }
183
184 public static void mainTest() {
185 // stageNum = 0;
186 // for (int i = 0; i < 5; i++) {
248 } catch (InvocationTargetException ite) {
249 ite.printStackTrace();
250 } catch (Exception ex) {
251 throw new RuntimeException(ex);
252 }
253 }
254
255 private static void checkTesting() {
256 if (Toolkit.getDefaultToolkit().isAlwaysOnTopSupported()) {
257 performTesting();
258 }
259 }
260
261 public static void testForAlwaysOnTop() {
262 System.err.println("Checking for always-on-top " + topw);
263
264 ensureInitialWinPosition(topw);
265
266 // Check that always-on-top window is topmost.
267 // - Click on always-on-top window on the windows cross area.
268 clickOn(topw, f, 10, 30, "setting " + msgVisibility +
269 " window (1) always-on-top didn't make it topmost");
270
271 // Check that we can't change z-order of always-on-top window.
272 // - a) Try to put the other window on the top.
273 f.toFront();
274 clickOn(uncheckedSrc, f, 190, 30, ""); // coz toFront() works not always
275 pause(300);
276
277 // - b) Click on always-on-top window on the windows cross area.
278 clickOn(topw, f, 10, 30, "setting " + msgVisibility +
279 " window (1) always-on-top didn't make it such");
280
281 // Ask for always-on-top property
282 if (isAlwaysOnTop(topw) != true)
283 error("Test failed: stage #" + stageNum + ", action #" + actNum + ": " + msgCase + ": " + msgAction +
284 ": isAlwaysOnTop() returned 'false' for window (1) set always-on-top at state "
285 + msgVisibility);
286 }
287
288 public static void testForNotAlwaysOnTop() {
289 System.err.println("Checking for non always-on-top of " + topw);
290 ensureInitialWinPosition(topw);
291
292 if (msgVisibility.equals("visible") && actNum != 2) {
293 // Check that the window remains topmost.
294 // - click on the window on the windows cross area.
295 clickOn(topw, f, 10, 30, "setting " + msgVisibility +
296 " window (1) not always-on-top didn't keep it topmost");
297 }
298
299 // Check that we can change z-order of not always-on-top window.
300 // - a) try to put the other window on the top.
301 f.toFront();
302 clickOn(uncheckedSrc, f, 190, 30, ""); // coz toFront() works not always
303 pause(300);
304
305 // - b) click on not always-on-top window on the windows cross area.
306 clickOn(f, f, 10, 30, "setting " + msgVisibility +
307 " window (1) not always-on-top didn't make it such");
308
309 // Ask for always-on-top property
310 if (isAlwaysOnTop(topw) != false)
311 error("Test failed: stage #" + stageNum + ", action #" + actNum + ": " + msgCase + ": " + msgAction +
312 ": isAlwaysOnTop() returned 'true' for window (1) set not always-on-top at state "
313 + msgVisibility);
314 }
315
316
317 private static void createWindow(int stageNum) {
318 // Free native resourses
319 if (topw != null && topw.isVisible()) {
320 topw.dispose();
321 }
322
323 switch (stageNum) {
324 case 0:
325 topw = new Frame("Top Frame");
326 msgCase.replace(0, msgCase.length(), "Frame (1) over Frame (2)");
327 break;
328 case 1:
329 topw = new JFrame("Top JFrame");
330 msgCase.replace(0, msgCase.length(), "JFrame (1) over Frame (2)");
331 break;
332 case 2:
333 topw = new Dialog(parentw, "Top Dialog");
334 msgCase.replace(0, msgCase.length(), "Dialog (1) over Frame (2)");
335 break;
336 case 3:
337 topw = new JDialog(parentw, "Top JDialog");
338 msgCase.replace(0, msgCase.length(), "JDialog (1) over Frame (2)");
339 break;
340 case 4:
341 topw = new Frame("Top Frame");
342 f.dispose();
343 f = new Dialog(parentf, "Auxiliary Dialog");
344 f.setBounds(50, 0, 250, 50);
345 f.setVisible(true);
346 waitTillShown(f);
347 msgCase.replace(0, msgCase.length(), "Frame (1) over Dialog (2)");
348 break;
349 case 5:
350 topw = new Window(parentw);
351 msgCase.replace(0, msgCase.length(), "Window (1) over Frame (2)");
352 break;
353 case 6:
354 topw = new JWindow(parentw);
355 msgCase.replace(0, msgCase.length(), "JWindow (1) over Frame (2)");
356 break;
357 }
358 topw.addWindowStateListener(new WindowAdapter() {
359 public void windowStateChanged(WindowEvent e) {
360 System.err.println("* " + e);
361 STATE_SEMA.raise();
362 }
363 });
364 topw.setSize(200, 50);
365 }
366
367 /**
368 * 0: setting always-on-top to invisible window
369 * 1: setting always-on-top to visible window
370 * 2: always-on-top on visible non-focusable window
371 * 3: always-on-top on visible, dragging topw after that
372 * 4: always-on-top on visible, dragging f after that
373 * 5: always-on-top on (visible, maximized), make normal after that
374 * 6: always-on-top on (visible, iconified), make normal after that
375 * 7: always-on-top on visible, iconify/deiconify after that
376 * 8: always-on-top on visible, maximize/restore after that
377 */
378 public static void preAction_0() {
379 topw.setVisible(false);
380 }
381 public static void postAction_0() {
382 if (topw.isShowing()) {
383 error("Test failed: stage #" + stageNum + ", action #" + actNum + ": " + msgCase +
384 ": no actions with windows: changing always-on-top property at window (1) state 'invisible' makes window (1) visible");
419 public static void postAction_2() {}
420 public static boolean isActionAllowed_2() {
421 return !((stageNum == 5 || stageNum == 6) && isUnix) && (stageNum < stagesCount);
422 }
423 public static void checkActionEvents_2(AWTEvent e) {
424 System.err.println(e.toString());
425 if ( (e.getID() >= FocusEvent.FOCUS_FIRST && e.getID() <= FocusEvent.FOCUS_LAST) ||
426 (e.getID() == WindowEvent.WINDOW_LOST_FOCUS && e.getID() == WindowEvent.WINDOW_GAINED_FOCUS)) {
427 eventsCheckPassed = false;
428 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " +
429 msgAction + ": after call " + msgFunc +
430 ": unexpected event " + e + " was generated");
431 }
432 }
433
434 public static void preAction_3() {
435 setWindowVisible("after dragging", "visible");
436 }
437 public static void postAction_3() {
438 Point p = topw.getLocationOnScreen();
439 int x = p.x + 40, y = p.y + 5;
440
441 try { // Take a pause to avoid double click
442 Thread.sleep(500); // when called one after another.
443 } catch (InterruptedException ie) {
444 ie.printStackTrace();
445 } catch (IllegalComponentStateException e) {
446 e.printStackTrace();
447 }
448
449 // Drag the window.
450 robot.mouseMove(x, y);
451 robot.mousePress(InputEvent.BUTTON1_MASK);
452 robot.mouseMove(200, 50);
453 robot.mouseMove(x, y);
454 robot.mouseRelease(InputEvent.BUTTON1_MASK);
455 }
456 public static boolean isActionAllowed_3() {
457 return (stageNum < 5);
458 }
459 public static void checkActionEvents_3(AWTEvent e) {
460 System.err.println(e.toString());
461 }
462
463 public static void preAction_4() {
464 setWindowVisible("after dragging window (2)", "visible");
465 }
466 public static void postAction_4() {
467 Point p = f.getLocationOnScreen();
468 int x = p.x + 150, y = p.y + 5;
469
470 try { // Take a pause to avoid double click
471 Thread.sleep(500); // when called one after another.
472 } catch (InterruptedException ie) {
473 ie.printStackTrace();
474 } catch (IllegalComponentStateException e) {
475 e.printStackTrace();
476 }
477
478 // Drag the window.
479 robot.mouseMove(x, y);
480 robot.mousePress(InputEvent.BUTTON1_MASK);
481 robot.mouseMove(200, 50);
482 robot.mouseMove(x, y);
483 robot.mouseRelease(InputEvent.BUTTON1_MASK);
484
485 ensureInitialWinPosition(f);
486 }
487 public static boolean isActionAllowed_4() {
488 return !((stageNum == 5 || stageNum == 6) && isUnix);
489 }
490 public static void checkActionEvents_4(AWTEvent e) {
491 System.err.println(e.toString());
492 }
493
494 // Metacity has a bug not allowing to set a window to NORMAL state!!!
495
496 public static void preAction_5() {
497 setWindowVisible("at state 'maximized'", "visible");
498 ((Frame)topw).setExtendedState(Frame.MAXIMIZED_BOTH);
499 waitForStateChange();
500 }
501 public static void postAction_5() {
582 }
583 }
584 public static boolean isActionAllowed_8() {
585 return (stageNum < 2);
586 }
587 public static void checkActionEvents_8(AWTEvent e) {
588 System.err.println(e.toString());
589 if (e.getID() == WindowEvent.WINDOW_STATE_CHANGED) {
590 eventsCheckPassed = true;
591 }
592 }
593
594 //***************************************************************************
595
596 private static void setWindowVisible(String mAction, String mVisibility) {
597 msgAction.replace(0, msgAction.length(), mAction);
598 msgVisibility.replace(0, msgVisibility.length(), mVisibility);
599
600 topw.setVisible(true);
601 pause(100); // Needs for Sawfish
602 topw.setLocation(0, 0);
603 waitTillShown(topw);
604 f.toFront();
605 pause(300);
606 }
607
608 private static void clickOn(Object src, Window relwin, int x, int y, String errorStr) {
609 Point p = relwin.getLocationOnScreen();
610 int counter = 10;
611 while (--counter > 0) {
612 eventSrc = src;
613 msgError.replace(0, msgError.length(), errorStr);
614
615 robot.mouseMove(p.x + x, p.y + y);
616 robot.mousePress(InputEvent.BUTTON1_MASK);
617 robot.mouseRelease(InputEvent.BUTTON1_MASK);
618
619 synchronized (eventSrc) {
620 if (!dispatchedCond) {
621 try {
622 eventSrc.wait(1000);
623 } catch (InterruptedException e) {
624 e.printStackTrace();
625 }
626 }
627 if (!dispatchedCond) {
628 //System.err.println("clickOn: MOUSE_CLICKED event losed, trying to generate it again...");
629 continue;
630 }
631 dispatchedCond = false;
632 }
633 break;
634 } // end while
635 if (counter <= 0) {
636 eventSrc = uncheckedSrc;
637 error("Test: internal error: could't catch MOUSE_CLICKED event. Skip testing this stage");
638 }
639 }
640
641 private static void setAlwaysOnTop(Window w, boolean value) {
642 System.err.println("Setting always on top on " + w + " to " + value);
643 robot.mouseMove(0, 100); // Move out of the window
644 msgFunc.replace(0, msgCase.length(), "setAlwaysOnTop()");
645 try {
646 w.setAlwaysOnTop(value);
647 } catch (Exception e) {
648 error("Test failed: stage#" + stageNum + "action #" + actNum + ": " + msgCase + ": " + msgAction +
649 ": setAlwaysOnTop(" + value + ") called at state " + msgVisibility +
650 " threw exeption " + e);
651 }
652 }
653
654 private static boolean isAlwaysOnTop(Window w) {
655 robot.mouseMove(0, 100); // Move out of the window
656 msgFunc.replace(0, msgCase.length(), "isAlwaysOnTop()");
657 boolean result = false;
658 try {
659 result = w.isAlwaysOnTop();
660 } catch (Exception e) {
661 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + msgAction +
662 ": isAlwaysOnTop() called at state " + msgVisibility +
663 " threw exeption " + e);
664 }
665 return result;
666 }
667
668 private static void waitTillShown(Component c) {
669 while (true) {
670 try {
671 Thread.sleep(100);
672 c.getLocationOnScreen();
673 break;
674 } catch (InterruptedException e) {
675 e.printStackTrace();
705 pause(500);
706 doCheckEvents = false;
707
708 if (!eventsCheckPassed) {
709 testResult = -1;
710 error("Test failed: stage #" + stageNum + ", action # " + actNum + ": " + msgCase + ": " + msgAction + ": after call "
711 + msgFunc + ": " + msgEventsChecks[actNum]);
712 }
713 }
714 }
715
716 private static boolean waitForStateChange() {
717 System.err.println("------- Waiting for state change");
718 try {
719 STATE_SEMA.doWait(3000);
720 } catch (InterruptedException ie) {
721 System.err.println("Wait interrupted: " + ie);
722 }
723 boolean state = STATE_SEMA.getState();
724 STATE_SEMA.reset();
725 return state;
726 }
727
728 private static void ensureInitialWinPosition(Window w) {
729 int counter = 30;
730 while (w.getLocationOnScreen().y != 0 && --counter > 0) {
731 try {
732 Thread.sleep(100);
733 } catch (InterruptedException e) {
734 e.printStackTrace();
735 break;
736 }
737 }
738 if (counter <= 0) {
739 w.setLocation(0, 0);
740 pause(100);
741 System.err.println("Test: window set to initial position forcedly");
742 }
743 }
744
745 private static void pause(int mls) {
746 try {
747 Thread.sleep(mls);
748 } catch (InterruptedException e) {
749 e.printStackTrace();
750 }
751 }
752
753 private static void error(String msg) {
754 errors.add(msg);
755 System.err.println(msg);
756 }
757 }
758
759 class Semaphore {
|
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;
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++) {
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");
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() {
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();
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 {
|