blob: f20a490d637b3a8a55e7acede2f1d7e27c2e6f9d [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/*
25 @test
26 @bug 6187066
27 @summary Tests the Window.autoRequestFocus property for the Window.setVisible() method.
28 @author anton.tarasov: area=awt.focus
29 @library ../../regtesthelpers
30 @build Util
31 @run main AutoRequestFocusSetVisibleTest
32*/
33
34import java.awt.*;
35import java.awt.event.*;
36import java.applet.Applet;
37import java.util.concurrent.atomic.AtomicBoolean;
38import java.lang.reflect.InvocationTargetException;
39import test.java.awt.regtesthelpers.Util;
40
41public class AutoRequestFocusSetVisibleTest extends Applet {
42 static Frame focusedFrame;
43 static Button focusOwner;
44 static Frame frame;
45 static Button frameButton;
46 static Frame frame2;
47 static Button frameButton2;
48 static Window window;
49 static Button winButton;
50 static Window ownedWindow;
51 static Button ownWinButton;
52 static Dialog ownedDialog;
53 static Button ownDlgButton;
54 static Dialog dialog;
55 static Button dlgButton;
56
57 static String toolkitClassName;
58 static Robot robot = Util.createRobot();
59
60 public static void main(String[] args) {
61 AutoRequestFocusSetVisibleTest app = new AutoRequestFocusSetVisibleTest();
62 app.init();
63 app.start();
64 }
65
66 public void init() {
67 // Create instructions for the user here, as well as set up
68 // the environment -- set the layout manager, add buttons,
69 // etc.
70 this.setLayout (new BorderLayout ());
71 Sysout.createDialogWithInstructions(new String[]
72 {"This is an automatic test. Simply wait until it is done."
73 });
74 toolkitClassName = Toolkit.getDefaultToolkit().getClass().getName();
75 }
76
77 void recreateGUI() {
78 if (focusedFrame != null) {
79 focusedFrame.dispose();
80 frame.dispose();
81 frame2.dispose();
82 window.dispose();
83 ownedWindow.dispose();
84 ownedDialog.dispose();
85 dialog.dispose();
86 }
87
88 focusedFrame = new Frame("Base Frame");
89 focusOwner = new Button("button");
90
91 frame = new Frame("Test Frame");
92 frameButton = new Button("button");
93
94 frame2 = new Frame("Test Frame");
95 frameButton2 = new Button("button");
96
97 window = new Window(focusedFrame);
98 winButton = new Button("button");
99
100 ownedWindow = new Window(frame) {
101 /*
102 * When 'frame' is shown along with the 'ownedWindow'
103 * (i.e. showWithParent==true) then it can appear
104 * that the 'ownedWindow' is shown too early and
105 * it can't be focused due to its owner can't be
106 * yet activated. So, to avoid this race, we pospone
107 * a little the showing of the 'ownedWindow'.
108 */
109 public void show() {
110 robot.delay(100);
111 super.show();
112 }
113 };
114 ownWinButton = new Button("button");
115
116 ownedDialog = new Dialog(frame2);
117 ownDlgButton = new Button("button");
118
119 dialog = new Dialog(focusedFrame, "Test Dialog");
120 dlgButton = new Button("button");
121
122 focusedFrame.add(focusOwner);
123 focusedFrame.setBounds(100, 100, 300, 300);
124
125 frame.setBounds(140, 140, 220, 220);
126 frame.add(frameButton);
127
128 frame2.setBounds(140, 140, 220, 220);
129 frame2.add(frameButton2);
130
131 window.setBounds(140, 140, 220, 220);
132 window.add(winButton);
133
134 ownedWindow.setBounds(180, 180, 140, 140);
135 ownedWindow.add(ownWinButton);
136
137 ownedDialog.setBounds(180, 180, 140, 140);
138 ownedDialog.add(ownDlgButton);
139
140 dialog.setBounds(140, 140, 220, 220);
141 dialog.add(dlgButton);
142 }
143
144 public void start() {
145
146 ///////////////////////////////////////////////////////
147 // 1. Show Frame with owned modal Dialog without delay.
148 // Check that the Dialog takes focus.
149 ///////////////////////////////////////////////////////
150
151 recreateGUI();
152
153 Sysout.println("Stage 1 in progress...");
154
155 dialog.setModal(true);
156 dialog.setAutoRequestFocus(false);
157 setVisible(focusedFrame, true);
158
159 TestHelper.invokeLaterAndWait(new Runnable() {
160 public void run() {
161 dialog.setVisible(true);
162 }
163 }, robot);
164
165 if (focusOwner.hasFocus()) {
166 throw new TestFailedException("the modal dialog must gain focus but it didn't!");
167 }
168 setVisible(dialog, false);
169
170 //////////////////////////////////////////////////
171 // 2. Show Frame, activate, auto hide, auto show.
172 // Check that the Frame takes focus.
173 //////////////////////////////////////////////////
174
175 recreateGUI();
176
177 Sysout.println("Stage 2 in progress...");
178
179 setVisible(focusedFrame, false);
180
181 focusedFrame.setAutoRequestFocus(false);
182 setVisible(focusedFrame, true);
183
184 Util.clickOnTitle(focusedFrame, robot);
185 Util.waitForIdle(robot);
186
187 if (!focusedFrame.isFocused()) {
188 throw new Error("Test error: the frame couldn't be focused.");
189 }
190
191 focusedFrame.setExtendedState(Frame.ICONIFIED);
192 Util.waitForIdle(robot);
193 focusedFrame.setExtendedState(Frame.NORMAL);
194 Util.waitForIdle(robot);
195
196 if (!focusedFrame.isFocused()) {
197 throw new TestFailedException("the restored frame must gain focus but it didn't!");
198 }
199
200
201 ////////////////////////
202 // 3.1 Show Frame normal.
203 ////////////////////////
204
205 recreateGUI();
206
207 test("Stage 3.1 in progress...", frame, frameButton);
208
209
210 // 3.2. Show Frame maximized both.
211 /////////////////////////////////
212
213 if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) {
214 System.out.println("Stage 3.2: Frame.MAXIMIZED_BOTH not supported. Skipping.");
215 } else {
216 frame.setExtendedState(Frame.MAXIMIZED_BOTH);
217
218 test("Stage 3.2 in progress...", frame, frameButton);
219 }
220
221
222 // 3.3. Show Frame maximized vertically.
223 ///////////////////////////////////////
224
225 if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_VERT)) {
226 System.out.println("Stage 3.3: Frame.MAXIMIZED_VERT not supported. Skipping.");
227 } else {
228 frame.setExtendedState(Frame.MAXIMIZED_VERT);
229
230 test("Stage 3.3 in progress...", frame, frameButton);
231 }
232
233
234 // 3.4. Show Frame maximized horizontally.
235 /////////////////////////////////////////
236
237 if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_HORIZ)) {
238 System.out.println("Stage 3.4: Frame.MAXIMIZED_HORIZ not supported. Skipping.");
239 } else {
240 frame.setExtendedState(Frame.MAXIMIZED_HORIZ);
241
242 test("Stage 3.4 in progress...", frame, frameButton);
243 }
244
245
246 // 3.5. Show Frame iconified.
247 ////////////////////////////
248
249 if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.ICONIFIED)) {
250 System.out.println("Stage 3.5: Frame.ICONIFIED not supported. Skipping.");
251 } else {
252 frame.setExtendedState(Frame.ICONIFIED);
253
254 test("Stage 3.5 in progress...", frame, frameButton);
255 }
256
257
258 ///////////////////
259 // 4.1 Show Window.
260 ///////////////////
261 recreateGUI();
262 test("Stage 4.1 in progress...", window, winButton);
263
264
265 // 4.2 Show Dialog.
266 //////////////////
267
268 test("Stage 4.2 in progress...", dialog, dlgButton);
269
270
271 // 4.3. Show modal Dialog.
272 /////////////////////////
273
274 dialog.setModal(true);
275 test("Stage 4.3 in progress...", dialog, dlgButton, true);
276
277
278 ///////////////////////////////////
279 // 5.1 Show Frame with owned Window.
280 ///////////////////////////////////
281
282 // On Windows, an owned Window will not be focused on its showing
283 // if the owner is not currently active.
284 if ("sun.awt.windows.WToolkit".equals(toolkitClassName)) {
285 Sysout.println("Stage 5.1 - Skiping.");
286 } else {
287 setVisible(ownedWindow, true);
288 setVisible(frame, false); // 'ownedWindow' will be shown along with the owner.
289
290 test("Stage 5.1 in progress...", frame, ownedWindow, ownWinButton, true);
291 }
292
293
294 // 5.2 Show Frame with owned Dialog.
295 ///////////////////////////////////
296
297 setVisible(ownedDialog, true);
298 setVisible(frame2, false); // 'ownedDialog' will be shown along with the owner.
299
300 test("Stage 5.2 in progress...", frame2, ownedDialog, ownDlgButton, true);
301
302
303 ///////////////////////////////////
304 // 6. Show unblocking modal Dialog.
305 ///////////////////////////////////
306
307 if ("sun.awt.motif.MToolkit".equals(toolkitClassName)) {
308 Sysout.println("Stage 6 - Skiping.");
309 } else {
310 Sysout.println("Stage 6 in progress...");
311
312 // ---
313 // Testing the bug of activating invisible modal Dialog (awt_Window::SetAndActivateModalBlocker).
314 // Having some window not excluded from modality, so that it would be blocked.
315 Frame f = new Frame("Aux. Frame");
316 f.setSize(100, 100);
317 setVisible(f, true);
318 // ---
319
320 setVisible(focusedFrame, true);
321 if (!focusOwner.hasFocus()) {
322 Util.clickOnComp(focusOwner, robot);
323 Util.waitForIdle(robot);
324 if (!focusOwner.hasFocus()) {
325 throw new Error("Test error: the frame couldn't be focused.");
326 }
327 }
328
329 dialog.setModal(true);
330 dialog.setAutoRequestFocus(false);
331 focusedFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
332
333 TestHelper.invokeLaterAndWait(new Runnable() {
334 public void run() {
335 dialog.setVisible(true);
336 }
337 }, robot);
338
339 if (dialog.isFocused()) {
340 throw new TestFailedException("the unblocking dialog shouldn't gain focus but it did!");
341 }
342 setVisible(dialog, false);
343 }
344
345 Sysout.println("Test passed.");
346 }
347
348 /*
349 * @param msg notifies test stage number
350 * @param showWindow a window to show/test (if ownedWindow == null)
351 * @param ownedWindow an owned window to show/test, or null if showWindow should be tested
352 * @param clickButton a button of the window (owner or owned) expected to be on the top of stack order
353 * @param shouldFocusChange true the test window should gain focus
354 */
355 void test(String msg, final Window showWindow, Window ownedWindow, final Button clickButton, boolean shouldFocusChange) {
356 Window testWindow = (ownedWindow == null ? showWindow : ownedWindow);
357
358 Sysout.println(msg);
359
360 if (showWindow.isVisible()) {
361 showWindow.dispose();
362 Util.waitForIdle(robot);
363 }
364 if (!focusedFrame.isVisible()) {
365 setVisible(focusedFrame, true);
366 }
367 if (!focusOwner.hasFocus()) {
368 Util.clickOnComp(focusOwner, robot);
369 Util.waitForIdle(robot);
370 if (!focusOwner.hasFocus()) {
371 throw new Error("Test error: the frame couldn't be focused.");
372 }
373 }
374
375 //////////////////////////////////////////
376 // Test focus change on showing the window
377 //////////////////////////////////////////
378
379 final Runnable showAction = new Runnable() {
380 public void run() {
381 showWindow.setAutoRequestFocus(false);
382 showWindow.setVisible(true);
383 }
384 };
385
386 final Runnable trackerAction = new Runnable() {
387 public void run() {
388 if (showWindow instanceof Dialog && ((Dialog)showWindow).isModal()) {
389 TestHelper.invokeLaterAndWait(showAction, robot);
390 } else {
391 showAction.run();
392 }
393 }
394 };
395
396 if (shouldFocusChange) {
397 trackerAction.run();
398 Util.waitForIdle(robot);
399
400 if (!testWindow.isFocused()) {
401 throw new TestFailedException("the window must gain focus but it didn't!");
402 }
403
404 } else if (TestHelper.trackFocusChangeFor(trackerAction, robot)) {
405 throw new TestFailedException("the window shouldn't gain focus but it did!");
406 }
407
408
409 ////////////////////////////////////////////
410 // Test that the window was shown on the top.
411 // Test that it can be focused.
412 ////////////////////////////////////////////
413
414 if (!(testWindow instanceof Frame) ||
415 ((Frame)testWindow).getExtendedState() != Frame.ICONIFIED)
416 {
417 boolean performed = Util.trackActionPerformed(clickButton, new Runnable() {
418 public void run() {
419 /*
420 * If 'showWindow' is not on the top then
421 * 'focusOwner' button completely overlaps 'clickButton'
422 * and we won't catch the action.
423 */
424 Util.clickOnComp(clickButton, robot);
425 }
426 }, 1000, false);
427
428 if (!performed) {
429 // In case of loosing ACTION_PERFORMED, try once more.
430 Sysout.println("(ACTION_EVENT was not generated. One more attemp.)");
431 performed = Util.trackActionPerformed(clickButton, new Runnable() {
432 public void run() {
433 Util.clickOnComp(clickButton, robot);
434 }
435 }, 1000, false);
436
437 if (!performed) {
438 throw new TestFailedException("the window shown is not on the top!");
439 }
440 }
441 }
442
443 recreateGUI();
444 }
445
446 void test(String msg, final Window showWindow, Button clickButton) {
447 test(msg, showWindow, null, clickButton, false);
448 }
449 void test(String msg, final Window showWindow, Button clickButton, boolean shouldFocusChange) {
450 test(msg, showWindow, null, clickButton, shouldFocusChange);
451 }
452 void test(String msg, final Window showWindow, Window ownedWindow, Button clickButton) {
453 test(msg, showWindow, ownedWindow, clickButton, false);
454 }
455
456 private static void setVisible(Window w, boolean b) {
457 w.setVisible(b);
458 try {
459 Util.waitForIdle(robot);
460 } catch (RuntimeException rte) { // InfiniteLoop
461 rte.printStackTrace();
462 }
463 robot.delay(200);
464 }
465}
466
467class TestFailedException extends RuntimeException {
468 TestFailedException(String msg) {
469 super("Test failed: " + msg);
470 }
471}
472
473/****************************************************
474 Standard Test Machinery
475 DO NOT modify anything below -- it's a standard
476 chunk of code whose purpose is to make user
477 interaction uniform, and thereby make it simpler
478 to read and understand someone else's test.
479 ****************************************************/
480
481/**
482 This is part of the standard test machinery.
483 It creates a dialog (with the instructions), and is the interface
484 for sending text messages to the user.
485 To print the instructions, send an array of strings to Sysout.createDialog
486 WithInstructions method. Put one line of instructions per array entry.
487 To display a message for the tester to see, simply call Sysout.println
488 with the string to be displayed.
489 This mimics System.out.println but works within the test harness as well
490 as standalone.
491 */
492
493class Sysout
494{
495 static TestDialog dialog;
496
497 public static void createDialogWithInstructions( String[] instructions )
498 {
499 dialog = new TestDialog( new Frame(), "Instructions" );
500 dialog.printInstructions( instructions );
501// dialog.setVisible(true);
502 println( "Any messages for the tester will display here." );
503 }
504
505 public static void createDialog( )
506 {
507 dialog = new TestDialog( new Frame(), "Instructions" );
508 String[] defInstr = { "Instructions will appear here. ", "" } ;
509 dialog.printInstructions( defInstr );
510// dialog.setVisible(true);
511 println( "Any messages for the tester will display here." );
512 }
513
514
515 public static void printInstructions( String[] instructions )
516 {
517 dialog.printInstructions( instructions );
518 }
519
520
521 public static void println( String messageIn )
522 {
523 dialog.displayMessage( messageIn );
524 }
525
526}// Sysout class
527
528/**
529 This is part of the standard test machinery. It provides a place for the
530 test instructions to be displayed, and a place for interactive messages
531 to the user to be displayed.
532 To have the test instructions displayed, see Sysout.
533 To have a message to the user be displayed, see Sysout.
534 Do not call anything in this dialog directly.
535 */
536class TestDialog extends Dialog
537{
538
539 TextArea instructionsText;
540 TextArea messageText;
541 int maxStringLength = 80;
542
543 //DO NOT call this directly, go through Sysout
544 public TestDialog( Frame frame, String name )
545 {
546 super( frame, name );
547 int scrollBoth = TextArea.SCROLLBARS_BOTH;
548 instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
549 add( "North", instructionsText );
550
551 messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
552 add("Center", messageText);
553
554 pack();
555
556// setVisible(true);
557 }// TestDialog()
558
559 //DO NOT call this directly, go through Sysout
560 public void printInstructions( String[] instructions )
561 {
562 //Clear out any current instructions
563 instructionsText.setText( "" );
564
565 //Go down array of instruction strings
566
567 String printStr, remainingStr;
568 for( int i=0; i < instructions.length; i++ )
569 {
570 //chop up each into pieces maxSringLength long
571 remainingStr = instructions[ i ];
572 while( remainingStr.length() > 0 )
573 {
574 //if longer than max then chop off first max chars to print
575 if( remainingStr.length() >= maxStringLength )
576 {
577 //Try to chop on a word boundary
578 int posOfSpace = remainingStr.
579 lastIndexOf( ' ', maxStringLength - 1 );
580
581 if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
582
583 printStr = remainingStr.substring( 0, posOfSpace + 1 );
584 remainingStr = remainingStr.substring( posOfSpace + 1 );
585 }
586 //else just print
587 else
588 {
589 printStr = remainingStr;
590 remainingStr = "";
591 }
592
593 instructionsText.append( printStr + "\n" );
594
595 }// while
596
597 }// for
598
599 }//printInstructions()
600
601 //DO NOT call this directly, go through Sysout
602 public void displayMessage( String messageIn )
603 {
604 messageText.append( messageIn + "\n" );
605 System.out.println(messageIn);
606 }
607
608}// TestDialog class