1/* 2 * Copyright (c) 1997, 2016, 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 */ 23package org.netbeans.jemmy.operators; 24 25import java.awt.Component; 26import java.awt.Window; 27import java.awt.event.WindowListener; 28import java.lang.reflect.InvocationTargetException; 29import java.util.ResourceBundle; 30 31import org.netbeans.jemmy.ClassReference; 32import org.netbeans.jemmy.ComponentChooser; 33import org.netbeans.jemmy.ComponentSearcher; 34import org.netbeans.jemmy.JemmyException; 35import org.netbeans.jemmy.JemmyProperties; 36import org.netbeans.jemmy.Outputable; 37import org.netbeans.jemmy.TestOut; 38import org.netbeans.jemmy.TimeoutExpiredException; 39import org.netbeans.jemmy.Timeouts; 40import org.netbeans.jemmy.WindowWaiter; 41import org.netbeans.jemmy.drivers.DriverManager; 42import org.netbeans.jemmy.drivers.WindowDriver; 43 44/** 45 * <BR><BR>Timeouts used: <BR> 46 * WindowWaiter.WaitWindowTimeout - time to wait window displayed <BR> 47 * WindowWaiter.AfterWindowTimeout - time to sleep after window has been 48 * dispayed <BR>. 49 * 50 * @see org.netbeans.jemmy.Timeouts 51 * 52 * @author Alexandre Iline (alexandre.iline@oracle.com) 53 * 54 */ 55public class WindowOperator extends ContainerOperator<Window> 56 implements Outputable { 57 58 TestOut output; 59 WindowDriver driver; 60 61 /** 62 * Constructor. 63 * 64 * @param w a component 65 */ 66 public WindowOperator(Window w) { 67 super(w); 68 driver = DriverManager.getWindowDriver(getClass()); 69 } 70 71 /** 72 * Constructs a DialogOperator object. 73 * 74 * @param owner window - owner 75 * @param chooser a component chooser specifying searching criteria. 76 * @param index an index between appropriate ones. 77 */ 78 public WindowOperator(WindowOperator owner, ComponentChooser chooser, int index) { 79 this(owner. 80 waitSubWindow(chooser, 81 index)); 82 copyEnvironment(owner); 83 } 84 85 /** 86 * Constructs a DialogOperator object. 87 * 88 * @param owner window - owner 89 * @param chooser a component chooser specifying searching criteria. 90 */ 91 public WindowOperator(WindowOperator owner, ComponentChooser chooser) { 92 this(owner, chooser, 0); 93 } 94 95 /** 96 * Constructor. Waits for the index'th displayed owner's child. Uses owner's 97 * timeout and output for waiting and to init operator. 98 * 99 * @param owner Operator pointing on a window owner. 100 * @param index an index between appropriate ones. 101 * @throws TimeoutExpiredException 102 */ 103 public WindowOperator(WindowOperator owner, int index) { 104 this(waitWindow(owner, 105 ComponentSearcher.getTrueChooser("Any Window"), 106 index)); 107 copyEnvironment(owner); 108 } 109 110 /** 111 * Constructor. Waits for the first displayed owner's child. Uses owner's 112 * timeout and output for waiting and to init operator. 113 * 114 * @param owner Operator pointing on a window owner. 115 * @throws TimeoutExpiredException 116 */ 117 public WindowOperator(WindowOperator owner) { 118 this(owner, 0); 119 } 120 121 /** 122 * Constructor. Waits for the index'th displayed window. Constructor can be 123 * used in complicated cases when output or timeouts should differ from 124 * default. 125 * 126 * @param index an index between appropriate ones. 127 * @param env an operator to copy environment from. 128 * @throws TimeoutExpiredException 129 */ 130 public WindowOperator(int index, Operator env) { 131 this(waitWindow(ComponentSearcher.getTrueChooser("Any Window"), 132 index, env.getTimeouts(), env.getOutput())); 133 copyEnvironment(env); 134 } 135 136 /** 137 * Constructor. Waits for the index'th displayed window. Uses current 138 * timeouts and output values. 139 * 140 * @see JemmyProperties#getCurrentTimeouts() 141 * @see JemmyProperties#getCurrentOutput() 142 * @param index an index between appropriate ones. 143 * @throws TimeoutExpiredException 144 */ 145 public WindowOperator(int index) { 146 this(index, 147 getEnvironmentOperator()); 148 } 149 150 /** 151 * Constructor. Waits for the first displayed window. Uses current timeouts 152 * and output values. 153 * 154 * @see JemmyProperties#getCurrentTimeouts() 155 * @see JemmyProperties#getCurrentOutput() 156 * @throws TimeoutExpiredException 157 */ 158 public WindowOperator() { 159 this(0); 160 } 161 162 /** 163 * Searches an index'th window. 164 * 165 * @param chooser a component chooser specifying searching criteria. 166 * @param index an index between appropriate ones. 167 * @return a window 168 */ 169 public static Window findWindow(ComponentChooser chooser, int index) { 170 return WindowWaiter.getWindow(chooser, index); 171 } 172 173 /** 174 * Searches a window. 175 * 176 * @param chooser a component chooser specifying searching criteria. 177 * @return a window 178 */ 179 public static Window findWindow(ComponentChooser chooser) { 180 return findWindow(chooser, 0); 181 } 182 183 /** 184 * Searches an index'th window. 185 * 186 * @param owner Window - owner. 187 * @param chooser a component chooser specifying searching criteria. 188 * @param index an index between appropriate ones. 189 * @return a window 190 */ 191 public static Window findWindow(Window owner, ComponentChooser chooser, int index) { 192 return WindowWaiter.getWindow(owner, chooser, index); 193 } 194 195 /** 196 * Searches a window. 197 * 198 * @param owner Window - owner. 199 * @param chooser a component chooser specifying searching criteria. 200 * @return a window 201 */ 202 public static Window findWindow(Window owner, ComponentChooser chooser) { 203 return findWindow(owner, chooser, 0); 204 } 205 206 /** 207 * Waits an index'th window. 208 * 209 * @param chooser a component chooser specifying searching criteria. 210 * @param index an index between appropriate ones. 211 * @throws TimeoutExpiredException 212 * @return a window 213 */ 214 public static Window waitWindow(ComponentChooser chooser, int index) { 215 return (waitWindow(chooser, index, 216 JemmyProperties.getCurrentTimeouts(), 217 JemmyProperties.getCurrentOutput())); 218 } 219 220 /** 221 * Waits a window. 222 * 223 * @param chooser a component chooser specifying searching criteria. 224 * @throws TimeoutExpiredException 225 * @return a window 226 */ 227 public static Window waitWindow(ComponentChooser chooser) { 228 return waitWindow(chooser, 0); 229 } 230 231 /** 232 * Waits an index'th window. 233 * 234 * @param owner Window - owner. 235 * @param chooser a component chooser specifying searching criteria. 236 * @param index an index between appropriate ones. 237 * @throws TimeoutExpiredException 238 * @return a window 239 */ 240 public static Window waitWindow(Window owner, ComponentChooser chooser, int index) { 241 return (waitWindow(owner, chooser, index, 242 JemmyProperties.getCurrentTimeouts(), 243 JemmyProperties.getCurrentOutput())); 244 } 245 246 /** 247 * Waits a window. 248 * 249 * @param owner Window - owner. 250 * @param chooser a component chooser specifying searching criteria. 251 * @throws TimeoutExpiredException 252 * @return a window 253 */ 254 public static Window waitWindow(Window owner, ComponentChooser chooser) { 255 return waitWindow(owner, chooser, 0); 256 } 257 258 @Override 259 public void setOutput(TestOut out) { 260 super.setOutput(out); 261 output = out; 262 } 263 264 @Override 265 public TestOut getOutput() { 266 return output; 267 } 268 269 @Override 270 public void copyEnvironment(Operator anotherOperator) { 271 super.copyEnvironment(anotherOperator); 272 driver 273 = (WindowDriver) DriverManager. 274 getDriver(DriverManager.WINDOW_DRIVER_ID, 275 getClass(), 276 anotherOperator.getProperties()); 277 } 278 279 /** 280 * Activates the window. Uses WindowDriver registered for the operator type. 281 */ 282 public void activate() { 283 output.printLine("Activate window\n " + getSource().toString()); 284 output.printGolden("Activate window"); 285 driver.activate(this); 286 } 287 288 /** 289 * Requests the window to close. Uses WindowDriver registered for the 290 * operator type. 291 */ 292 public void requestClose() { 293 output.printLine("Requesting close of window\n " + getSource().toString()); 294 output.printGolden("Requesting close of window"); 295 driver.requestClose(this); 296 } 297 298 /** 299 * Closes a window by requesting it to close and then hiding it. Not 300 * implemented for internal frames at the moment. Uses WindowDriver 301 * registered for the operator type. 302 * 303 * @see #requestClose() 304 */ 305 public void requestCloseAndThenHide() { 306 output.printLine("Closing window\n " + getSource().toString()); 307 output.printGolden("Closing window"); 308 driver.requestCloseAndThenHide(this); 309 if (getVerification()) { 310 waitClosed(); 311 } 312 } 313 314 /** 315 * Closes a window by requesting it to close and then, if it's a top-level 316 * frame, hiding it. Uses WindowDriver registered for the operator type. 317 * 318 * @deprecated Use requestClose(). It is the target window's responsibility 319 * to hide itself if needed. Or, if you really have to, use 320 * requestCloseAndThenHide(). 321 * @see #requestClose() 322 * @see #requestCloseAndThenHide() 323 */ 324 @Deprecated 325 public void close() { 326 output.printLine("Closing window\n " + getSource().toString()); 327 output.printGolden("Closing window"); 328 driver.close(this); 329 if (getVerification()) { 330 waitClosed(); 331 } 332 } 333 334 /** 335 * Moves the window to another location. Uses WindowDriver registered for 336 * the operator type. 337 * 338 * @param x coordinate in screen coordinate system 339 * @param y coordinate in screen coordinate system 340 */ 341 public void move(int x, int y) { 342 output.printLine("Moving frame\n " + getSource().toString()); 343 output.printGolden("Moving frame"); 344 driver.move(this, x, y); 345 } 346 347 /** 348 * Resizes the window. Uses WindowDriver registered for the operator type. 349 * 350 * @param width new width 351 * @param height new height 352 */ 353 public void resize(int width, int height) { 354 output.printLine("Resizing frame\n " + getSource().toString()); 355 output.printGolden("Resizing frame"); 356 driver.resize(this, width, height); 357 } 358 359 /** 360 * Searches an index'th window between windows owned by this window. 361 * 362 * @param chooser a component chooser specifying searching criteria. 363 * @param index an index between appropriate ones. 364 * @return a subwindow 365 */ 366 public Window findSubWindow(ComponentChooser chooser, int index) { 367 getOutput().printLine("Looking for \"" + chooser.getDescription() 368 + "\" subwindow"); 369 return findWindow((Window) getSource(), chooser, index); 370 } 371 372 /** 373 * Searches a window between windows owned by this window. 374 * 375 * @param chooser a component chooser specifying searching criteria. 376 * @return a subwindow 377 */ 378 public Window findSubWindow(ComponentChooser chooser) { 379 return findSubWindow(chooser, 0); 380 } 381 382 /** 383 * Waits an index'th window between windows owned by this window. 384 * 385 * @param chooser a component chooser specifying searching criteria. 386 * @param index an index between appropriate ones. 387 * @return a subwindow 388 */ 389 public Window waitSubWindow(ComponentChooser chooser, int index) { 390 getOutput().printLine("Waiting for \"" + chooser.getDescription() 391 + "\" subwindow"); 392 WindowWaiter ww = new WindowWaiter(); 393 ww.setOutput(getOutput()); 394 ww.setTimeouts(getTimeouts()); 395 try { 396 return ww.waitWindow((Window) getSource(), chooser, index); 397 } catch (InterruptedException e) { 398 throw (new JemmyException("Waiting for \"" + chooser.getDescription() 399 + "\" window has been interrupted", e)); 400 } 401 } 402 403 /** 404 * Waits a window between windows owned by this window. 405 * 406 * @param chooser a component chooser specifying searching criteria. 407 * @return a subwindow 408 */ 409 public Window waitSubWindow(ComponentChooser chooser) { 410 return waitSubWindow(chooser, 0); 411 } 412 413 /** 414 * Waits the window to be closed. 415 */ 416 public void waitClosed() { 417 getOutput().printLine("Wait window to be closed \n : " 418 + getSource().toString()); 419 getOutput().printGolden("Wait window to be closed"); 420 waitState(new ComponentChooser() { 421 @Override 422 public boolean checkComponent(Component comp) { 423 return !comp.isVisible(); 424 } 425 426 @Override 427 public String getDescription() { 428 return "Closed window"; 429 } 430 431 @Override 432 public String toString() { 433 return "WindowOperator.waitClosed.Action{description = " + getDescription() + '}'; 434 } 435 }); 436 } 437 438 //////////////////////////////////////////////////////// 439 //Mapping // 440 /** 441 * Maps {@code Window.addWindowListener(WindowListener)} through queue 442 */ 443 public void addWindowListener(final WindowListener windowListener) { 444 runMapping(new MapVoidAction("addWindowListener") { 445 @Override 446 public void map() { 447 ((Window) getSource()).addWindowListener(windowListener); 448 } 449 }); 450 } 451 452 /** 453 * Maps {@code Window.applyResourceBundle(String)} through queue 454 */ 455 @Deprecated 456 public void applyResourceBundle(final String string) { 457 runMapping(new MapVoidAction("applyResourceBundle") { 458 @Override 459 public void map() { 460 ((Window) getSource()).applyResourceBundle(string); 461 } 462 }); 463 } 464 465 /** 466 * Maps {@code Window.applyResourceBundle(ResourceBundle)} through queue 467 */ 468 @Deprecated 469 public void applyResourceBundle(final ResourceBundle resourceBundle) { 470 runMapping(new MapVoidAction("applyResourceBundle") { 471 @Override 472 public void map() { 473 ((Window) getSource()).applyResourceBundle(resourceBundle); 474 } 475 }); 476 } 477 478 /** 479 * Maps {@code Window.dispose()} through queue 480 */ 481 public void dispose() { 482 runMapping(new MapVoidAction("dispose") { 483 @Override 484 public void map() { 485 ((Window) getSource()).dispose(); 486 } 487 }); 488 } 489 490 /** 491 * Maps {@code Window.getFocusOwner()} through queue 492 */ 493 public Component getFocusOwner() { 494 return (runMapping(new MapAction<Component>("getFocusOwner") { 495 @Override 496 public Component map() { 497 return ((Window) getSource()).getFocusOwner(); 498 } 499 })); 500 } 501 502 /** 503 * Maps {@code Window.getOwnedWindows()} through queue 504 */ 505 public Window[] getOwnedWindows() { 506 return ((Window[]) runMapping(new MapAction<Object>("getOwnedWindows") { 507 @Override 508 public Object map() { 509 return ((Window) getSource()).getOwnedWindows(); 510 } 511 })); 512 } 513 514 /** 515 * Maps {@code Window.getOwner()} through queue 516 */ 517 public Window getOwner() { 518 return (runMapping(new MapAction<Window>("getOwner") { 519 @Override 520 public Window map() { 521 return ((Window) getSource()).getOwner(); 522 } 523 })); 524 } 525 526 /** 527 * Maps {@code Window.getWarningString()} through queue 528 */ 529 public String getWarningString() { 530 return (runMapping(new MapAction<String>("getWarningString") { 531 @Override 532 public String map() { 533 return ((Window) getSource()).getWarningString(); 534 } 535 })); 536 } 537 538 /** 539 * Maps {@code Window.pack()} through queue 540 */ 541 public void pack() { 542 runMapping(new MapVoidAction("pack") { 543 @Override 544 public void map() { 545 ((Window) getSource()).pack(); 546 } 547 }); 548 } 549 550 /** 551 * Maps {@code Window.removeWindowListener(WindowListener)} through queue 552 */ 553 public void removeWindowListener(final WindowListener windowListener) { 554 runMapping(new MapVoidAction("removeWindowListener") { 555 @Override 556 public void map() { 557 ((Window) getSource()).removeWindowListener(windowListener); 558 } 559 }); 560 } 561 562 /** 563 * Maps {@code Window.toBack()} through queue 564 */ 565 public void toBack() { 566 runMapping(new MapVoidAction("toBack") { 567 @Override 568 public void map() { 569 ((Window) getSource()).toBack(); 570 } 571 }); 572 } 573 574 /** 575 * Maps {@code Window.toFront()} through queue 576 */ 577 public void toFront() { 578 runMapping(new MapVoidAction("toFront") { 579 @Override 580 public void map() { 581 ((Window) getSource()).toFront(); 582 } 583 }); 584 } 585 586 //End of mapping // 587 //////////////////////////////////////////////////////// 588 //////////////////////////////////////////////////////// 589 //Mapping 1.4 // 590 /** 591 * Maps {@code Window.isFocused()} through queue. 592 * 593 * @return result of the mapped method 594 */ 595 public boolean isFocused() { 596 if (System.getProperty("java.specification.version").compareTo("1.3") > 0) { 597 return (runMapping(new MapBooleanAction("isFocused") { 598 @Override 599 public boolean map() { 600 try { 601 return (((Boolean) new ClassReference(getSource()). 602 invokeMethod("isFocused", null, null)).booleanValue()); 603 } catch (InvocationTargetException e) { 604 return false; 605 } catch (NoSuchMethodException e) { 606 return false; 607 } catch (IllegalAccessException e) { 608 return false; 609 } 610 } 611 })); 612 } else { 613 return getFocusOwner() != null; 614 } 615 } 616 617 /** 618 * Maps {@code Window.isActive()} through queue. 619 * 620 * @return result of the mapped method 621 */ 622 public boolean isActive() { 623 if (System.getProperty("java.specification.version").compareTo("1.3") > 0) { 624 return (runMapping(new MapBooleanAction("isActive") { 625 @Override 626 public boolean map() { 627 try { 628 return (((Boolean) new ClassReference(getSource()). 629 invokeMethod("isActive", null, null)).booleanValue()); 630 } catch (InvocationTargetException e) { 631 return false; 632 } catch (NoSuchMethodException e) { 633 return false; 634 } catch (IllegalAccessException e) { 635 return false; 636 } 637 } 638 })); 639 } else { 640 return isShowing(); 641 } 642 } 643 644 //End of mapping 1.4 // 645 //////////////////////////////////////////////////////// 646 /** 647 * A method to be used from subclasses. Uses timeouts and output passed as 648 * parameters during the waiting. 649 * 650 * @param chooser org.netbeans.jemmy.ComponentChooser implementation. 651 * @param index Ordinal component index. 652 * @param timeouts timeouts to be used during the waiting. 653 * @param output an output to be used during the waiting. 654 * @return Component instance or null if component was not found. 655 */ 656 protected static Window waitWindow(ComponentChooser chooser, int index, 657 Timeouts timeouts, TestOut output) { 658 try { 659 WindowWaiter waiter = new WindowWaiter(); 660 waiter.setTimeouts(timeouts); 661 waiter.setOutput(output); 662 return waiter.waitWindow(chooser, index); 663 } catch (InterruptedException e) { 664 output.printStackTrace(e); 665 return null; 666 } 667 } 668 669 /** 670 * A method to be used from subclasses. Uses {@code owner}'s timeouts 671 * and output during the waiting. 672 * 673 * @param owner a window - dialog owner. 674 * @param chooser org.netbeans.jemmy.ComponentChooser implementation. 675 * @param index Ordinal component index. 676 * @return Component instance or null if component was not found. 677 */ 678 protected static Window waitWindow(WindowOperator owner, ComponentChooser chooser, int index) { 679 return (waitWindow((Window) owner.getSource(), 680 chooser, index, 681 owner.getTimeouts(), owner.getOutput())); 682 } 683 684 /** 685 * A method to be used from subclasses. Uses timeouts and output passed as 686 * parameters during the waiting. 687 * 688 * @param owner a window - dialog owner. 689 * @param chooser org.netbeans.jemmy.ComponentChooser implementation. 690 * @param index Ordinal component index. 691 * @param timeouts timeouts to be used during the waiting. 692 * @param output an output to be used during the waiting. 693 * @return Component instance or null if component was not found. 694 */ 695 protected static Window waitWindow(Window owner, ComponentChooser chooser, int index, 696 Timeouts timeouts, TestOut output) { 697 try { 698 WindowWaiter waiter = new WindowWaiter(); 699 waiter.setTimeouts(timeouts); 700 waiter.setOutput(output); 701 return waiter.waitWindow(owner, chooser, index); 702 } catch (InterruptedException e) { 703 JemmyProperties.getCurrentOutput().printStackTrace(e); 704 return null; 705 } 706 } 707 708} 709