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