1 /* 2 * Copyright (c) 2005, 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 6253913 27 @summary Tests that a Window shown before its owner is focusable. 28 @author anton.tarasov@sun.com: area=awt-focus 29 @run applet WindowUpdateFocusabilityTest.html 30 */ 31 32 import java.awt.*; 33 import java.awt.event.*; 34 import java.applet.Applet; 35 import java.lang.reflect.*; 36 37 public class WindowUpdateFocusabilityTest extends Applet { 38 Robot robot; 39 boolean focusGained = false; 40 final Object monitor = new Object(); 41 FocusListener listener = new FocusAdapter () { 42 public void focusGained(FocusEvent e) { 43 Sysout.println(e.toString()); 44 synchronized (monitor) { 45 focusGained = true; 46 monitor.notifyAll(); 47 } 48 } 49 }; 50 51 public static void main(String[] args) { 52 WindowUpdateFocusabilityTest app = new WindowUpdateFocusabilityTest(); 53 app.init(); 54 app.start(); 55 } 56 57 public void init() { 58 try { 59 robot = new Robot(); 60 } catch (AWTException e) { 61 throw new RuntimeException("Error: couldn't create robot"); 62 } 63 // Create instructions for the user here, as well as set up 64 // the environment -- set the layout manager, add buttons, 65 // etc. 66 this.setLayout (new BorderLayout ()); 67 Sysout.createDialogWithInstructions(new String[] 68 {"This is an automatic test. Simply wait until it's done."}); 69 } 70 71 public void start() { 72 if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) { 73 Sysout.println("No testing on Motif."); 74 return; 75 } 76 77 test(new Frame("Frame owner")); 78 Frame dialog_owner = new Frame("dialog's owner"); 79 test(new Dialog(dialog_owner)); 80 test(new Dialog(dialog_owner, Dialog.ModalityType.DOCUMENT_MODAL)); 81 test(new Dialog(dialog_owner, Dialog.ModalityType.APPLICATION_MODAL)); 82 test(new Dialog(dialog_owner, Dialog.ModalityType.TOOLKIT_MODAL)); 83 test(new Dialog((Window) null, Dialog.ModalityType.MODELESS)); 84 test(new Dialog((Window) null, Dialog.ModalityType.DOCUMENT_MODAL)); 85 test(new Dialog((Window) null, Dialog.ModalityType.APPLICATION_MODAL)); 86 test(new Dialog((Window) null, Dialog.ModalityType.TOOLKIT_MODAL)); 87 dialog_owner.dispose(); 88 } 89 90 private void test(final Window owner) 91 { 92 Window window0 = new Window(owner); // will not be shown 93 Window window1 = new Window(window0); 94 Window window2 = new Window(window1); 95 Button button1 = new Button("button1"); 96 Button button2 = new Button("button2"); 97 button1.addFocusListener(listener); 98 button2.addFocusListener(listener); 99 100 owner.setBounds(800, 0, 100, 100); 101 window1.setBounds(800, 300, 100, 100); 102 window2.setBounds(800, 150, 100, 100); 103 104 window1.add(button1); 105 window2.add(button2); 106 107 window2.setVisible(true); 108 window1.setVisible(true); 109 EventQueue.invokeLater(new Runnable() { 110 public void run() { 111 owner.setVisible(true); 112 } 113 }); 114 115 try { 116 EventQueue.invokeAndWait(new Runnable() { 117 public void run() { 118 // do nothing just wait until previous invokeLater will be executed 119 } 120 }); 121 } catch (InterruptedException ie) { 122 throw new RuntimeException(ie); 123 } catch (InvocationTargetException ite) { 124 throw new RuntimeException(ite); 125 } 126 127 robot.delay(1000); 128 129 clickOn(button1); 130 131 if (!isFocusGained()) { 132 throw new RuntimeException("Test failed: window1 is not focusable!"); 133 } 134 135 focusGained = false; 136 clickOn(button2); 137 138 if (!isFocusGained()) { 139 throw new RuntimeException("Test failed: window2 is not focusable!"); 140 } 141 142 Sysout.println("Test for " + owner.getName() + " passed."); 143 owner.dispose(); 144 } 145 146 void clickOn(Component c) { 147 Point p = c.getLocationOnScreen(); 148 Dimension d = c.getSize(); 149 150 Sysout.println("Clicking " + c); 151 152 robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + (int)(d.getHeight()/2)); 153 154 robot.mousePress(InputEvent.BUTTON1_MASK); 155 robot.mouseRelease(InputEvent.BUTTON1_MASK); 156 waitForIdle(); 157 } 158 159 void waitForIdle() { 160 try { 161 robot.waitForIdle(); 162 robot.delay(50); 163 EventQueue.invokeAndWait( new Runnable() { 164 public void run() {} // Dummy implementation 165 }); 166 } catch(InterruptedException ie) { 167 Sysout.println("waitForIdle, non-fatal exception caught:"); 168 ie.printStackTrace(); 169 } catch(InvocationTargetException ite) { 170 Sysout.println("waitForIdle, non-fatal exception caught:"); 171 ite.printStackTrace(); 172 } 173 } 174 175 boolean isFocusGained() { 176 synchronized (monitor) { 177 if (!focusGained) { 178 try { 179 monitor.wait(3000); 180 } catch (InterruptedException e) { 181 Sysout.println("Interrupted unexpectedly!"); 182 throw new RuntimeException(e); 183 } 184 } 185 } 186 return focusGained; 187 } 188 } 189 190 /**************************************************** 191 Standard Test Machinery 192 DO NOT modify anything below -- it's a standard 193 chunk of code whose purpose is to make user 194 interaction uniform, and thereby make it simpler 195 to read and understand someone else's test. 196 ****************************************************/ 197 198 /** 199 This is part of the standard test machinery. 200 It creates a dialog (with the instructions), and is the interface 201 for sending text messages to the user. 202 To print the instructions, send an array of strings to Sysout.createDialog 203 WithInstructions method. Put one line of instructions per array entry. 204 To display a message for the tester to see, simply call Sysout.println 205 with the string to be displayed. 206 This mimics System.out.println but works within the test harness as well 207 as standalone. 208 */ 209 210 class Sysout 211 { 212 static TestDialog dialog; 213 214 public static void createDialogWithInstructions( String[] instructions ) 215 { 216 dialog = new TestDialog( new Frame(), "Instructions" ); 217 dialog.printInstructions( instructions ); 218 dialog.setVisible(true); 219 println( "Any messages for the tester will display here." ); 220 } 221 222 public static void createDialog( ) 223 { 224 dialog = new TestDialog( new Frame(), "Instructions" ); 225 String[] defInstr = { "Instructions will appear here. ", "" } ; 226 dialog.printInstructions( defInstr ); 227 dialog.setVisible(true); 228 println( "Any messages for the tester will display here." ); 229 } 230 231 232 public static void printInstructions( String[] instructions ) 233 { 234 dialog.printInstructions( instructions ); 235 } 236 237 238 public static void println( String messageIn ) 239 { 240 dialog.displayMessage( messageIn ); 241 } 242 243 }// Sysout class 244 245 /** 246 This is part of the standard test machinery. It provides a place for the 247 test instructions to be displayed, and a place for interactive messages 248 to the user to be displayed. 249 To have the test instructions displayed, see Sysout. 250 To have a message to the user be displayed, see Sysout. 251 Do not call anything in this dialog directly. 252 */ 253 class TestDialog extends Dialog 254 { 255 256 TextArea instructionsText; 257 TextArea messageText; 258 int maxStringLength = 80; 259 260 //DO NOT call this directly, go through Sysout 261 public TestDialog( Frame frame, String name ) 262 { 263 super( frame, name ); 264 int scrollBoth = TextArea.SCROLLBARS_BOTH; 265 instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); 266 add( "North", instructionsText ); 267 268 messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); 269 add("Center", messageText); 270 271 pack(); 272 273 setVisible(true); 274 }// TestDialog() 275 276 //DO NOT call this directly, go through Sysout 277 public void printInstructions( String[] instructions ) 278 { 279 //Clear out any current instructions 280 instructionsText.setText( "" ); 281 282 //Go down array of instruction strings 283 284 String printStr, remainingStr; 285 for( int i=0; i < instructions.length; i++ ) 286 { 287 //chop up each into pieces maxSringLength long 288 remainingStr = instructions[ i ]; 289 while( remainingStr.length() > 0 ) 290 { 291 //if longer than max then chop off first max chars to print 292 if( remainingStr.length() >= maxStringLength ) 293 { 294 //Try to chop on a word boundary 295 int posOfSpace = remainingStr. 296 lastIndexOf( ' ', maxStringLength - 1 ); 297 298 if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; 299 300 printStr = remainingStr.substring( 0, posOfSpace + 1 ); 301 remainingStr = remainingStr.substring( posOfSpace + 1 ); 302 } 303 //else just print 304 else 305 { 306 printStr = remainingStr; 307 remainingStr = ""; 308 } 309 310 instructionsText.append( printStr + "\n" ); 311 312 }// while 313 314 }// for 315 316 }//printInstructions() 317 318 //DO NOT call this directly, go through Sysout 319 public void displayMessage( String messageIn ) 320 { 321 messageText.append( messageIn + "\n" ); 322 System.out.println(messageIn); 323 } 324 325 }// TestDialog class