1 /*
   2  * Copyright (c) 2005, 2014, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27   @test
  28   @bug 5025858
  29   @summary Tests that after programmatically moving or resizing a component,
  30 corresponding ComponentEvents are generated only once
  31   @author artem.ananiev: area=awt.event
  32   @run main/manual MovedResizedTwiceTest
  33 */
  34 
  35 import java.awt.*;
  36 import java.awt.event.*;
  37 
  38 /*
  39   IMPORTANT: this test is made manual as some window managers may generate
  40   strange events and that would lead to the test to fail. However, on most
  41   popular platforms (windows, linux w/ KDE or GNOME, solaris w/ CDE or
  42   GNOME) it usually passes successfully.
  43 */
  44 
  45 public class MovedResizedTwiceTest
  46 {
  47     private static volatile int componentMovedCount;
  48     private static volatile int componentResizedCount;
  49 
  50     private static volatile int rightX, rightY;
  51 
  52     private static volatile boolean failed = false;
  53 
  54     private static void init()
  55     {
  56         componentMovedCount = componentResizedCount = 0;
  57 
  58         Robot robot;
  59         try {
  60             robot = new Robot();
  61         }catch(Exception ex) {
  62             ex.printStackTrace();
  63             throw new RuntimeException("Cannot create Robot: failure");
  64         }
  65 
  66         Frame f = new Frame("Frame F");
  67         f.setLayout(null);
  68         f.setBounds(100, 100, 100, 100);
  69         f.add(new Button("Button"));
  70 
  71         f.setVisible(true);
  72         robot.waitForIdle();
  73 
  74         ComponentListener cl = new ComponentAdapter()
  75         {
  76             public void componentMoved(ComponentEvent e)
  77             {
  78                 componentMovedCount++;
  79                 Component c = (Component)e.getSource();
  80                 if (!(c instanceof Window))
  81                 {
  82                     return;
  83                 }
  84                 Point p = c.getLocationOnScreen();
  85                 if ((p.x != rightX) || (p.y != rightY))
  86                 {
  87                     System.err.println("Error: wrong location on screen after COMPONENT_MOVED");
  88                     System.err.println("Location on screen is (" + p.x + ", " + p.y + ") against right location (" + rightX + ", " + rightY + ")");
  89                     failed = true;
  90                 }
  91             }
  92             public void componentResized(ComponentEvent e)
  93             {
  94                 componentResizedCount++;
  95             }
  96         };
  97 
  98         f.addComponentListener(cl);
  99 
 100         componentResizedCount = componentMovedCount = 0;
 101         rightX = 100;
 102         rightY = 100;
 103         f.setSize(200, 200);
 104         robot.waitForIdle();
 105         checkResized("setSize", f);
 106 
 107         componentResizedCount = componentMovedCount = 0;
 108         rightX = 200;
 109         rightY = 200;
 110         f.setLocation(200, 200);
 111         robot.waitForIdle();
 112         checkMoved("setLocation", f);
 113 
 114         componentResizedCount = componentMovedCount = 0;
 115         rightX = 150;
 116         rightY = 150;
 117         f.setBounds(150, 150, 100, 100);
 118         robot.waitForIdle();
 119         checkResized("setBounds", f);
 120         checkMoved("setBounds", f);
 121 
 122         Button b = new Button("B");
 123         b.setBounds(10, 10, 40, 40);
 124         f.add(b);
 125         robot.waitForIdle();
 126 
 127         b.addComponentListener(cl);
 128 
 129         componentResizedCount = componentMovedCount = 0;
 130         b.setBounds(20, 20, 50, 50);
 131         robot.waitForIdle();
 132         checkMoved("setBounds", b);
 133         checkResized("setBounds", b);
 134         f.remove(b);
 135 
 136         Component c = new Component() {};
 137         c.setBounds(10, 10, 40, 40);
 138         f.add(c);
 139         robot.waitForIdle();
 140 
 141         c.addComponentListener(cl);
 142 
 143         componentResizedCount = componentMovedCount = 0;
 144         c.setBounds(20, 20, 50, 50);
 145         robot.waitForIdle();
 146         checkMoved("setBounds", c);
 147         checkResized("setBounds", c);
 148         f.remove(c);
 149 
 150         if (failed)
 151         {
 152             MovedResizedTwiceTest.fail("Test FAILED");
 153         }
 154         else
 155         {
 156             MovedResizedTwiceTest.pass();
 157         }
 158     }
 159 
 160     private static void checkResized(String methodName, Component c)
 161     {
 162         String failMessage = null;
 163         if (componentResizedCount == 1)
 164         {
 165             return;
 166         }
 167         else if (componentResizedCount == 0)
 168         {
 169             failMessage = "Test FAILED: COMPONENT_RESIZED is not sent after call to " + methodName + "()";
 170         }
 171         else
 172         {
 173             failMessage = "Test FAILED: COMPONENT_RESIZED is sent " + componentResizedCount + " + times after call to " + methodName + "()";
 174         }
 175         System.err.println("Failed component: " + c);
 176         MovedResizedTwiceTest.fail(failMessage);
 177     }
 178 
 179     private static void checkMoved(String methodName, Component c)
 180     {
 181         String failMessage = null;
 182         if (componentMovedCount == 1)
 183         {
 184             return;
 185         }
 186         if (componentMovedCount == 0)
 187         {
 188             failMessage = "Test FAILED: COMPONENT_MOVED is not sent after call to " + methodName + "()";
 189         }
 190         else
 191         {
 192             failMessage = "Test FAILED: COMPONENT_MOVED is sent " + componentMovedCount + " times after call to " + methodName + "()";
 193         }
 194         System.err.println("Failed component: " + c);
 195         MovedResizedTwiceTest.fail(failMessage);
 196     }
 197 
 198     private static boolean theTestPassed = false;
 199     private static boolean testGeneratedInterrupt = false;
 200     private static String failureMessage = "";
 201 
 202     private static Thread mainThread = null;
 203 
 204     private static int sleepTime = 300000;
 205 
 206     public static void main( String args[] ) throws InterruptedException
 207     {
 208         mainThread = Thread.currentThread();
 209         try
 210         {
 211             init();
 212         }
 213         catch (TestPassedException e)
 214         {
 215             return;
 216         }
 217 
 218         try
 219         {
 220             Thread.sleep(sleepTime);
 221             throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
 222         }
 223         catch (InterruptedException e)
 224         {
 225             if (!testGeneratedInterrupt)
 226             {
 227                 throw e;
 228             }
 229 
 230             testGeneratedInterrupt = false;
 231 
 232             if (!theTestPassed)
 233             {
 234                 throw new RuntimeException( failureMessage );
 235             }
 236         }
 237     }
 238 
 239     public static synchronized void setTimeoutTo(int seconds)
 240     {
 241         sleepTime = seconds * 1000;
 242     }
 243 
 244     public static synchronized void pass()
 245     {
 246         if (mainThread == Thread.currentThread())
 247         {
 248             theTestPassed = true;
 249             throw new TestPassedException();
 250         }
 251         theTestPassed = true;
 252         testGeneratedInterrupt = true;
 253         mainThread.interrupt();
 254     }
 255 
 256     public static synchronized void fail()
 257     {
 258         fail("it just plain failed! :-)");
 259     }
 260 
 261     public static synchronized void fail(String whyFailed)
 262     {
 263         if (mainThread == Thread.currentThread())
 264         {
 265             throw new RuntimeException(whyFailed);
 266         }
 267         theTestPassed = false;
 268         testGeneratedInterrupt = true;
 269         failureMessage = whyFailed;
 270         mainThread.interrupt();
 271     }
 272 }
 273 
 274 class TestPassedException extends RuntimeException
 275 {
 276 }