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