1 /* 2 @test 3 @bug 6401036 4 @summary InputVerifier shouldn't be called when requestFocus() is called on comp from another toplevel 5 @author oleg.sukhodolsky: area=awt.focus 6 @run main InputVerifierTest2 7 */ 8 9 /** 10 * InputVerifierTest2.java 11 * 12 * summary: REGRESSION: InputVerifier and JOptionPane 13 */ 14 15 import java.awt.AWTException; 16 import java.awt.BorderLayout; 17 import java.awt.Component; 18 import java.awt.Dialog; 19 import java.awt.Frame; 20 import java.awt.Point; 21 import java.awt.Robot; 22 import java.awt.TextArea; 23 import java.awt.Toolkit; 24 25 import java.awt.event.InputEvent; 26 27 import javax.swing.InputVerifier; 28 import javax.swing.JButton; 29 import javax.swing.JComponent; 30 import javax.swing.JFrame; 31 import javax.swing.JTextField; 32 import javax.swing.JWindow; 33 34 import sun.awt.SunToolkit; 35 36 public class InputVerifierTest2 37 { 38 39 private static void init() 40 { 41 //*** Create instructions for the user here *** 42 43 String[] instructions = 44 { 45 "This is an AUTOMATIC test, simply wait until it is done.", 46 "The result (passed or failed) will be shown in the", 47 "message window below." 48 }; 49 Sysout.createDialog( ); 50 Sysout.printInstructions( instructions ); 51 52 JFrame frame = new JFrame(); 53 frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 54 JTextField tf = new JTextField(10); 55 frame.getContentPane().add(tf); 56 57 final JWindow w = new JWindow(frame); 58 JButton btn1 = new JButton("window"); 59 btn1.setName("bnt1"); 60 w.getContentPane().add(btn1); 61 w.pack(); 62 w.setVisible(true); 63 64 frame.setSize(200, 200); 65 frame.setVisible(true); 66 67 SunToolkit tk = ((SunToolkit)Toolkit.getDefaultToolkit()); 68 69 Robot r = null; 70 try { 71 r = new Robot(); 72 } catch (AWTException e) { 73 InputVerifierTest2.fail(e); 74 } 75 76 77 try { 78 tk.realSync(); 79 mouseClickOnComp(r, tf); 80 tk.realSync(); 81 82 if (!tf.isFocusOwner()) { 83 throw new RuntimeException("t1 is not a focus owner"); 84 } 85 86 tf.setInputVerifier(new InputVerifier() { 87 public boolean verify(JComponent input) { 88 System.err.println("verify on " + input); 89 throw new RuntimeException("InputVerifier should not be called"); 90 } 91 }); 92 btn1.requestFocus(); 93 } catch (Exception e) { 94 InputVerifierTest2.fail(e); 95 } 96 97 InputVerifierTest2.pass(); 98 99 }//End init() 100 101 102 static void mouseClickOnComp(Robot r, Component comp) { 103 Point loc = comp.getLocationOnScreen(); 104 loc.x += comp.getWidth() / 2; 105 loc.y += comp.getHeight() / 2; 106 r.mouseMove(loc.x, loc.y); 107 r.delay(10); 108 r.mousePress(InputEvent.BUTTON1_MASK); 109 r.delay(10); 110 r.mouseRelease(InputEvent.BUTTON1_MASK); 111 } 112 113 /***************************************************** 114 * Standard Test Machinery Section 115 * DO NOT modify anything in this section -- it's a 116 * standard chunk of code which has all of the 117 * synchronisation necessary for the test harness. 118 * By keeping it the same in all tests, it is easier 119 * to read and understand someone else's test, as 120 * well as insuring that all tests behave correctly 121 * with the test harness. 122 * There is a section following this for test- 123 * classes 124 ******************************************************/ 125 private static boolean theTestPassed = false; 126 private static boolean testGeneratedInterrupt = false; 127 private static String failureMessage = ""; 128 129 private static Thread mainThread = null; 130 131 private static int sleepTime = 300000; 132 133 // Not sure about what happens if multiple of this test are 134 // instantiated in the same VM. Being static (and using 135 // static vars), it aint gonna work. Not worrying about 136 // it for now. 137 public static void main( String args[] ) throws InterruptedException 138 { 139 mainThread = Thread.currentThread(); 140 try 141 { 142 init(); 143 } 144 catch( TestPassedException e ) 145 { 146 //The test passed, so just return from main and harness will 147 // interepret this return as a pass 148 return; 149 } 150 //At this point, neither test pass nor test fail has been 151 // called -- either would have thrown an exception and ended the 152 // test, so we know we have multiple threads. 153 154 //Test involves other threads, so sleep and wait for them to 155 // called pass() or fail() 156 try 157 { 158 Thread.sleep( sleepTime ); 159 //Timed out, so fail the test 160 throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); 161 } 162 catch (InterruptedException e) 163 { 164 //The test harness may have interrupted the test. If so, rethrow the exception 165 // so that the harness gets it and deals with it. 166 if( ! testGeneratedInterrupt ) throw e; 167 168 //reset flag in case hit this code more than once for some reason (just safety) 169 testGeneratedInterrupt = false; 170 171 if ( theTestPassed == false ) 172 { 173 throw new RuntimeException( failureMessage ); 174 } 175 } 176 177 }//main 178 179 public static synchronized void setTimeoutTo( int seconds ) 180 { 181 sleepTime = seconds * 1000; 182 } 183 184 public static synchronized void pass() 185 { 186 Sysout.println( "The test passed." ); 187 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 188 //first check if this is executing in main thread 189 if ( mainThread == Thread.currentThread() ) 190 { 191 //Still in the main thread, so set the flag just for kicks, 192 // and throw a test passed exception which will be caught 193 // and end the test. 194 theTestPassed = true; 195 throw new TestPassedException(); 196 } 197 theTestPassed = true; 198 testGeneratedInterrupt = true; 199 mainThread.interrupt(); 200 }//pass() 201 202 public static synchronized void fail( Exception whyFailed ) 203 { 204 Sysout.println( "The test failed: " + whyFailed ); 205 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 206 //check if this called from main thread 207 if ( mainThread == Thread.currentThread() ) 208 { 209 //If main thread, fail now 'cause not sleeping 210 throw new RuntimeException( whyFailed ); 211 } 212 theTestPassed = false; 213 testGeneratedInterrupt = true; 214 failureMessage = whyFailed.toString(); 215 mainThread.interrupt(); 216 }//fail() 217 218 }// class InputVerifierTest2 219 220 //This exception is used to exit from any level of call nesting 221 // when it's determined that the test has passed, and immediately 222 // end the test. 223 class TestPassedException extends RuntimeException 224 { 225 } 226 227 //*********** End Standard Test Machinery Section ********** 228 229 /**************************************************** 230 Standard Test Machinery 231 DO NOT modify anything below -- it's a standard 232 chunk of code whose purpose is to make user 233 interaction uniform, and thereby make it simpler 234 to read and understand someone else's test. 235 ****************************************************/ 236 237 /** 238 This is part of the standard test machinery. 239 It creates a dialog (with the instructions), and is the interface 240 for sending text messages to the user. 241 To print the instructions, send an array of strings to Sysout.createDialog 242 WithInstructions method. Put one line of instructions per array entry. 243 To display a message for the tester to see, simply call Sysout.println 244 with the string to be displayed. 245 This mimics System.out.println but works within the test harness as well 246 as standalone. 247 */ 248 249 class Sysout 250 { 251 private static TestDialog dialog; 252 253 public static void createDialogWithInstructions( String[] instructions ) 254 { 255 dialog = new TestDialog( new Frame(), "Instructions" ); 256 dialog.printInstructions( instructions ); 257 dialog.setVisible(true); 258 println( "Any messages for the tester will display here." ); 259 } 260 261 public static void createDialog( ) 262 { 263 dialog = new TestDialog( new Frame(), "Instructions" ); 264 String[] defInstr = { "Instructions will appear here. ", "" } ; 265 dialog.printInstructions( defInstr ); 266 dialog.setVisible(true); 267 println( "Any messages for the tester will display here." ); 268 } 269 270 271 public static void printInstructions( String[] instructions ) 272 { 273 dialog.printInstructions( instructions ); 274 } 275 276 277 public static void println( String messageIn ) 278 { 279 dialog.displayMessage( messageIn ); 280 System.out.println(messageIn); 281 } 282 283 }// Sysout class 284 285 /** 286 This is part of the standard test machinery. It provides a place for the 287 test instructions to be displayed, and a place for interactive messages 288 to the user to be displayed. 289 To have the test instructions displayed, see Sysout. 290 To have a message to the user be displayed, see Sysout. 291 Do not call anything in this dialog directly. 292 */ 293 class TestDialog extends Dialog 294 { 295 296 TextArea instructionsText; 297 TextArea messageText; 298 int maxStringLength = 80; 299 300 //DO NOT call this directly, go through Sysout 301 public TestDialog( Frame frame, String name ) 302 { 303 super( frame, name ); 304 int scrollBoth = TextArea.SCROLLBARS_BOTH; 305 instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); 306 add( "North", instructionsText ); 307 308 messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); 309 add("Center", messageText); 310 311 pack(); 312 313 setVisible(true); 314 }// TestDialog() 315 316 //DO NOT call this directly, go through Sysout 317 public void printInstructions( String[] instructions ) 318 { 319 //Clear out any current instructions 320 instructionsText.setText( "" ); 321 322 //Go down array of instruction strings 323 324 String printStr, remainingStr; 325 for( int i=0; i < instructions.length; i++ ) 326 { 327 //chop up each into pieces maxSringLength long 328 remainingStr = instructions[ i ]; 329 while( remainingStr.length() > 0 ) 330 { 331 //if longer than max then chop off first max chars to print 332 if( remainingStr.length() >= maxStringLength ) 333 { 334 //Try to chop on a word boundary 335 int posOfSpace = remainingStr. 336 lastIndexOf( ' ', maxStringLength - 1 ); 337 338 if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; 339 340 printStr = remainingStr.substring( 0, posOfSpace + 1 ); 341 remainingStr = remainingStr.substring( posOfSpace + 1 ); 342 } 343 //else just print 344 else 345 { 346 printStr = remainingStr; 347 remainingStr = ""; 348 } 349 350 instructionsText.append( printStr + "\n" ); 351 352 }// while 353 354 }// for 355 356 }//printInstructions() 357 358 //DO NOT call this directly, go through Sysout 359 public void displayMessage( String messageIn ) 360 { 361 messageText.append( messageIn + "\n" ); 362 System.out.println(messageIn); 363 } 364 365 }// TestDialog class