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 
init()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 
checkResized(String methodName, Component c)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 
checkMoved(String methodName, Component c)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 
main( String args[] )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 
setTimeoutTo(int seconds)239     public static synchronized void setTimeoutTo(int seconds)
240     {
241         sleepTime = seconds * 1000;
242     }
243 
pass()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 
fail()256     public static synchronized void fail()
257     {
258         fail("it just plain failed! :-)");
259     }
260 
fail(String whyFailed)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 }
277