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