1 /* 2 * Copyright (c) 2005, 2019, 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 @key headful 29 @bug 5025858 8144125 30 @summary Tests that after programmatically moving or resizing a component, 31 corresponding ComponentEvents are generated only once 32 */ 33 34 import java.awt.Button; 35 import java.awt.Component; 36 import java.awt.Frame; 37 import java.awt.Point; 38 import java.awt.Robot; 39 import java.awt.Window; 40 import java.awt.event.ComponentAdapter; 41 import java.awt.event.ComponentEvent; 42 import java.awt.event.ComponentListener; 43 44 /* 45 IMPORTANT: this test can fail because some window managers may generate 46 strange events and that would lead to the test to fail. However, on most 47 popular platforms (windows, linux w/ KDE or GNOME, solaris w/ CDE or 48 GNOME) it usually passes successfully. 49 */ 50 51 public class MovedResizedTwiceTest 52 { 53 private static volatile int componentMovedCount; 54 private static volatile int componentResizedCount; 55 56 private static volatile int rightX, rightY; 57 58 private static volatile boolean failed = false; 59 init()60 private static void init() 61 { 62 componentMovedCount = componentResizedCount = 0; 63 64 Robot robot; 65 try { 66 robot = new Robot(); 67 }catch(Exception ex) { 68 ex.printStackTrace(); 69 throw new RuntimeException("Cannot create Robot: failure"); 70 } 71 72 Frame f = new Frame("Frame F"); 73 f.setLayout(null); 74 f.setBounds(100, 100, 100, 100); 75 f.add(new Button("Button")); 76 77 f.setVisible(true); 78 robot.waitForIdle(); 79 80 ComponentListener cl = new ComponentAdapter() 81 { 82 public void componentMoved(ComponentEvent e) 83 { 84 componentMovedCount++; 85 Component c = (Component)e.getSource(); 86 if (!(c instanceof Window)) 87 { 88 return; 89 } 90 Point p = c.getLocationOnScreen(); 91 if ((p.x != rightX) || (p.y != rightY)) 92 { 93 System.err.println("Error: wrong location on screen after COMPONENT_MOVED"); 94 System.err.println("Location on screen is (" + p.x + ", " + p.y + ") against right location (" + rightX + ", " + rightY + ")"); 95 failed = true; 96 } 97 } 98 public void componentResized(ComponentEvent e) 99 { 100 componentResizedCount++; 101 } 102 }; 103 104 f.addComponentListener(cl); 105 106 componentResizedCount = componentMovedCount = 0; 107 rightX = 100; 108 rightY = 100; 109 f.setSize(200, 200); 110 robot.waitForIdle(); 111 checkResized("setSize", f); 112 113 componentResizedCount = componentMovedCount = 0; 114 rightX = 200; 115 rightY = 200; 116 f.setLocation(200, 200); 117 robot.waitForIdle(); 118 checkMoved("setLocation", f); 119 120 componentResizedCount = componentMovedCount = 0; 121 rightX = 150; 122 rightY = 150; 123 f.setBounds(150, 150, 100, 100); 124 robot.waitForIdle(); 125 checkResized("setBounds", f); 126 checkMoved("setBounds", f); 127 128 Button b = new Button("B"); 129 b.setBounds(10, 10, 40, 40); 130 f.add(b); 131 robot.waitForIdle(); 132 133 b.addComponentListener(cl); 134 135 componentResizedCount = componentMovedCount = 0; 136 b.setBounds(20, 20, 50, 50); 137 robot.waitForIdle(); 138 checkMoved("setBounds", b); 139 checkResized("setBounds", b); 140 f.remove(b); 141 142 Component c = new Component() {}; 143 c.setBounds(10, 10, 40, 40); 144 f.add(c); 145 robot.waitForIdle(); 146 147 c.addComponentListener(cl); 148 149 componentResizedCount = componentMovedCount = 0; 150 c.setBounds(20, 20, 50, 50); 151 robot.waitForIdle(); 152 checkMoved("setBounds", c); 153 checkResized("setBounds", c); 154 f.remove(c); 155 156 if (failed) 157 { 158 MovedResizedTwiceTest.fail("Test FAILED"); 159 } 160 else 161 { 162 MovedResizedTwiceTest.pass(); 163 } 164 } 165 checkResized(String methodName, Component c)166 private static void checkResized(String methodName, Component c) 167 { 168 String failMessage = null; 169 if (componentResizedCount == 1) 170 { 171 return; 172 } 173 else if (componentResizedCount == 0) 174 { 175 failMessage = "Test FAILED: COMPONENT_RESIZED is not sent after call to " + methodName + "()"; 176 } 177 else 178 { 179 failMessage = "Test FAILED: COMPONENT_RESIZED is sent " + componentResizedCount + " + times after call to " + methodName + "()"; 180 } 181 System.err.println("Failed component: " + c); 182 MovedResizedTwiceTest.fail(failMessage); 183 } 184 checkMoved(String methodName, Component c)185 private static void checkMoved(String methodName, Component c) 186 { 187 String failMessage = null; 188 if (componentMovedCount == 1) 189 { 190 return; 191 } 192 if (componentMovedCount == 0) 193 { 194 failMessage = "Test FAILED: COMPONENT_MOVED is not sent after call to " + methodName + "()"; 195 } 196 else 197 { 198 failMessage = "Test FAILED: COMPONENT_MOVED is sent " + componentMovedCount + " times after call to " + methodName + "()"; 199 } 200 System.err.println("Failed component: " + c); 201 MovedResizedTwiceTest.fail(failMessage); 202 } 203 204 private static boolean theTestPassed = false; 205 private static boolean testGeneratedInterrupt = false; 206 private static String failureMessage = ""; 207 208 private static Thread mainThread = null; 209 210 private static int sleepTime = 300000; 211 main( String args[] )212 public static void main( String args[] ) throws InterruptedException 213 { 214 mainThread = Thread.currentThread(); 215 try 216 { 217 init(); 218 } 219 catch (TestPassedException e) 220 { 221 return; 222 } 223 224 try 225 { 226 Thread.sleep(sleepTime); 227 throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" ); 228 } 229 catch (InterruptedException e) 230 { 231 if (!testGeneratedInterrupt) 232 { 233 throw e; 234 } 235 236 testGeneratedInterrupt = false; 237 238 if (!theTestPassed) 239 { 240 throw new RuntimeException( failureMessage ); 241 } 242 } 243 } 244 setTimeoutTo(int seconds)245 public static synchronized void setTimeoutTo(int seconds) 246 { 247 sleepTime = seconds * 1000; 248 } 249 pass()250 public static synchronized void pass() 251 { 252 if (mainThread == Thread.currentThread()) 253 { 254 theTestPassed = true; 255 throw new TestPassedException(); 256 } 257 theTestPassed = true; 258 testGeneratedInterrupt = true; 259 mainThread.interrupt(); 260 } 261 fail()262 public static synchronized void fail() 263 { 264 fail("it just plain failed! :-)"); 265 } 266 fail(String whyFailed)267 public static synchronized void fail(String whyFailed) 268 { 269 if (mainThread == Thread.currentThread()) 270 { 271 throw new RuntimeException(whyFailed); 272 } 273 theTestPassed = false; 274 testGeneratedInterrupt = true; 275 failureMessage = whyFailed; 276 mainThread.interrupt(); 277 } 278 } 279 280 class TestPassedException extends RuntimeException 281 { 282 } 283