CompEventOnHiddenComponent.java revision 14851:980da45565c8
1/* 2 * Copyright (c) 2006, 2016, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26/* 27 @test 28 @key headful 29 @bug 6383903 8144166 30 @summary REGRESSION: componentMoved is now getting called for some hidden components 31 @author andrei.dmitriev: area=awt.component 32 @run main CompEventOnHiddenComponent 33*/ 34 35import java.awt.*; 36import java.awt.event.*; 37import javax.swing.*; 38 39public class CompEventOnHiddenComponent 40{ 41 transient static boolean moved = false; 42 transient static boolean resized = false; 43 44 transient static boolean ancestor_moved = false; 45 transient static boolean ancestor_resized = false; 46 static String passed = ""; 47 48 private static void init() 49 { 50 String[] instructions = 51 { 52 "This is an AUTOMATIC test, simply wait until it is done.", 53 "The result (passed or failed) will be shown in the", 54 "message window below." 55 }; 56 Sysout.createDialog( ); 57 Sysout.printInstructions( instructions ); 58 59 Robot robot; 60 try { 61 robot = new Robot(); 62 }catch(Exception ex) { 63 ex.printStackTrace(); 64 throw new RuntimeException("Unexpected failure"); 65 } 66 67 EventQueue.invokeLater(new Runnable(){ 68 public void run(){ 69 JFrame f = new JFrame("JFrame"); 70 JButton b = new JButton("JButton"); 71 f.add(b); 72 new JOptionPane(). 73 createInternalFrame(b, "Test"). 74 addComponentListener(new ComponentAdapter() { 75 public void componentMoved(ComponentEvent e) { 76 moved = true; 77 System.out.println(e); 78 } 79 public void componentResized(ComponentEvent e) { 80 resized = true; 81 System.out.println(e); 82 } 83 }); 84 } 85 }); 86 87 robot.waitForIdle(); 88 89 if (moved || resized){ 90 passed = "Hidden component got COMPONENT_MOVED or COMPONENT_RESIZED event"; 91 } else { 92 System.out.println("Stage 1 passed."); 93 } 94 95 EventQueue.invokeLater(new Runnable() { 96 public void run() { 97 JFrame parentWindow = new JFrame("JFrame 1"); 98 JButton component = new JButton("JButton 1");; 99 JButton smallButton = new JButton("Small Button"); 100 101 102 smallButton.addHierarchyBoundsListener(new HierarchyBoundsAdapter() { 103 public void ancestorMoved(HierarchyEvent e) { 104 ancestor_moved = true; 105 System.out.println("SMALL COMPONENT >>>>>"+e); 106 } 107 public void ancestorResized(HierarchyEvent e) { 108 ancestor_resized = true; 109 System.out.println("SMALL COMPONENT >>>>>"+e); 110 } 111 }); 112 113 114 parentWindow.add(component); 115 component.add(smallButton); 116 117 component.setSize(100, 100); 118 component.setLocation(100, 100); 119 120 } 121 }); 122 123 robot.waitForIdle(); 124 125 if (!ancestor_resized || !ancestor_moved){ 126 passed = "Hidden component didn't get ANCESTOR event"; 127 } else { 128 System.out.println("Stage 2 passed."); 129 } 130 131 robot.waitForIdle(); 132 133 if (passed.equals("")){ 134 CompEventOnHiddenComponent.pass(); 135 } else { 136 CompEventOnHiddenComponent.fail(passed); 137 } 138 139 }//End init() 140 141 142 143 /***************************************************** 144 * Standard Test Machinery Section 145 * DO NOT modify anything in this section -- it's a 146 * standard chunk of code which has all of the 147 * synchronisation necessary for the test harness. 148 * By keeping it the same in all tests, it is easier 149 * to read and understand someone else's test, as 150 * well as insuring that all tests behave correctly 151 * with the test harness. 152 * There is a section following this for test- 153 * classes 154 ******************************************************/ 155 private static boolean theTestPassed = false; 156 private static boolean testGeneratedInterrupt = false; 157 private static String failureMessage = ""; 158 159 private static Thread mainThread = null; 160 161 private static int sleepTime = 300000; 162 163 // Not sure about what happens if multiple of this test are 164 // instantiated in the same VM. Being static (and using 165 // static vars), it aint gonna work. Not worrying about 166 // it for now. 167 public static void main( String args[] ) throws InterruptedException 168 { 169 mainThread = Thread.currentThread(); 170 try 171 { 172 init(); 173 } 174 catch( TestPassedException e ) 175 { 176 //The test passed, so just return from main and harness will 177 // interepret this return as a pass 178 return; 179 } 180 //At this point, neither test pass nor test fail has been 181 // called -- either would have thrown an exception and ended the 182 // test, so we know we have multiple threads. 183 184 //Test involves other threads, so sleep and wait for them to 185 // called pass() or fail() 186 try 187 { 188 Thread.sleep( sleepTime ); 189 //Timed out, so fail the test 190 throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); 191 } 192 catch (InterruptedException e) 193 { 194 //The test harness may have interrupted the test. If so, rethrow the exception 195 // so that the harness gets it and deals with it. 196 if( ! testGeneratedInterrupt ) throw e; 197 198 //reset flag in case hit this code more than once for some reason (just safety) 199 testGeneratedInterrupt = false; 200 201 if ( theTestPassed == false ) 202 { 203 throw new RuntimeException( failureMessage ); 204 } 205 } 206 207 }//main 208 209 public static synchronized void setTimeoutTo( int seconds ) 210 { 211 sleepTime = seconds * 1000; 212 } 213 214 public static synchronized void pass() 215 { 216 Sysout.println( "The test passed." ); 217 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 218 //first check if this is executing in main thread 219 if ( mainThread == Thread.currentThread() ) 220 { 221 //Still in the main thread, so set the flag just for kicks, 222 // and throw a test passed exception which will be caught 223 // and end the test. 224 theTestPassed = true; 225 throw new TestPassedException(); 226 } 227 theTestPassed = true; 228 testGeneratedInterrupt = true; 229 mainThread.interrupt(); 230 }//pass() 231 232 public static synchronized void fail() 233 { 234 //test writer didn't specify why test failed, so give generic 235 fail( "it just plain failed! :-)" ); 236 } 237 238 public static synchronized void fail( String whyFailed ) 239 { 240 Sysout.println( "The test failed: " + whyFailed ); 241 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 242 //check if this called from main thread 243 if ( mainThread == Thread.currentThread() ) 244 { 245 //If main thread, fail now 'cause not sleeping 246 throw new RuntimeException( whyFailed ); 247 } 248 theTestPassed = false; 249 testGeneratedInterrupt = true; 250 failureMessage = whyFailed; 251 mainThread.interrupt(); 252 }//fail() 253 254}// class CompEventOnHiddenComponent 255 256//This exception is used to exit from any level of call nesting 257// when it's determined that the test has passed, and immediately 258// end the test. 259class TestPassedException extends RuntimeException 260{ 261} 262 263//*********** End Standard Test Machinery Section ********** 264 265 266//************ Begin classes defined for the test **************** 267 268// if want to make listeners, here is the recommended place for them, then instantiate 269// them in init() 270 271/* Example of a class which may be written as part of a test 272class NewClass implements anInterface 273 { 274 static int newVar = 0; 275 276 public void eventDispatched(AWTEvent e) 277 { 278 //Counting events to see if we get enough 279 eventCount++; 280 281 if( eventCount == 20 ) 282 { 283 //got enough events, so pass 284 285 CompEventOnHiddenComponent.pass(); 286 } 287 else if( tries == 20 ) 288 { 289 //tried too many times without getting enough events so fail 290 291 CompEventOnHiddenComponent.fail(); 292 } 293 294 }// eventDispatched() 295 296 }// NewClass class 297 298*/ 299 300 301//************** End classes defined for the test ******************* 302 303 304 305 306/**************************************************** 307 Standard Test Machinery 308 DO NOT modify anything below -- it's a standard 309 chunk of code whose purpose is to make user 310 interaction uniform, and thereby make it simpler 311 to read and understand someone else's test. 312 ****************************************************/ 313 314/** 315 This is part of the standard test machinery. 316 It creates a dialog (with the instructions), and is the interface 317 for sending text messages to the user. 318 To print the instructions, send an array of strings to Sysout.createDialog 319 WithInstructions method. Put one line of instructions per array entry. 320 To display a message for the tester to see, simply call Sysout.println 321 with the string to be displayed. 322 This mimics System.out.println but works within the test harness as well 323 as standalone. 324 */ 325 326class Sysout 327{ 328 private static TestDialog dialog; 329 330 public static void createDialogWithInstructions( String[] instructions ) 331 { 332 dialog = new TestDialog( new Frame(), "Instructions" ); 333 dialog.printInstructions( instructions ); 334 dialog.setVisible(true); 335 println( "Any messages for the tester will display here." ); 336 } 337 338 public static void createDialog( ) 339 { 340 dialog = new TestDialog( new Frame(), "Instructions" ); 341 String[] defInstr = { "Instructions will appear here. ", "" } ; 342 dialog.printInstructions( defInstr ); 343 dialog.setVisible(true); 344 println( "Any messages for the tester will display here." ); 345 } 346 347 348 public static void printInstructions( String[] instructions ) 349 { 350 dialog.printInstructions( instructions ); 351 } 352 353 354 public static void println( String messageIn ) 355 { 356 dialog.displayMessage( messageIn ); 357 System.out.println(messageIn); 358 } 359 360}// Sysout class 361 362/** 363 This is part of the standard test machinery. It provides a place for the 364 test instructions to be displayed, and a place for interactive messages 365 to the user to be displayed. 366 To have the test instructions displayed, see Sysout. 367 To have a message to the user be displayed, see Sysout. 368 Do not call anything in this dialog directly. 369 */ 370class TestDialog extends Dialog 371{ 372 373 TextArea instructionsText; 374 TextArea messageText; 375 int maxStringLength = 80; 376 377 //DO NOT call this directly, go through Sysout 378 public TestDialog( Frame frame, String name ) 379 { 380 super( frame, name ); 381 int scrollBoth = TextArea.SCROLLBARS_BOTH; 382 instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); 383 add( "North", instructionsText ); 384 385 messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); 386 add("Center", messageText); 387 388 pack(); 389 390 setVisible(true); 391 }// TestDialog() 392 393 //DO NOT call this directly, go through Sysout 394 public void printInstructions( String[] instructions ) 395 { 396 //Clear out any current instructions 397 instructionsText.setText( "" ); 398 399 //Go down array of instruction strings 400 401 String printStr, remainingStr; 402 for( int i=0; i < instructions.length; i++ ) 403 { 404 //chop up each into pieces maxSringLength long 405 remainingStr = instructions[ i ]; 406 while( remainingStr.length() > 0 ) 407 { 408 //if longer than max then chop off first max chars to print 409 if( remainingStr.length() >= maxStringLength ) 410 { 411 //Try to chop on a word boundary 412 int posOfSpace = remainingStr. 413 lastIndexOf( ' ', maxStringLength - 1 ); 414 415 if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; 416 417 printStr = remainingStr.substring( 0, posOfSpace + 1 ); 418 remainingStr = remainingStr.substring( posOfSpace + 1 ); 419 } 420 //else just print 421 else 422 { 423 printStr = remainingStr; 424 remainingStr = ""; 425 } 426 427 instructionsText.append( printStr + "\n" ); 428 429 }// while 430 431 }// for 432 433 }//printInstructions() 434 435 //DO NOT call this directly, go through Sysout 436 public void displayMessage( String messageIn ) 437 { 438 messageText.append( messageIn + "\n" ); 439 System.out.println(messageIn); 440 } 441 442}// TestDialog class 443