1 /* 2 * Copyright (c) 2011, 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 * @summary Utility routines that wait for a window to be displayed or for 26 colors to be visible 27 * @summary com.apple.junit.utils 28 */ 29 package test.java.awt.regtesthelpers; 30 31 import java.awt.*; 32 import java.awt.event.InputEvent; 33 import java.util.TimerTask; 34 import javax.swing.JButton; 35 36 public class RobotUtilities { 37 38 // interval between mouse down and mouse up events 39 public static final int CLICK_DELAY = 20; 40 // interval between clicks of a double click 41 public static final int DOUBLE_CLICK_DELAY = 100; 42 // allow some time for visual verification 43 public static final int POST_MOVE_DELAY = 250; 44 // allow some time for frame to draw 45 public static final int PRE_TEST_DELAY = 250; 46 // allow some time for event processing/visual verification 47 public static final int POST_TEST_DELAY = 750; 48 49 public RobotUtilities() { 50 51 } 52 53 public static void pressKey(int num) { 54 Robot robot = getRobot(); 55 robot.keyPress(num); 56 } 57 58 public static void releaseKey(int num) { 59 Robot robot = getRobot(); 60 robot.keyRelease(num); 61 } 62 63 public static void typeKey(int num) { 64 Robot robot = getRobot(); 65 robot.keyPress(num); 66 robot.delay(CLICK_DELAY); 67 robot.keyRelease(num); 68 } 69 70 static Robot _robot; 71 72 private static Robot getRobot() { 73 if (_robot == null) { 74 try { 75 _robot = new Robot(); 76 } catch (AWTException e) { 77 throw new RuntimeException(e); 78 } 79 } 80 return _robot; 81 } 82 83 //////////////////////////////////////////////////////////////////////// 84 // moveMouse - move the cusor to the specified location 85 //////////////////////////////////////////////////////////////////////// 86 public static void moveMouseTo(int posX, int posY) { 87 Robot robot = getRobot(); 88 robot.mouseMove(posX, posY); 89 robot.delay(POST_MOVE_DELAY); 90 } 91 92 //////////////////////////////////////////////////////////////////////// 93 // moveMouse - move the cusor to the specified location of the component 94 // positive values specify the offset from the top-left of the component 95 // negative values specify the offset from the bottom-right of the component 96 //////////////////////////////////////////////////////////////////////// 97 public static void moveMouseTo(Component c, int posX, int posY) { 98 Point pt; 99 int x; 100 int y; 101 102 if (c == null) { 103 return; 104 } 105 106 // Get the position of the component 107 pt = c.getLocationOnScreen(); 108 109 x = pt.x + posX; 110 if (posX < 0) { 111 x += c.getWidth(); 112 } 113 114 y = pt.y + posY; 115 if (posY < 0) { 116 y += c.getHeight(); 117 } 118 119 moveMouseTo(x, y); 120 // robot.mouseMove(x , y); 121 // robot.delay(POST_MOVE_DELAY); 122 } 123 124 ///////////////////////////////////////////////////////////////////////// 125 // moveMouse - move the cusor to the specified location of the component 126 // positive values specify the offset from the top-left of the component 127 // negative values specify the offset from the bottom-right of the component 128 ///////////////////////////////////////////////////////////////////////// 129 public static void moveMouseFromCenter(Component c, 130 int offsetX, 131 int offsetY) { 132 Point pt; 133 int x; 134 int y; 135 136 if (c == null) { 137 return; 138 } 139 140 // Get the position of the component 141 pt = c.getLocationOnScreen(); 142 143 x = pt.x + offsetX + c.getWidth() / 2; 144 145 y = pt.y + offsetY + c.getHeight() / 2; 146 147 moveMouseTo(x, y); 148 } 149 150 /////////////////////////////////////////////////////////////////////// 151 // moveMouseToCenter - move the cusor to the center of the component 152 /////////////////////////////////////////////////////////////////////// 153 public static void moveMouseToCenter(Component c) { 154 Point pt; 155 int x; 156 int y; 157 158 if (c == null) { 159 return; 160 } 161 162 // Get the position of the component 163 pt = c.getLocationOnScreen(); 164 165 x = pt.x + c.getWidth() / 2; 166 167 y = pt.y + c.getHeight() / 2; 168 169 moveMouseTo(x, y); 170 } 171 172 public static void pressMouseButton() { 173 Robot robot = getRobot(); 174 robot.mousePress(InputEvent.BUTTON1_MASK); 175 } 176 177 public static void releaseMouseButton() { 178 Robot robot = getRobot(); 179 robot.mouseRelease(InputEvent.BUTTON1_MASK); 180 } 181 182 public static void click() { 183 Robot robot = getRobot(); 184 robot.mousePress(InputEvent.BUTTON1_MASK); 185 robot.delay(CLICK_DELAY); 186 robot.mouseRelease(InputEvent.BUTTON1_MASK); 187 } 188 189 public static void click(Component c) { 190 Point pt; 191 int x; 192 int y; 193 194 if (c == null) { 195 return; 196 } 197 198 // Get the position of the component 199 pt = c.getLocationOnScreen(); 200 201 x = pt.x + c.getWidth() / 2; 202 y = pt.y + c.getHeight() / 2; 203 204 moveMouseTo(x, y); 205 206 click(); 207 } 208 209 public static void doubleClick() { 210 Robot robot = getRobot(); 211 click(); 212 robot.delay(DOUBLE_CLICK_DELAY); 213 click(); 214 } 215 216 public static void doubleClick(Component c) { 217 Point pt; 218 int x; 219 int y; 220 221 if (c == null) { 222 return; 223 } 224 225 // Get the position of the component 226 pt = c.getLocationOnScreen(); 227 228 x = pt.x + c.getWidth() / 2; 229 y = pt.y + c.getHeight() / 2; 230 231 moveMouseTo(x, y); 232 233 doubleClick(); 234 } 235 236 public static void tripleClick() { 237 Robot robot = getRobot(); 238 click(); 239 robot.delay(DOUBLE_CLICK_DELAY); 240 click(); 241 robot.delay(DOUBLE_CLICK_DELAY); 242 click(); 243 } 244 245 public static void tripleClick(Component c) { 246 Point pt; 247 int x; 248 int y; 249 250 if (c == null) { 251 return; 252 } 253 254 // Get the position of the component 255 pt = c.getLocationOnScreen(); 256 257 x = pt.x + c.getWidth() / 2; 258 y = pt.y + c.getHeight() / 2; 259 260 moveMouseTo(x, y); 261 262 tripleClick(); 263 } 264 265 /////////////////////////////////////////////////////////////////////// 266 // clickAt - click at specified point 267 /////////////////////////////////////////////////////////////////////// 268 public static void clickAt(int posX, int posY) { 269 moveMouseTo(posX, posY); 270 click(); 271 } 272 273 ///////////////////////////////////////////////////////////////////////// 274 // clickAt - click at specified point in the component 275 // positive values specify the offset from the top-left of the component 276 // negative values specify the offset from the bottom-right of the component 277 ////////////////////////////////////////////////////////////////////////// 278 public static void clickAt(Component c, int posX, int posY) { 279 moveMouseTo(c, posX, posY); 280 click(); 281 } 282 283 /////////////////////////////////////////////////////////////////////// 284 /////////////////////////////////////////////////////////////////////// 285 public static void delay(int interval) { 286 Robot robot = getRobot(); 287 robot.delay(interval); 288 } 289 290 ///////////////////////////////////////////////////////////////////////// 291 // clickAndDrag - click and drag within the component 292 // positive values specify the offset from the top-left of the component 293 // negative values specify the offset from the bottom-right of the component 294 ///////////////////////////////////////////////////////////////////////// 295 public static void clickAndDrag(Component c, 296 int startX, 297 int startY, 298 int endX, 299 int endY) { 300 Point pt; 301 int x; 302 int y; 303 304 if (c == null) { 305 return; 306 } 307 308 // Get the position of the component 309 pt = c.getLocationOnScreen(); 310 311 // Make adjustments for negative values of offset 312 x = pt.x + startX; 313 if (startX < 0) { 314 x += c.getWidth(); 315 } 316 317 y = pt.y + startY; 318 if (startY < 0) { 319 y += c.getHeight(); 320 } 321 322 moveMouseTo(x, y); 323 pressMouseButton(); 324 325 x = pt.x + endX; 326 if (endX < 0) { 327 x += c.getWidth(); 328 } 329 330 y = pt.y + endY; 331 if (endY < 0) { 332 y += c.getHeight(); 333 } 334 335 moveMouseTo(x, y); 336 releaseMouseButton(); 337 } 338 339 /////////////////////////////////////////////////////////////////////// 340 // screenshot - take a screenshot and save to disk as a jpg 341 // basename - base name of the file. the file will be named 342 // <basename>.<timestamp>.jpg 343 // location - parent directory. If null, uses the current working directory. 344 // return value - the File for the newly created image. 345 // failure cases - if the basename is null, the file already exists, or 346 // location isn't a directory, returns null. 347 /////////////////////////////////////////////////////////////////////// 348 public static java.io.File screenshot(String basename, 349 java.io.File location) 350 throws java.io.IOException, java.awt.AWTException { 351 if (basename == null) { 352 return null; 353 } 354 if (location != null) { 355 if (!location.exists() || !location.isDirectory()) { 356 return null; 357 } 358 } 359 360 Robot robot = getRobot(); 361 java.awt.image.BufferedImage screenshot = robot.createScreenCapture( 362 new java.awt.Rectangle( 363 java.awt.Toolkit.getDefaultToolkit().getScreenSize())); 364 365 java.util.GregorianCalendar calendar = new java.util.GregorianCalendar(); 366 StringBuffer sb = new StringBuffer(); 367 sb.append(basename); 368 sb.append("."); 369 sb.append(calendar.get(java.util.Calendar.YEAR)); 370 sb.append(calendar.get(java.util.Calendar.MONTH)); 371 sb.append(calendar.get(java.util.Calendar.DAY_OF_MONTH)); 372 sb.append(calendar.get(java.util.Calendar.HOUR_OF_DAY)); 373 sb.append(calendar.get(java.util.Calendar.MINUTE)); 374 sb.append(".png"); 375 376 java.io.File outputFile = new java.io.File(location, sb.toString()); 377 javax.imageio.ImageIO.write(screenshot, "png", outputFile); 378 379 return outputFile; 380 } 381 382 /* 383 * Utility function to walk the container heirarchy looking for a JButton 384 * matching a specific text string. For example, this is used to extract 385 * the "Cancel" button from a JDialog. 386 */ 387 public static JButton extractJButton(Container parent, String text) { 388 JButton cancel = null; 389 Component[] c = parent.getComponents(); 390 for (int i = 0; i < c.length; i += 1) { 391 if (c[i] instanceof JButton) { 392 JButton b = (JButton) c[i]; 393 if (b.getText().equals(text)) { 394 cancel = (JButton) c[i]; 395 break; 396 } 397 } else if (c[i] instanceof Container) { 398 cancel = extractJButton((Container) c[i], text); 399 } 400 } 401 return cancel; 402 } 403 404 /* 405 * Utility class that takes a JButton and, later on, clicks it 406 */ 407 public static class Clicker extends TimerTask { 408 409 JButton target = null; 410 private Exception cachedException; 411 412 // We need to know what to click 413 public Clicker(JButton target) { 414 super(); 415 this.target = target; 416 } 417 418 // This does the clicking 419 public void run() { 420 try { 421 Robot r = new Robot(); 422 Point pt = target.getLocationOnScreen(); 423 int x = pt.x + target.getWidth() / 2; 424 int y = pt.y + target.getHeight() / 2; 425 r.mouseMove(x, y); 426 r.delay(30); 427 r.mousePress(InputEvent.BUTTON1_MASK); 428 r.delay(101); 429 r.mouseRelease(InputEvent.BUTTON1_MASK); 430 } catch (Exception x) { 431 setCachedException(x); 432 } 433 } 434 435 void setCachedException(Exception cachedException) { 436 this.cachedException = cachedException; 437 } 438 439 public Exception getCachedException() { 440 return cachedException; 441 } 442 } 443 }