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