1 /* 2 * Copyright (c) 2009, 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. 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 %W% %E% 26 @key headful 27 @bug 6779670 28 @summary Tests if a LW components in the glass pane affects HW in the content pane 29 @author anthony.petrov@...: area=awt.mixing 30 @library ../regtesthelpers 31 @build Util 32 @run main JButtonInGlassPane 33 */ 34 35 36 /** 37 * JButtonInGlassPane.java 38 * 39 * summary: Tests whether a LW menu correctly overlaps a HW button 40 */ 41 42 import java.awt.*; 43 import java.awt.event.*; 44 import javax.swing.*; 45 import test.java.awt.regtesthelpers.Util; 46 47 48 49 public class JButtonInGlassPane 50 { 51 static volatile boolean failed = false; 52 53 private static void init() 54 { 55 //*** Create instructions for the user here *** 56 57 String[] instructions = 58 { 59 "This is an AUTOMATIC test, simply wait until it is done.", 60 "The result (passed or failed) will be shown in the", 61 "message window below." 62 }; 63 Sysout.createDialog( ); 64 Sysout.printInstructions( instructions ); 65 66 JFrame frame = new JFrame("Glass Pane children test"); 67 frame.setLayout(null); 68 69 final Button button = new Button("AWT Button"); 70 button.setBounds(100,100,100,100); 71 frame.add(button); 72 73 button.addActionListener(new ActionListener() { 74 public void actionPerformed(ActionEvent e) { 75 failed = true; 76 } 77 }); 78 79 frame.getGlassPane().setVisible(true); 80 Container glassPane = (Container) frame.getGlassPane(); 81 glassPane.setLayout(null); 82 83 final JButton jbutton = new JButton("JButton"); 84 jbutton.setBounds(50,50,100,100); 85 glassPane.add(jbutton); 86 87 jbutton.setVisible(false); 88 89 frame.setSize(400, 400); 90 frame.setLocationRelativeTo(null); 91 frame.setVisible(true); 92 93 Robot robot = Util.createRobot(); 94 robot.setAutoDelay(20); 95 96 Util.waitForIdle(robot); 97 98 jbutton.setVisible(true); 99 Util.waitForIdle(robot); 100 101 // Click the LW button - in the area that intersects with 102 // the HW button. 103 Point lLoc = jbutton.getLocationOnScreen(); 104 robot.mouseMove(lLoc.x + jbutton.getWidth() - 5, lLoc.y + jbutton.getHeight() - 5); 105 106 robot.mousePress(InputEvent.BUTTON1_MASK); 107 robot.mouseRelease(InputEvent.BUTTON1_MASK); 108 Util.waitForIdle(robot); 109 110 jbutton.setBounds(50,50,120,120); 111 Util.waitForIdle(robot); 112 113 // Now click on the 'added' area of the LW button that again 114 // intersects with the HW. 115 robot.mouseMove(lLoc.x + jbutton.getWidth() - 5, lLoc.y + jbutton.getHeight() - 5); 116 117 robot.mousePress(InputEvent.BUTTON1_MASK); 118 robot.mouseRelease(InputEvent.BUTTON1_MASK); 119 Util.waitForIdle(robot); 120 121 if (failed) { 122 JButtonInGlassPane.fail("The LW button did not receive the click."); 123 } else { 124 JButtonInGlassPane.pass(); 125 } 126 }//End init() 127 128 129 130 /***************************************************** 131 * Standard Test Machinery Section 132 * DO NOT modify anything in this section -- it's a 133 * standard chunk of code which has all of the 134 * synchronisation necessary for the test harness. 135 * By keeping it the same in all tests, it is easier 136 * to read and understand someone else's test, as 137 * well as insuring that all tests behave correctly 138 * with the test harness. 139 * There is a section following this for test- 140 * classes 141 ******************************************************/ 142 private static boolean theTestPassed = false; 143 private static boolean testGeneratedInterrupt = false; 144 private static String failureMessage = ""; 145 146 private static Thread mainThread = null; 147 148 private static int sleepTime = 300000; 149 150 // Not sure about what happens if multiple of this test are 151 // instantiated in the same VM. Being static (and using 152 // static vars), it aint gonna work. Not worrying about 153 // it for now. 154 public static void main( String args[] ) throws InterruptedException 155 { 156 mainThread = Thread.currentThread(); 157 try 158 { 159 init(); 160 } 161 catch( TestPassedException e ) 162 { 163 //The test passed, so just return from main and harness will 164 // interepret this return as a pass 165 return; 166 } 167 //At this point, neither test pass nor test fail has been 168 // called -- either would have thrown an exception and ended the 169 // test, so we know we have multiple threads. 170 171 //Test involves other threads, so sleep and wait for them to 172 // called pass() or fail() 173 try 174 { 175 Thread.sleep( sleepTime ); 176 //Timed out, so fail the test 177 throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); 178 } 179 catch (InterruptedException e) 180 { 181 //The test harness may have interrupted the test. If so, rethrow the exception 182 // so that the harness gets it and deals with it. 183 if( ! testGeneratedInterrupt ) throw e; 184 185 //reset flag in case hit this code more than once for some reason (just safety) 186 testGeneratedInterrupt = false; 187 188 if ( theTestPassed == false ) 189 { 190 throw new RuntimeException( failureMessage ); 191 } 192 } 193 194 }//main 195 196 public static synchronized void setTimeoutTo( int seconds ) 197 { 198 sleepTime = seconds * 1000; 199 } 200 201 public static synchronized void pass() 202 { 203 Sysout.println( "The test passed." ); 204 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 205 //first check if this is executing in main thread 206 if ( mainThread == Thread.currentThread() ) 207 { 208 //Still in the main thread, so set the flag just for kicks, 209 // and throw a test passed exception which will be caught 210 // and end the test. 211 theTestPassed = true; 212 throw new TestPassedException(); 213 } 214 theTestPassed = true; 215 testGeneratedInterrupt = true; 216 mainThread.interrupt(); 217 }//pass() 218 219 public static synchronized void fail() 220 { 221 //test writer didn't specify why test failed, so give generic 222 fail( "it just plain failed! :-)" ); 223 } 224 225 public static synchronized void fail( String whyFailed ) 226 { 227 Sysout.println( "The test failed: " + whyFailed ); 228 Sysout.println( "The test is over, hit Ctl-C to stop Java VM" ); 229 //check if this called from main thread 230 if ( mainThread == Thread.currentThread() ) 231 { 232 //If main thread, fail now 'cause not sleeping 233 throw new RuntimeException( whyFailed ); 234 } 235 theTestPassed = false; 236 testGeneratedInterrupt = true; 237 failureMessage = whyFailed; 238 mainThread.interrupt(); 239 }//fail() 240 241 }// class JButtonInGlassPane 242 243 //This exception is used to exit from any level of call nesting 244 // when it's determined that the test has passed, and immediately 245 // end the test. 246 class TestPassedException extends RuntimeException 247 { 248 } 249 250 //*********** End Standard Test Machinery Section ********** 251 252 253 //************ Begin classes defined for the test **************** 254 255 // if want to make listeners, here is the recommended place for them, then instantiate 256 // them in init() 257 258 /* Example of a class which may be written as part of a test 259 class NewClass implements anInterface 260 { 261 static int newVar = 0; 262 263 public void eventDispatched(AWTEvent e) 264 { 265 //Counting events to see if we get enough 266 eventCount++; 267 268 if( eventCount == 20 ) 269 { 270 //got enough events, so pass 271 272 JButtonInGlassPane.pass(); 273 } 274 else if( tries == 20 ) 275 { 276 //tried too many times without getting enough events so fail 277 278 JButtonInGlassPane.fail(); 279 } 280 281 }// eventDispatched() 282 283 }// NewClass class 284 285 */ 286 287 288 //************** End classes defined for the test ******************* 289 290 291 292 293 /**************************************************** 294 Standard Test Machinery 295 DO NOT modify anything below -- it's a standard 296 chunk of code whose purpose is to make user 297 interaction uniform, and thereby make it simpler 298 to read and understand someone else's test. 299 ****************************************************/ 300 301 /** 302 This is part of the standard test machinery. 303 It creates a dialog (with the instructions), and is the interface 304 for sending text messages to the user. 305 To print the instructions, send an array of strings to Sysout.createDialog 306 WithInstructions method. Put one line of instructions per array entry. 307 To display a message for the tester to see, simply call Sysout.println 308 with the string to be displayed. 309 This mimics System.out.println but works within the test harness as well 310 as standalone. 311 */ 312 313 class Sysout 314 { 315 private static TestDialog dialog; 316 317 public static void createDialogWithInstructions( String[] instructions ) 318 { 319 dialog = new TestDialog( new Frame(), "Instructions" ); 320 dialog.printInstructions( instructions ); 321 dialog.setVisible(true); 322 println( "Any messages for the tester will display here." ); 323 } 324 325 public static void createDialog( ) 326 { 327 dialog = new TestDialog( new Frame(), "Instructions" ); 328 String[] defInstr = { "Instructions will appear here. ", "" } ; 329 dialog.printInstructions( defInstr ); 330 dialog.setVisible(true); 331 println( "Any messages for the tester will display here." ); 332 } 333 334 335 public static void printInstructions( String[] instructions ) 336 { 337 dialog.printInstructions( instructions ); 338 } 339 340 341 public static void println( String messageIn ) 342 { 343 dialog.displayMessage( messageIn ); 344 System.out.println(messageIn); 345 } 346 347 }// Sysout class 348 349 /** 350 This is part of the standard test machinery. It provides a place for the 351 test instructions to be displayed, and a place for interactive messages 352 to the user to be displayed. 353 To have the test instructions displayed, see Sysout. 354 To have a message to the user be displayed, see Sysout. 355 Do not call anything in this dialog directly. 356 */ 357 class TestDialog extends Dialog 358 { 359 360 TextArea instructionsText; 361 TextArea messageText; 362 int maxStringLength = 80; 363 364 //DO NOT call this directly, go through Sysout 365 public TestDialog( Frame frame, String name ) 366 { 367 super( frame, name ); 368 int scrollBoth = TextArea.SCROLLBARS_BOTH; 369 instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); 370 add( "North", instructionsText ); 371 372 messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); 373 add("Center", messageText); 374 375 pack(); 376 377 setVisible(true); 378 }// TestDialog() 379 380 //DO NOT call this directly, go through Sysout 381 public void printInstructions( String[] instructions ) 382 { 383 //Clear out any current instructions 384 instructionsText.setText( "" ); 385 386 //Go down array of instruction strings 387 388 String printStr, remainingStr; 389 for( int i=0; i < instructions.length; i++ ) 390 { 391 //chop up each into pieces maxSringLength long 392 remainingStr = instructions[ i ]; 393 while( remainingStr.length() > 0 ) 394 { 395 //if longer than max then chop off first max chars to print 396 if( remainingStr.length() >= maxStringLength ) 397 { 398 //Try to chop on a word boundary 399 int posOfSpace = remainingStr. 400 lastIndexOf( ' ', maxStringLength - 1 ); 401 402 if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; 403 404 printStr = remainingStr.substring( 0, posOfSpace + 1 ); 405 remainingStr = remainingStr.substring( posOfSpace + 1 ); 406 } 407 //else just print 408 else 409 { 410 printStr = remainingStr; 411 remainingStr = ""; 412 } 413 414 instructionsText.append( printStr + "\n" ); 415 416 }// while 417 418 }// for 419 420 }//printInstructions() 421 422 //DO NOT call this directly, go through Sysout 423 public void displayMessage( String messageIn ) 424 { 425 messageText.append( messageIn + "\n" ); 426 System.out.println(messageIn); 427 } 428 429 }// TestDialog class 430 431