1 /*
   2  * Copyright (c) 2006, 2018, 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         // We must be sure that the Size system command is exactly the 3rd one in the System menu.
  61         System.out.println("NOTE: The test is known to work correctly with English MS Windows only.");
  62 
  63 
  64         String s = Toolkit.getDefaultToolkit().getClass().getName();
  65 
  66         // This is Windows-only test
  67         if (!s.contains("WToolkit")) {
  68             pass();
  69         }
  70 
  71         // MAXIMIZED_BOTH is known to be supported on MS Windows.
  72         if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) {
  73             fail("Toolkit doesn't support the Frame.MAXIMIZED_BOTH extended state.");
  74         }
  75 
  76         final Frame frame = new Frame("Test Frame");
  77 
  78         // Add some components to check their position later
  79         JPanel panel = new JPanel();
  80         panel.setBackground(Color.RED);
  81 
  82         JTextField jf = new JTextField (10);
  83         JTextField jf1 = new JTextField (10);
  84         JButton jb = new JButton("Test");
  85 
  86         panel.add(jf);
  87         panel.add(jf1);
  88         panel.add(jb);
  89         frame.add(panel);
  90 
  91         frame.setSize(400, 400);
  92         frame.setVisible(true);
  93 
  94         Robot robot = Util.createRobot();
  95         robot.setAutoDelay(20);
  96 
  97         // To be sure the window is shown and packed
  98         Util.waitForIdle(robot);
  99 
 100         // The initial JTextField position. After maximization it's supposed to be changed.
 101         Point loc1 = jf1.getLocation();
 102 
 103         System.out.println("The initial position of the JTextField is: " + loc1);
 104 
 105         // The point to move mouse pointer inside the frame
 106         Point pt = frame.getLocation();
 107 
 108         // Alt-Space opens System menu
 109         robot.keyPress(KeyEvent.VK_ALT);
 110         robot.keyPress(KeyEvent.VK_SPACE);
 111         robot.keyRelease(KeyEvent.VK_SPACE);
 112         robot.keyRelease(KeyEvent.VK_ALT);
 113 
 114 
 115         // Two "down arrow" presses move the menu selection to the Size menu item.
 116         for (int i = 0; i < 2; i++) {
 117             robot.keyPress(KeyEvent.VK_DOWN);
 118             robot.keyRelease(KeyEvent.VK_DOWN);
 119         }
 120 
 121         // And finally select the Size command
 122         robot.keyPress(KeyEvent.VK_ENTER);
 123         robot.keyRelease(KeyEvent.VK_ENTER);
 124 
 125         Util.waitForIdle(robot);
 126 
 127         // Now move the mouse pointer somewhere inside the frame.
 128         robot.mouseMove(pt.x + 95, pt.y + 70);
 129 
 130         // And click once we are inside to imitate the canceling of the size operation.
 131         robot.mousePress( InputEvent.BUTTON1_MASK );
 132         robot.mouseRelease( InputEvent.BUTTON1_MASK );
 133         Util.waitForIdle(robot);
 134 
 135         // Now we maximize the frame
 136         frame.setExtendedState(Frame.MAXIMIZED_BOTH);
 137 
 138 
 139         Util.waitForIdle(robot);
 140 
 141         // And check whether the location of the JTextField has changed.
 142         Point loc2 = jf1.getLocation();
 143         System.out.println("Position of the JTextField after maximization is: " + loc2);
 144 
 145         // Location of the component changed if relayouting has happened.
 146 
 147         if (loc2.equals(loc1)) {
 148             fail("Location of a component has not been changed.");
 149             return;
 150         }
 151 
 152         LayoutOnMaximizeTest.pass();
 153 
 154     }//End  init()
 155 
 156 
 157 
 158     /*****************************************************
 159      * Standard Test Machinery Section
 160      * DO NOT modify anything in this section -- it's a
 161      * standard chunk of code which has all of the
 162      * synchronisation necessary for the test harness.
 163      * By keeping it the same in all tests, it is easier
 164      * to read and understand someone else's test, as
 165      * well as insuring that all tests behave correctly
 166      * with the test harness.
 167      * There is a section following this for test-
 168      * classes
 169      ******************************************************/
 170     private static boolean theTestPassed = false;
 171     private static boolean testGeneratedInterrupt = false;
 172     private static String failureMessage = "";
 173 
 174     private static Thread mainThread = null;
 175 
 176     private static int sleepTime = 300000;
 177 
 178     // Not sure about what happens if multiple of this test are
 179     //  instantiated in the same VM.  Being static (and using
 180     //  static vars), it aint gonna work.  Not worrying about
 181     //  it for now.
 182     public static void main( String args[] ) throws InterruptedException
 183     {
 184         mainThread = Thread.currentThread();
 185         try
 186         {
 187             init();
 188         }
 189         catch( TestPassedException e )
 190         {
 191             //The test passed, so just return from main and harness will
 192             // interepret this return as a pass
 193             return;
 194         }
 195         //At this point, neither test pass nor test fail has been
 196         // called -- either would have thrown an exception and ended the
 197         // test, so we know we have multiple threads.
 198 
 199         //Test involves other threads, so sleep and wait for them to
 200         // called pass() or fail()
 201         try
 202         {
 203             Thread.sleep( sleepTime );
 204             //Timed out, so fail the test
 205             throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
 206         }
 207         catch (InterruptedException e)
 208         {
 209             //The test harness may have interrupted the test.  If so, rethrow the exception
 210             // so that the harness gets it and deals with it.
 211             if( ! testGeneratedInterrupt ) throw e;
 212 
 213             //reset flag in case hit this code more than once for some reason (just safety)
 214             testGeneratedInterrupt = false;
 215 
 216             if ( theTestPassed == false )
 217             {
 218                 throw new RuntimeException( failureMessage );
 219             }
 220         }
 221 
 222     }//main
 223 
 224     public static synchronized void setTimeoutTo( int seconds )
 225     {
 226         sleepTime = seconds * 1000;
 227     }
 228 
 229     public static synchronized void pass()
 230     {
 231         System.out.println( "The test passed." );
 232         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 233         //first check if this is executing in main thread
 234         if ( mainThread == Thread.currentThread() )
 235         {
 236             //Still in the main thread, so set the flag just for kicks,
 237             // and throw a test passed exception which will be caught
 238             // and end the test.
 239             theTestPassed = true;
 240             throw new TestPassedException();
 241         }
 242         theTestPassed = true;
 243         testGeneratedInterrupt = true;
 244         mainThread.interrupt();
 245     }//pass()
 246 
 247     public static synchronized void fail()
 248     {
 249         //test writer didn't specify why test failed, so give generic
 250         fail( "it just plain failed! :-)" );
 251     }
 252 
 253     public static synchronized void fail( String whyFailed )
 254     {
 255         System.out.println( "The test failed: " + whyFailed );
 256         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 257         //check if this called from main thread
 258         if ( mainThread == Thread.currentThread() )
 259         {
 260             //If main thread, fail now 'cause not sleeping
 261             throw new RuntimeException( whyFailed );
 262         }
 263         theTestPassed = false;
 264         testGeneratedInterrupt = true;
 265         failureMessage = whyFailed;
 266         mainThread.interrupt();
 267     }//fail()
 268 
 269 }// class LayoutOnMaximizeTest
 270 
 271 //This exception is used to exit from any level of call nesting
 272 // when it's determined that the test has passed, and immediately
 273 // end the test.
 274 class TestPassedException extends RuntimeException
 275 {
 276 }