1 /*
   2  * Copyright (c) 2007, 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 6533330
  28   @summary ANCESTOR_RESIZED is not sent while resizing a frame. Regression caused by 6500477.
  29   @author anthony.petrov: area=awt.toplevel
  30   @library ../../../regtesthelpers
  31   @build Util
  32   @run main AncestorResized
  33 */
  34 
  35 
  36 /**
  37  * AncestorResized.java
  38  *
  39  * summary:  After fixing the 6500477, the ANCESTOR_RESIZED event stoped
  40  *           firing while resizing a frame. This was a regression.
  41  *           The test checks whether the event starts dispatching as it
  42  *           was before fixing the 6500477.
  43  */
  44 
  45 import java.awt.*;
  46 import java.awt.event.*;
  47 import test.java.awt.regtesthelpers.Util;
  48 
  49 
  50 public class AncestorResized
  51 {
  52     public static volatile int ancestorResizedCounter = 0;
  53 
  54 
  55     static class HierarchyBoundsListenerImpl implements HierarchyBoundsListener {
  56         public void ancestorMoved(HierarchyEvent ce) {
  57             // ANCESTOR_MOVED seems to work OK.
  58         }
  59         public void ancestorResized(HierarchyEvent ce) {
  60             ancestorResizedCounter++;
  61         }
  62     }
  63 
  64     private static void init()
  65     {
  66         Frame frame;
  67         Panel panel;
  68         Button button;
  69         Label label;
  70         Component[] components;
  71 
  72         frame = new Frame("Test Frame");
  73         frame.setLayout(new FlowLayout());
  74 
  75         panel = new Panel();
  76         button = new Button("Button");
  77         label = new Label("Label");
  78 
  79         components = new Component[] {
  80             panel, button, label
  81         };
  82 
  83         frame.setSize(300, 300);
  84         frame.setVisible(true);
  85 
  86         Robot robot = Util.createRobot();
  87         robot.setAutoDelay(20);
  88 
  89         // To ensure the window is shown and packed
  90         Util.waitForIdle(robot);
  91 
  92         Insets insets = frame.getInsets();
  93         if (insets.right == 0 || insets.bottom == 0) {
  94             // Because we want to catch the "size-grip" of the frame.
  95             System.out.println("The test environment must have non-zero right & bottom insets! The current insets are: " + insets);
  96             pass();
  97             return;
  98         }
  99 
 100         // Let's move the mouse pointer to the bottom-right coner of the frame (the "size-grip")
 101         Rectangle bounds = frame.getBounds();
 102 
 103         robot.mouseMove(bounds.x + bounds.width - 1, bounds.y + bounds.height - 1);
 104 
 105         // From now on the ANCESTOR_RESIZED events get counted.
 106         HierarchyBoundsListener listener = new HierarchyBoundsListenerImpl();
 107         for (int i = 0; i < components.length; i++) {
 108             components[i].addHierarchyBoundsListener(listener);
 109             frame.add(components[i]);
 110         }
 111 
 112         // ... and start resizing
 113         robot.mousePress( InputEvent.BUTTON1_MASK );
 114         robot.mouseMove(bounds.x + bounds.width + 20, bounds.y + bounds.height + 15);
 115         Util.waitForIdle(robot);
 116 
 117         if (ancestorResizedCounter == 0) {
 118             robot.mouseRelease( InputEvent.BUTTON1_MASK );
 119             AncestorResized.fail("No ANCESTOR_RESIZED events received.");
 120             return;
 121         }
 122 
 123         robot.mouseRelease( InputEvent.BUTTON1_MASK );
 124 
 125         AncestorResized.pass();
 126     }//End  init()
 127 
 128 
 129 
 130     /*****************************************************
 131      * Standard Test Machinery Section
 132      * DO NOT modify anything in this section -- it's a
 133      * standard chunk of code which has all of the
 134      * synchronisation necessary for the test harness.
 135      * By keeping it the same in all tests, it is easier
 136      * to read and understand someone else's test, as
 137      * well as insuring that all tests behave correctly
 138      * with the test harness.
 139      * There is a section following this for test-
 140      * classes
 141      ******************************************************/
 142     private static boolean theTestPassed = false;
 143     private static boolean testGeneratedInterrupt = false;
 144     private static String failureMessage = "";
 145 
 146     private static Thread mainThread = null;
 147 
 148     private static int sleepTime = 300000;
 149 
 150     // Not sure about what happens if multiple of this test are
 151     //  instantiated in the same VM.  Being static (and using
 152     //  static vars), it aint gonna work.  Not worrying about
 153     //  it for now.
 154     public static void main( String args[] ) throws InterruptedException
 155     {
 156         mainThread = Thread.currentThread();
 157         try
 158         {
 159             init();
 160         }
 161         catch( TestPassedException e )
 162         {
 163             //The test passed, so just return from main and harness will
 164             // interepret this return as a pass
 165             return;
 166         }
 167         //At this point, neither test pass nor test fail has been
 168         // called -- either would have thrown an exception and ended the
 169         // test, so we know we have multiple threads.
 170 
 171         //Test involves other threads, so sleep and wait for them to
 172         // called pass() or fail()
 173         try
 174         {
 175             Thread.sleep( sleepTime );
 176             //Timed out, so fail the test
 177             throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
 178         }
 179         catch (InterruptedException e)
 180         {
 181             //The test harness may have interrupted the test.  If so, rethrow the exception
 182             // so that the harness gets it and deals with it.
 183             if( ! testGeneratedInterrupt ) throw e;
 184 
 185             //reset flag in case hit this code more than once for some reason (just safety)
 186             testGeneratedInterrupt = false;
 187 
 188             if ( theTestPassed == false )
 189             {
 190                 throw new RuntimeException( failureMessage );
 191             }
 192         }
 193 
 194     }//main
 195 
 196     public static synchronized void setTimeoutTo( int seconds )
 197     {
 198         sleepTime = seconds * 1000;
 199     }
 200 
 201     public static synchronized void pass()
 202     {
 203         System.out.println( "The test passed." );
 204         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 205         //first check if this is executing in main thread
 206         if ( mainThread == Thread.currentThread() )
 207         {
 208             //Still in the main thread, so set the flag just for kicks,
 209             // and throw a test passed exception which will be caught
 210             // and end the test.
 211             theTestPassed = true;
 212             throw new TestPassedException();
 213         }
 214         theTestPassed = true;
 215         testGeneratedInterrupt = true;
 216         mainThread.interrupt();
 217     }//pass()
 218 
 219     public static synchronized void fail()
 220     {
 221         //test writer didn't specify why test failed, so give generic
 222         fail( "it just plain failed! :-)" );
 223     }
 224 
 225     public static synchronized void fail( String whyFailed )
 226     {
 227         System.out.println( "The test failed: " + whyFailed );
 228         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 229         //check if this called from main thread
 230         if ( mainThread == Thread.currentThread() )
 231         {
 232             //If main thread, fail now 'cause not sleeping
 233             throw new RuntimeException( whyFailed );
 234         }
 235         theTestPassed = false;
 236         testGeneratedInterrupt = true;
 237         failureMessage = whyFailed;
 238         mainThread.interrupt();
 239     }//fail()
 240 
 241 }// class AncestorResized
 242 
 243 //This exception is used to exit from any level of call nesting
 244 // when it's determined that the test has passed, and immediately
 245 // end the test.
 246 class TestPassedException extends RuntimeException
 247 {
 248 }
 249 
 250 //*********** End Standard Test Machinery Section **********
 251 
 252 
 253 //************ Begin classes defined for the test ****************
 254 
 255 // if want to make listeners, here is the recommended place for them, then instantiate
 256 //  them in init()
 257 
 258 /* Example of a class which may be written as part of a test
 259 class NewClass implements anInterface
 260  {
 261    static int newVar = 0;
 262 
 263    public void eventDispatched(AWTEvent e)
 264     {
 265       //Counting events to see if we get enough
 266       eventCount++;
 267 
 268       if( eventCount == 20 )
 269        {
 270          //got enough events, so pass
 271 
 272          AncestorResized.pass();
 273        }
 274       else if( tries == 20 )
 275        {
 276          //tried too many times without getting enough events so fail
 277 
 278          AncestorResized.fail();
 279        }
 280 
 281     }// eventDispatched()
 282 
 283  }// NewClass class
 284 
 285 */
 286 
 287 
 288 //************** End classes defined for the test *******************