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