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