1 /*
   2  * Copyright (c) 1997, 2018, 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 package org.netbeans.jemmy.operators;
  24 
  25 import java.awt.Component;
  26 import java.awt.Container;
  27 import java.awt.Dimension;
  28 import java.awt.Point;
  29 import java.awt.Rectangle;
  30 import java.beans.PropertyVetoException;
  31 import java.util.Hashtable;
  32 
  33 import javax.swing.Icon;
  34 import javax.swing.JDesktopPane;
  35 import javax.swing.JInternalFrame;
  36 import javax.swing.JLayeredPane;
  37 import javax.swing.JMenuBar;
  38 import javax.swing.JScrollPane;
  39 import javax.swing.JInternalFrame.JDesktopIcon;
  40 import javax.swing.event.InternalFrameListener;
  41 import javax.swing.plaf.InternalFrameUI;
  42 
  43 import org.netbeans.jemmy.ComponentChooser;
  44 import org.netbeans.jemmy.ComponentSearcher;
  45 import org.netbeans.jemmy.JemmyInputException;
  46 import org.netbeans.jemmy.JemmyProperties;
  47 import org.netbeans.jemmy.Outputable;
  48 import org.netbeans.jemmy.TestOut;
  49 import org.netbeans.jemmy.TimeoutExpiredException;
  50 import org.netbeans.jemmy.Timeoutable;
  51 import org.netbeans.jemmy.Timeouts;
  52 import org.netbeans.jemmy.drivers.DriverManager;
  53 import org.netbeans.jemmy.drivers.FrameDriver;
  54 import org.netbeans.jemmy.drivers.InternalFrameDriver;
  55 import org.netbeans.jemmy.drivers.WindowDriver;
  56 import org.netbeans.jemmy.util.EmptyVisualizer;
  57 
  58 /**
  59  * Class provides necessary functionality to operate with
  60  * javax.swing.JInternalFrame component.
  61  *
  62  * Some methods can throw WrongInternalFrameStateException exception.
  63  *
  64  * <BR><BR>Timeouts used: <BR>
  65  * ComponentOperator.WaitComponentTimeout - time to wait component displayed
  66  * <BR>
  67  * ComponentOperator.MouseClickTimeout - time between mouse pressing and
  68  * releasing <BR>
  69  * AbstractButtonOperator.PushButtonTimeout - time between button pressing and
  70  * releasing<BR>
  71  * JScrollBarOperator.WholeScrollTimeout - time for the whole scrolling <BR>.
  72  *
  73  * @see org.netbeans.jemmy.Timeouts
  74  * @see WrongInternalFrameStateException
  75  * @author Alexandre Iline (alexandre.iline@oracle.com)
  76  */
  77 public class JInternalFrameOperator extends JComponentOperator
  78         implements Outputable, Timeoutable {
  79 
  80     /**
  81      * Identifier for a "title" property.
  82      *
  83      * @see #getDump
  84      */
  85     public static final String TITLE_DPROP = "Title";
  86 
  87     /**
  88      * Identifier for a "state" property.
  89      *
  90      * @see #getDump
  91      */
  92     public static final String STATE_DPROP = "State";
  93 
  94     /**
  95      * Identifier for a "normal" value of "state" property.
  96      *
  97      * @see #getDump
  98      */
  99     public static final String STATE_NORMAL_DPROP_VALUE = "NORMAL";
 100 
 101     /**
 102      * Identifier for a "closed" value of "state" property.
 103      *
 104      * @see #getDump
 105      */
 106     public static final String STATE_CLOSED_DPROP_VALUE = "CLOSED";
 107 
 108     /**
 109      * Identifier for a "iconified" value of "state" property.
 110      *
 111      * @see #getDump
 112      */
 113     public static final String STATE_ICONIFIED_DPROP_VALUE = "ICONIFIED";
 114 
 115     /**
 116      * Identifier for a "maximized" value of "state" property.
 117      *
 118      * @see #getDump
 119      */
 120     public static final String STATE_MAXIMAZED_DPROP_VALUE = "MAXIMIZED";
 121 
 122     /**
 123      * Identifier for a "resizable" property.
 124      *
 125      * @see #getDump
 126      */
 127     public static final String IS_RESIZABLE_DPROP = "Resizable";
 128 
 129     /**
 130      * Identifier for a "selected" property.
 131      *
 132      * @see #getDump
 133      */
 134     public static final String IS_SELECTED_DPROP = "Selected";
 135 
 136     /**
 137      * A minimizing button.
 138      */
 139     protected JButtonOperator minOper = null;
 140 
 141     /**
 142      * A maximizing button.
 143      */
 144     protected JButtonOperator maxOper = null;
 145 
 146     /**
 147      * A close button.
 148      */
 149     protected JButtonOperator closeOper = null;
 150 
 151     /**
 152      * A title operator.
 153      */
 154     protected ContainerOperator<?> titleOperator = null;
 155     private TestOut output;
 156     private Timeouts timeouts;
 157     private JDesktopIconOperator iconOperator;
 158 
 159     WindowDriver wDriver;
 160     FrameDriver fDriver;
 161     InternalFrameDriver iDriver;
 162 
 163     /**
 164      * Constructor.
 165      *
 166      * @param b a component
 167      */
 168     public JInternalFrameOperator(JInternalFrame b) {
 169         super(b);
 170         wDriver = DriverManager.getWindowDriver(getClass());
 171         fDriver = DriverManager.getFrameDriver(getClass());
 172         iDriver = DriverManager.getInternalFrameDriver(getClass());
 173     }
 174 
 175     /**
 176      * Constructs a JInternalFrameOperator object.
 177      *
 178      * @param cont a container
 179      * @param chooser a component chooser specifying searching criteria.
 180      * @param index an index between appropriate ones.
 181      */
 182     public JInternalFrameOperator(ContainerOperator<?> cont, ComponentChooser chooser, int index) {
 183         this((JInternalFrame) cont.
 184                 waitSubComponent(new JInternalFrameFinder(chooser),
 185                         index));
 186         copyEnvironment(cont);
 187     }
 188 
 189     /**
 190      * Constructs a JInternalFrameOperator object.
 191      *
 192      * @param cont a container
 193      * @param chooser a component chooser specifying searching criteria.
 194      */
 195     public JInternalFrameOperator(ContainerOperator<?> cont, ComponentChooser chooser) {
 196         this(cont, chooser, 0);
 197     }
 198 
 199     /**
 200      * Constructor. Waits component in container first. Uses cont's timeout and
 201      * output for waiting and to init operator.
 202      *
 203      * @param cont a container
 204      * @param text Button text.
 205      * @param index Ordinal component index.
 206      * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
 207      *
 208      */
 209     public JInternalFrameOperator(ContainerOperator<?> cont, String text, int index) {
 210         this(findOne(cont, text, index));
 211         copyEnvironment(cont);
 212     }
 213 
 214     /**
 215      * Constructor. Waits component in container first. Uses cont's timeout and
 216      * output for waiting and to init operator.
 217      *
 218      * @param cont a container
 219      * @param text Button text.
 220      * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
 221      *
 222      */
 223     public JInternalFrameOperator(ContainerOperator<?> cont, String text) {
 224         this(cont, text, 0);
 225     }
 226 
 227     /**
 228      * Constructor. Waits component in container first. Uses cont's timeout and
 229      * output for waiting and to init operator.
 230      *
 231      * @param cont a container
 232      * @param index Ordinal component index.
 233      *
 234      */
 235     public JInternalFrameOperator(ContainerOperator<?> cont, int index) {
 236         this((JInternalFrame) waitComponent(cont,
 237                 new JInternalFrameFinder(),
 238                 index));
 239         copyEnvironment(cont);
 240     }
 241 
 242     /**
 243      * Constructor. Waits component in container first. Uses cont's timeout and
 244      * output for waiting and to init operator.
 245      *
 246      * @param cont a container
 247      *
 248      */
 249     public JInternalFrameOperator(ContainerOperator<?> cont) {
 250         this(cont, 0);
 251     }
 252 
 253     /**
 254      * Searches JInternalframe in container.
 255      *
 256      * @param cont Container to search component in.
 257      * @param chooser a component chooser specifying searching criteria.
 258      * @param index Ordinal component index.
 259      * @return JInternalframe instance or null if component was not found.
 260      */
 261     public static JInternalFrame findJInternalFrame(Container cont, ComponentChooser chooser, int index) {
 262         Component res = findComponent(cont, new JInternalFrameFinder(chooser), index);
 263         if (res instanceof JInternalFrame) {
 264             return (JInternalFrame) res;
 265         } else if (res instanceof JInternalFrame.JDesktopIcon) {
 266             return ((JInternalFrame.JDesktopIcon) res).getInternalFrame();
 267         } else {
 268             return null;
 269         }
 270     }
 271 
 272     /**
 273      * Searches JInternalframe in container.
 274      *
 275      * @param cont Container to search component in.
 276      * @param chooser a component chooser specifying searching criteria.
 277      * @return JInternalframe instance or null if component was not found.
 278      */
 279     public static JInternalFrame findJInternalFrame(Container cont, ComponentChooser chooser) {
 280         return findJInternalFrame(cont, chooser, 0);
 281     }
 282 
 283     /**
 284      * Searches JInternalframe by title.
 285      *
 286      * @param cont Container to search component in.
 287      * @param text Component text.
 288      * @param ce Compare text exactly.
 289      * @param ccs Compare text case sensitively.
 290      * @param index Ordinal component index.
 291      * @return JInternalframe instance or null if component was not found.
 292      * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
 293      */
 294     public static JInternalFrame findJInternalFrame(Container cont, String text, boolean ce, boolean ccs, int index) {
 295         return (findJInternalFrame(cont,
 296                 new JInternalFrameByTitleFinder(text,
 297                         new DefaultStringComparator(ce, ccs)),
 298                 index));
 299     }
 300 
 301     /**
 302      * Searches JInternalframe by title.
 303      *
 304      * @param cont Container to search component in.
 305      * @param text Component text.
 306      * @param ce Compare text exactly.
 307      * @param ccs Compare text case sensitively.
 308      * @return JInternalframe instance or null if component was not found.
 309      * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
 310      */
 311     public static JInternalFrame findJInternalFrame(Container cont, String text, boolean ce, boolean ccs) {
 312         return findJInternalFrame(cont, text, ce, ccs, 0);
 313     }
 314 
 315     /**
 316      * Searches JInternalFrame object which component lies on.
 317      *
 318      * @param comp Component to find JInternalFrame under.
 319      * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
 320      * @return JInternalFrame instance or null if component was not found.
 321      */
 322     public static JInternalFrame findJInternalFrameUnder(Component comp, ComponentChooser chooser) {
 323         return (JInternalFrame) findContainerUnder(comp, new JInternalFrameFinder(chooser));
 324     }
 325 
 326     /**
 327      * Searches JInternalFrame object which component lies on.
 328      *
 329      * @param comp Component to find JInternalFrame under.
 330      * @return JInternalFrame instance or null if component was not found.
 331      */
 332     public static JInternalFrame findJInternalFrameUnder(Component comp) {
 333         return findJInternalFrameUnder(comp, new JInternalFrameFinder());
 334     }
 335 
 336     /**
 337      * Waits JInternalframe in container.
 338      *
 339      * @param cont Container to search component in.
 340      * @param chooser a component chooser specifying searching criteria.
 341      * @param index Ordinal component index.
 342      * @return JInternalframe instance.
 343      *
 344      */
 345     public static JInternalFrame waitJInternalFrame(final Container cont, final ComponentChooser chooser, final int index) {
 346         Component res = waitComponent(cont, new JInternalFrameFinder(chooser), index);
 347         if (res instanceof JInternalFrame) {
 348             return (JInternalFrame) res;
 349         } else if (res instanceof JInternalFrame.JDesktopIcon) {
 350             return ((JInternalFrame.JDesktopIcon) res).getInternalFrame();
 351         } else {
 352             throw (new TimeoutExpiredException(chooser.getDescription()));
 353         }
 354     }
 355 
 356     /**
 357      * Waits JInternalframe in container.
 358      *
 359      * @param cont Container to search component in.
 360      * @param chooser a component chooser specifying searching criteria.
 361      * @return JInternalframe instance.
 362      *
 363      */
 364     public static JInternalFrame waitJInternalFrame(Container cont, ComponentChooser chooser) {
 365         return waitJInternalFrame(cont, chooser, 0);
 366     }
 367 
 368     /**
 369      * Waits JInternalframe by title.
 370      *
 371      * @param cont Container to search component in.
 372      * @param text Component text.
 373      * @param ce Compare text exactly.
 374      * @param ccs Compare text case sensitively.
 375      * @param index Ordinal component index.
 376      * @return JInternalframe instance.
 377      * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
 378      *
 379      */
 380     public static JInternalFrame waitJInternalFrame(Container cont, String text, boolean ce, boolean ccs, int index) {
 381         return (waitJInternalFrame(cont,
 382                 new JInternalFrameByTitleFinder(text,
 383                         new DefaultStringComparator(ce, ccs)),
 384                 index));
 385     }
 386 
 387     /**
 388      * Waits JInternalframe by title.
 389      *
 390      * @param cont Container to search component in.
 391      * @param text Component text.
 392      * @param ce Compare text exactly.
 393      * @param ccs Compare text case sensitively.
 394      * @return JInternalframe instance.
 395      * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
 396      *
 397      */
 398     public static JInternalFrame waitJInternalFrame(Container cont, String text, boolean ce, boolean ccs) {
 399         return waitJInternalFrame(cont, text, ce, ccs, 0);
 400     }
 401 
 402     @Override
 403     public void setOutput(TestOut out) {
 404         output = out;
 405         super.setOutput(output.createErrorOutput());
 406     }
 407 
 408     @Override
 409     public TestOut getOutput() {
 410         return output;
 411     }
 412 
 413     @Override
 414     public void setTimeouts(Timeouts times) {
 415         timeouts = times;
 416         super.setTimeouts(timeouts);
 417     }
 418 
 419     @Override
 420     public Timeouts getTimeouts() {
 421         return timeouts;
 422     }
 423 
 424     /**
 425      * Iconifies frame. Note: frame should not be iconified and should be
 426      * iconifiable.
 427      *
 428      * @throws WrongInternalFrameStateException
 429      *
 430      */
 431     public void iconify() {
 432         output.printLine("Iconify JInternalFrame\n    : " + toStringSource());
 433         output.printGolden("Iconify JInternalFrame \"" + getTitle() + "\"");
 434         checkIconified(false);
 435         makeComponentVisible();
 436         fDriver.iconify(this);
 437         if (getVerification()) {
 438             waitIcon(true);
 439         }
 440     }
 441 
 442     /**
 443      * Deiconifies frame. Note: frame should be iconified.
 444      *
 445      * @throws WrongInternalFrameStateException
 446      *
 447      */
 448     public void deiconify() {
 449         output.printLine("Deiconify JInternalFrame\n    : " + toStringSource());
 450         output.printGolden("Deiconify JInternalFrame \"" + getTitle() + "\"");
 451         checkIconified(true);
 452         fDriver.deiconify(this);
 453         if (getVerification()) {
 454             waitIcon(false);
 455         }
 456     }
 457 
 458     /**
 459      * Maximizes frame. Note: frame should not be iconified.
 460      *
 461      * @throws WrongInternalFrameStateException
 462      */
 463     public void maximize() {
 464         output.printLine("Maximize JInternalFrame\n    : " + toStringSource());
 465         output.printGolden("Maximize JInternalFrame \"" + getTitle() + "\"");
 466         checkIconified(false);
 467         makeComponentVisible();
 468         fDriver.maximize(this);
 469         if (getVerification()) {
 470             waitMaximum(true);
 471         }
 472     }
 473 
 474     /**
 475      * Demaximizes frame. Note: frame should not be iconified.
 476      *
 477      * @throws WrongInternalFrameStateException
 478      */
 479     public void demaximize() {
 480         output.printLine("Demaximize JInternalFrame\n    : " + toStringSource());
 481         output.printGolden("Demaximize JInternalFrame \"" + getTitle() + "\"");
 482         checkIconified(false);
 483         makeComponentVisible();
 484         fDriver.demaximize(this);
 485         if (getVerification()) {
 486             waitMaximum(false);
 487         }
 488     }
 489 
 490     /**
 491      * Moves frame to new location. Note: frame should not be iconified.
 492      *
 493      * @param x X coordinate of a new frame location.
 494      * @param y Y coordinate of a new frame location.
 495      * @throws WrongInternalFrameStateException
 496      */
 497     public void move(int x, int y) {
 498         checkIconified(false);
 499         output.printLine("Move JInternalFrame to ("
 500                 + Integer.toString(x) + ","
 501                 + Integer.toString(y) + ")"
 502                 + " position\n    : " + toStringSource());
 503         output.printGolden("Move " + getTitle()
 504                 + " JInternalFrame to ("
 505                 + Integer.toString(x) + ","
 506                 + Integer.toString(y) + ")"
 507                 + " position");
 508         checkIconified(false);
 509         wDriver.move(this, x, y);
 510         if (getVerification()) {
 511             waitComponentLocation(new Point(x, y));
 512         }
 513     }
 514 
 515     /**
 516      * Resizes frame. Note: frame should not be iconified.
 517      *
 518      * @param width New frame width.
 519      * @param height New frame height.
 520      * @throws WrongInternalFrameStateException
 521      */
 522     public void resize(int width, int height) {
 523         output.printLine("Resize JInternalFrame to ("
 524                 + Integer.toString(width) + ","
 525                 + Integer.toString(height) + ")"
 526                 + " size\n    : " + toStringSource());
 527         output.printGolden("Resize " + getTitle()
 528                 + " JInternalFrame to ("
 529                 + Integer.toString(width) + ","
 530                 + Integer.toString(height) + ")"
 531                 + " size");
 532         checkIconified(false);
 533         wDriver.resize(this, width, height);
 534         if (getVerification()) {
 535             waitComponentSize(new Dimension(width, height));
 536         }
 537     }
 538 
 539     /**
 540      * Activates frame. Note: frame should not be iconified.
 541      *
 542      * @throws WrongInternalFrameStateException
 543      */
 544     public void activate() {
 545         checkIconified(false);
 546         wDriver.activate(this);
 547         if (getVerification()) {
 548             waitActivate(true);
 549         }
 550     }
 551 
 552     /**
 553      * Closes the frame.
 554      */
 555     public void close() {
 556         checkIconified(false);
 557         wDriver.requestClose(this);
 558         if (getVerification()) {
 559             waitClosed();
 560         }
 561     }
 562 
 563     /**
 564      * Scrolls to internal frame's rectangle.
 565      *
 566      * @param x Horizontal rectangle coordinate
 567      * @param y Vertical rectangle coordinate
 568      * @param width rectangle width
 569      * @param height rectangle height
 570      *
 571      */
 572     public void scrollToRectangle(int x, int y, int width, int height) {
 573         output.printTrace("Scroll desktop pane to make \"" + getTitle() + "\" internal frame visible");
 574         output.printGolden("Scroll desktop pane to make \"" + getTitle() + "\" internal frame visible");
 575         makeComponentVisible();
 576         //try to find JScrollPane under.
 577         JScrollPane scroll;
 578         if (isIcon()) {
 579             scroll
 580                     = (JScrollPane) iconOperator.getContainer(new JScrollPaneOperator.JScrollPaneFinder(ComponentSearcher.
 581                             getTrueChooser("JScrollPane")));
 582         } else {
 583             scroll
 584                     = (JScrollPane) getContainer(new JScrollPaneOperator.JScrollPaneFinder(ComponentSearcher.
 585                             getTrueChooser("JScrollPane")));
 586         }
 587         if (scroll == null) {
 588             return;
 589         }
 590         JScrollPaneOperator scroller = new JScrollPaneOperator(scroll);
 591         scroller.copyEnvironment(this);
 592         scroller.setVisualizer(new EmptyVisualizer());
 593         scroller.scrollToComponentRectangle(isIcon() ? iconOperator.getSource() : getSource(),
 594                 x, y, width, height);
 595     }
 596 
 597     /**
 598      * Scrolls to internal frame's rectangle.
 599      *
 600      * @param rect a rectangle to scroll to.
 601      */
 602     public void scrollToRectangle(Rectangle rect) {
 603         scrollToRectangle(rect.x, rect.y, rect.width, rect.height);
 604     }
 605 
 606     /**
 607      * Scrolls to internal frame.
 608      *
 609      */
 610     public void scrollToFrame() {
 611         if (isIcon()) {
 612             scrollToRectangle(0, 0, iconOperator.getWidth(), iconOperator.getHeight());
 613         } else {
 614             scrollToRectangle(0, 0, getWidth(), getHeight());
 615         }
 616     }
 617 
 618     /**
 619      * Waits for a minimize button inside the title pane.
 620      *
 621      * @return a button operator
 622      */
 623     public JButtonOperator getMinimizeButton() {
 624         initOperators();
 625         return minOper;
 626     }
 627 
 628     /**
 629      * Waits for a maximize button inside the title pane.
 630      *
 631      * @return a button operator
 632      */
 633     public JButtonOperator getMaximizeButton() {
 634         initOperators();
 635         return maxOper;
 636     }
 637 
 638     /**
 639      * Waits for a close button inside the title pane.
 640      *
 641      * @return a button operator
 642      */
 643     public JButtonOperator getCloseButton() {
 644         initOperators();
 645         return closeOper;
 646     }
 647 
 648     /**
 649      * Waits for the title pane.
 650      *
 651      * @return a button operator
 652      */
 653     public ContainerOperator<?> getTitleOperator() {
 654         initOperators();
 655         return titleOperator;
 656     }
 657 
 658     /**
 659      * Creates an operator for an desktop icon.
 660      *
 661      * @return an icon operator.
 662      */
 663     public JDesktopIconOperator getIconOperator() {
 664         initOperators();
 665         return iconOperator;
 666     }
 667 
 668     /**
 669      * Waits for the frame to be iconified or deiconified.
 670      *
 671      * @param isIconified whether the frame needs to be iconified or deiconified.
 672      */
 673     public void waitIcon(final boolean isIconified) {
 674         waitStateOnQueue(new ComponentChooser() {
 675             @Override
 676             public boolean checkComponent(Component comp) {
 677                 return isIcon() == isIconified;
 678             }
 679 
 680             @Override
 681             public String getDescription() {
 682                 return "Internal Frame is " + (isIconified ? "iconified" : "deiconified");
 683             }
 684 
 685             @Override
 686             public String toString() {
 687                 return "JInternalFrameOperator.waitIcon.ComponentChooser{description = " + getDescription() + '}';
 688             }
 689         });
 690     }
 691 
 692     /**
 693      * Waits for the frame to be activated or deactivated.
 694      *
 695      * @param isActivate whether the frame needs to be activated or deactivated.
 696      */
 697     public void waitActivate(final boolean isActivate) {
 698         waitStateOnQueue(new ComponentChooser() {
 699             @Override
 700             public boolean checkComponent(Component comp) {
 701                 return isSelected() == isActivate;
 702             }
 703 
 704             @Override
 705             public String getDescription() {
 706                 return "Internal Frame is " + (isActivate ? "activated" : "deactivated");
 707             }
 708 
 709             @Override
 710             public String toString() {
 711                 return "JInternalFrameOperator.waitActivate.ComponentChooser{description = " + getDescription() + '}';
 712             }
 713         });
 714     }
 715 
 716     /**
 717      * Waits for the frame to be closed.
 718      */
 719     public void waitClosed() {
 720         waitStateOnQueue(new ComponentChooser() {
 721             @Override
 722             public boolean checkComponent(Component comp) {
 723                 return isClosed();
 724             }
 725 
 726             @Override
 727             public String getDescription() {
 728                 return "Internal Frame is closed";
 729             }
 730 
 731             @Override
 732             public String toString() {
 733                 return "JInternalFrameOperator.waitClosed.ComponentChooser{description = " + getDescription() + '}';
 734             }
 735         });
 736     }
 737 
 738     /**
 739      * Waits for the frame to be maximized or demaximized.
 740      *
 741      * @param isMaximum whether the frame needs to be maximized or demaximized.
 742      */
 743     public void waitMaximum(final boolean isMaximum) {
 744         waitStateOnQueue(new ComponentChooser() {
 745             @Override
 746             public boolean checkComponent(Component comp) {
 747                 return isMaximum() == isMaximum;
 748             }
 749 
 750             @Override
 751             public String getDescription() {
 752                 return "Internal Frame is " + (isMaximum ? "maximizied" : "demaximizied");
 753             }
 754 
 755             @Override
 756             public String toString() {
 757                 return "JInternalFrameOperator.waitMaximum.ComponentChooser{description = " + getDescription() + '}';
 758             }
 759         });
 760     }
 761 
 762     /**
 763      * Returns information about component.
 764      */
 765     @Override
 766     public Hashtable<String, Object> getDump() {
 767         Hashtable<String, Object> result = super.getDump();
 768         result.put(TITLE_DPROP, ((JInternalFrame) getSource()).getTitle());
 769         String state = STATE_NORMAL_DPROP_VALUE;
 770         if (((JInternalFrame) getSource()).isClosed()) {
 771             state = STATE_CLOSED_DPROP_VALUE;
 772         } else if (((JInternalFrame) getSource()).isIcon()) {
 773             state = STATE_ICONIFIED_DPROP_VALUE;
 774         } else if (((JInternalFrame) getSource()).isMaximum()) {
 775             state = STATE_MAXIMAZED_DPROP_VALUE;
 776         }
 777         result.put(STATE_DPROP, state);
 778         result.put(IS_RESIZABLE_DPROP, ((JInternalFrame) getSource()).isResizable() ? "true" : "false");
 779         result.put(IS_SELECTED_DPROP, ((JInternalFrame) getSource()).isSelected() ? "true" : "false");
 780         return result;
 781     }
 782 
 783     ////////////////////////////////////////////////////////
 784     //Mapping                                             //
 785     /**
 786      * Maps
 787      * {@code JInternalFrame.addInternalFrameListener(InternalFrameListener)}
 788      * through queue
 789      */
 790     public void addInternalFrameListener(final InternalFrameListener internalFrameListener) {
 791         runMapping(new MapVoidAction("addInternalFrameListener") {
 792             @Override
 793             public void map() {
 794                 ((JInternalFrame) getSource()).addInternalFrameListener(internalFrameListener);
 795             }
 796         });
 797     }
 798 
 799     /**
 800      * Maps {@code JInternalFrame.dispose()} through queue
 801      */
 802     public void dispose() {
 803         runMapping(new MapVoidAction("dispose") {
 804             @Override
 805             public void map() {
 806                 ((JInternalFrame) getSource()).dispose();
 807             }
 808         });
 809     }
 810 
 811     /**
 812      * Maps {@code JInternalFrame.getContentPane()} through queue
 813      */
 814     public Container getContentPane() {
 815         return (runMapping(new MapAction<Container>("getContentPane") {
 816             @Override
 817             public Container map() {
 818                 return ((JInternalFrame) getSource()).getContentPane();
 819             }
 820         }));
 821     }
 822 
 823     /**
 824      * Maps {@code JInternalFrame.getDefaultCloseOperation()} through queue
 825      */
 826     public int getDefaultCloseOperation() {
 827         return (runMapping(new MapIntegerAction("getDefaultCloseOperation") {
 828             @Override
 829             public int map() {
 830                 return ((JInternalFrame) getSource()).getDefaultCloseOperation();
 831             }
 832         }));
 833     }
 834 
 835     /**
 836      * Maps {@code JInternalFrame.getDesktopIcon()} through queue
 837      */
 838     public JDesktopIcon getDesktopIcon() {
 839         return (runMapping(new MapAction<JDesktopIcon>("getDesktopIcon") {
 840             @Override
 841             public JDesktopIcon map() {
 842                 return ((JInternalFrame) getSource()).getDesktopIcon();
 843             }
 844         }));
 845     }
 846 
 847     /**
 848      * Maps {@code JInternalFrame.getDesktopPane()} through queue
 849      */
 850     public JDesktopPane getDesktopPane() {
 851         return (runMapping(new MapAction<JDesktopPane>("getDesktopPane") {
 852             @Override
 853             public JDesktopPane map() {
 854                 return ((JInternalFrame) getSource()).getDesktopPane();
 855             }
 856         }));
 857     }
 858 
 859     /**
 860      * Maps {@code JInternalFrame.getFrameIcon()} through queue
 861      */
 862     public Icon getFrameIcon() {
 863         return (runMapping(new MapAction<Icon>("getFrameIcon") {
 864             @Override
 865             public Icon map() {
 866                 return ((JInternalFrame) getSource()).getFrameIcon();
 867             }
 868         }));
 869     }
 870 
 871     /**
 872      * Maps {@code JInternalFrame.getGlassPane()} through queue
 873      */
 874     public Component getGlassPane() {
 875         return (runMapping(new MapAction<Component>("getGlassPane") {
 876             @Override
 877             public Component map() {
 878                 return ((JInternalFrame) getSource()).getGlassPane();
 879             }
 880         }));
 881     }
 882 
 883     /**
 884      * Maps {@code JInternalFrame.getJMenuBar()} through queue
 885      */
 886     public JMenuBar getJMenuBar() {
 887         return (runMapping(new MapAction<JMenuBar>("getJMenuBar") {
 888             @Override
 889             public JMenuBar map() {
 890                 return ((JInternalFrame) getSource()).getJMenuBar();
 891             }
 892         }));
 893     }
 894 
 895     /**
 896      * Maps {@code JInternalFrame.getLayer()} through queue
 897      */
 898     public int getLayer() {
 899         return (runMapping(new MapIntegerAction("getLayer") {
 900             @Override
 901             public int map() {
 902                 return ((JInternalFrame) getSource()).getLayer();
 903             }
 904         }));
 905     }
 906 
 907     /**
 908      * Maps {@code JInternalFrame.getLayeredPane()} through queue
 909      */
 910     public JLayeredPane getLayeredPane() {
 911         return (runMapping(new MapAction<JLayeredPane>("getLayeredPane") {
 912             @Override
 913             public JLayeredPane map() {
 914                 return ((JInternalFrame) getSource()).getLayeredPane();
 915             }
 916         }));
 917     }
 918 
 919     /**
 920      * Maps {@code JInternalFrame.getTitle()} through queue
 921      */
 922     public String getTitle() {
 923         return (runMapping(new MapAction<String>("getTitle") {
 924             @Override
 925             public String map() {
 926                 return ((JInternalFrame) getSource()).getTitle();
 927             }
 928         }));
 929     }
 930 
 931     /**
 932      * Maps {@code JInternalFrame.getUI()} through queue
 933      */
 934     public InternalFrameUI getUI() {
 935         return (runMapping(new MapAction<InternalFrameUI>("getUI") {
 936             @Override
 937             public InternalFrameUI map() {
 938                 return ((JInternalFrame) getSource()).getUI();
 939             }
 940         }));
 941     }
 942 
 943     /**
 944      * Maps {@code JInternalFrame.getWarningString()} through queue
 945      */
 946     public String getWarningString() {
 947         return (runMapping(new MapAction<String>("getWarningString") {
 948             @Override
 949             public String map() {
 950                 return ((JInternalFrame) getSource()).getWarningString();
 951             }
 952         }));
 953     }
 954 
 955     /**
 956      * Maps {@code JInternalFrame.isClosable()} through queue
 957      */
 958     public boolean isClosable() {
 959         return (runMapping(new MapBooleanAction("isClosable") {
 960             @Override
 961             public boolean map() {
 962                 return ((JInternalFrame) getSource()).isClosable();
 963             }
 964         }));
 965     }
 966 
 967     /**
 968      * Maps {@code JInternalFrame.isClosed()} through queue
 969      */
 970     public boolean isClosed() {
 971         return (runMapping(new MapBooleanAction("isClosed") {
 972             @Override
 973             public boolean map() {
 974                 return ((JInternalFrame) getSource()).isClosed();
 975             }
 976         }));
 977     }
 978 
 979     /**
 980      * Maps {@code JInternalFrame.isIcon()} through queue
 981      */
 982     public boolean isIcon() {
 983         return (runMapping(new MapBooleanAction("isIcon") {
 984             @Override
 985             public boolean map() {
 986                 return ((JInternalFrame) getSource()).isIcon();
 987             }
 988         }));
 989     }
 990 
 991     /**
 992      * Maps {@code JInternalFrame.isIconifiable()} through queue
 993      */
 994     public boolean isIconifiable() {
 995         return (runMapping(new MapBooleanAction("isIconifiable") {
 996             @Override
 997             public boolean map() {
 998                 return ((JInternalFrame) getSource()).isIconifiable();
 999             }
1000         }));
1001     }
1002 
1003     /**
1004      * Maps {@code JInternalFrame.isMaximizable()} through queue
1005      */
1006     public boolean isMaximizable() {
1007         return (runMapping(new MapBooleanAction("isMaximizable") {
1008             @Override
1009             public boolean map() {
1010                 return ((JInternalFrame) getSource()).isMaximizable();
1011             }
1012         }));
1013     }
1014 
1015     /**
1016      * Maps {@code JInternalFrame.isMaximum()} through queue
1017      */
1018     public boolean isMaximum() {
1019         return (runMapping(new MapBooleanAction("isMaximum") {
1020             @Override
1021             public boolean map() {
1022                 return ((JInternalFrame) getSource()).isMaximum();
1023             }
1024         }));
1025     }
1026 
1027     /**
1028      * Maps {@code JInternalFrame.isResizable()} through queue
1029      */
1030     public boolean isResizable() {
1031         return (runMapping(new MapBooleanAction("isResizable") {
1032             @Override
1033             public boolean map() {
1034                 return ((JInternalFrame) getSource()).isResizable();
1035             }
1036         }));
1037     }
1038 
1039     /**
1040      * Maps {@code JInternalFrame.isSelected()} through queue
1041      */
1042     public boolean isSelected() {
1043         return (runMapping(new MapBooleanAction("isSelected") {
1044             @Override
1045             public boolean map() {
1046                 return ((JInternalFrame) getSource()).isSelected();
1047             }
1048         }));
1049     }
1050 
1051     /**
1052      * Maps {@code JInternalFrame.moveToBack()} through queue
1053      */
1054     public void moveToBack() {
1055         runMapping(new MapVoidAction("moveToBack") {
1056             @Override
1057             public void map() {
1058                 ((JInternalFrame) getSource()).moveToBack();
1059             }
1060         });
1061     }
1062 
1063     /**
1064      * Maps {@code JInternalFrame.moveToFront()} through queue
1065      */
1066     public void moveToFront() {
1067         runMapping(new MapVoidAction("moveToFront") {
1068             @Override
1069             public void map() {
1070                 ((JInternalFrame) getSource()).moveToFront();
1071             }
1072         });
1073     }
1074 
1075     /**
1076      * Maps {@code JInternalFrame.pack()} through queue
1077      */
1078     public void pack() {
1079         runMapping(new MapVoidAction("pack") {
1080             @Override
1081             public void map() {
1082                 ((JInternalFrame) getSource()).pack();
1083             }
1084         });
1085     }
1086 
1087     /**
1088      * Maps
1089      * {@code JInternalFrame.removeInternalFrameListener(InternalFrameListener)}
1090      * through queue
1091      */
1092     public void removeInternalFrameListener(final InternalFrameListener internalFrameListener) {
1093         runMapping(new MapVoidAction("removeInternalFrameListener") {
1094             @Override
1095             public void map() {
1096                 ((JInternalFrame) getSource()).removeInternalFrameListener(internalFrameListener);
1097             }
1098         });
1099     }
1100 
1101     /**
1102      * Maps {@code JInternalFrame.setClosable(boolean)} through queue
1103      */
1104     public void setClosable(final boolean b) {
1105         runMapping(new MapVoidAction("setClosable") {
1106             @Override
1107             public void map() {
1108                 ((JInternalFrame) getSource()).setClosable(b);
1109             }
1110         });
1111     }
1112 
1113     /**
1114      * Maps {@code JInternalFrame.setClosed(boolean)} through queue
1115      */
1116     public void setClosed(final boolean b) {
1117         runMapping(new MapVoidAction("setClosed") {
1118             @Override
1119             public void map() throws PropertyVetoException {
1120                 ((JInternalFrame) getSource()).setClosed(b);
1121             }
1122         });
1123     }
1124 
1125     /**
1126      * Maps {@code JInternalFrame.setContentPane(Container)} through queue
1127      */
1128     public void setContentPane(final Container container) {
1129         runMapping(new MapVoidAction("setContentPane") {
1130             @Override
1131             public void map() {
1132                 ((JInternalFrame) getSource()).setContentPane(container);
1133             }
1134         });
1135     }
1136 
1137     /**
1138      * Maps {@code JInternalFrame.setDefaultCloseOperation(int)} through queue
1139      */
1140     public void setDefaultCloseOperation(final int i) {
1141         runMapping(new MapVoidAction("setDefaultCloseOperation") {
1142             @Override
1143             public void map() {
1144                 ((JInternalFrame) getSource()).setDefaultCloseOperation(i);
1145             }
1146         });
1147     }
1148 
1149     /**
1150      * Maps {@code JInternalFrame.setDesktopIcon(JDesktopIcon)} through queue
1151      */
1152     public void setDesktopIcon(final JDesktopIcon jDesktopIcon) {
1153         runMapping(new MapVoidAction("setDesktopIcon") {
1154             @Override
1155             public void map() {
1156                 ((JInternalFrame) getSource()).setDesktopIcon(jDesktopIcon);
1157             }
1158         });
1159     }
1160 
1161     /**
1162      * Maps {@code JInternalFrame.setFrameIcon(Icon)} through queue
1163      */
1164     public void setFrameIcon(final Icon icon) {
1165         runMapping(new MapVoidAction("setFrameIcon") {
1166             @Override
1167             public void map() {
1168                 ((JInternalFrame) getSource()).setFrameIcon(icon);
1169             }
1170         });
1171     }
1172 
1173     /**
1174      * Maps {@code JInternalFrame.setGlassPane(Component)} through queue
1175      */
1176     public void setGlassPane(final Component component) {
1177         runMapping(new MapVoidAction("setGlassPane") {
1178             @Override
1179             public void map() {
1180                 ((JInternalFrame) getSource()).setGlassPane(component);
1181             }
1182         });
1183     }
1184 
1185     /**
1186      * Maps {@code JInternalFrame.setIcon(boolean)} through queue
1187      */
1188     public void setIcon(final boolean b) {
1189         runMapping(new MapVoidAction("setIcon") {
1190             @Override
1191             public void map() throws PropertyVetoException {
1192                 ((JInternalFrame) getSource()).setIcon(b);
1193             }
1194         });
1195     }
1196 
1197     /**
1198      * Maps {@code JInternalFrame.setIconifiable(boolean)} through queue
1199      */
1200     public void setIconifiable(final boolean b) {
1201         runMapping(new MapVoidAction("setIconifiable") {
1202             @Override
1203             public void map() {
1204                 ((JInternalFrame) getSource()).setIconifiable(b);
1205             }
1206         });
1207     }
1208 
1209     /**
1210      * Maps {@code JInternalFrame.setJMenuBar(JMenuBar)} through queue
1211      */
1212     public void setJMenuBar(final JMenuBar jMenuBar) {
1213         runMapping(new MapVoidAction("setJMenuBar") {
1214             @Override
1215             public void map() {
1216                 ((JInternalFrame) getSource()).setJMenuBar(jMenuBar);
1217             }
1218         });
1219     }
1220 
1221     /**
1222      * Maps {@code JInternalFrame.setLayer(Integer)} through queue
1223      */
1224     public void setLayer(final Integer integer) {
1225         runMapping(new MapVoidAction("setLayer") {
1226             @Override
1227             public void map() {
1228                 ((JInternalFrame) getSource()).setLayer(integer);
1229             }
1230         });
1231     }
1232 
1233     /**
1234      * Maps {@code JInternalFrame.setLayeredPane(JLayeredPane)} through queue
1235      */
1236     public void setLayeredPane(final JLayeredPane jLayeredPane) {
1237         runMapping(new MapVoidAction("setLayeredPane") {
1238             @Override
1239             public void map() {
1240                 ((JInternalFrame) getSource()).setLayeredPane(jLayeredPane);
1241             }
1242         });
1243     }
1244 
1245     /**
1246      * Maps {@code JInternalFrame.setMaximizable(boolean)} through queue
1247      */
1248     public void setMaximizable(final boolean b) {
1249         runMapping(new MapVoidAction("setMaximizable") {
1250             @Override
1251             public void map() {
1252                 ((JInternalFrame) getSource()).setMaximizable(b);
1253             }
1254         });
1255     }
1256 
1257     /**
1258      * Maps {@code JInternalFrame.setMaximum(boolean)} through queue
1259      */
1260     public void setMaximum(final boolean b) {
1261         runMapping(new MapVoidAction("setMaximum") {
1262             @Override
1263             public void map() throws PropertyVetoException {
1264                 ((JInternalFrame) getSource()).setMaximum(b);
1265             }
1266         });
1267     }
1268 
1269     /**
1270      * Maps {@code JInternalFrame.setResizable(boolean)} through queue
1271      */
1272     public void setResizable(final boolean b) {
1273         runMapping(new MapVoidAction("setResizable") {
1274             @Override
1275             public void map() {
1276                 ((JInternalFrame) getSource()).setResizable(b);
1277             }
1278         });
1279     }
1280 
1281     /**
1282      * Maps {@code JInternalFrame.setSelected(boolean)} through queue
1283      */
1284     public void setSelected(final boolean b) {
1285         runMapping(new MapVoidAction("setSelected") {
1286             @Override
1287             public void map() throws PropertyVetoException {
1288                 ((JInternalFrame) getSource()).setSelected(b);
1289             }
1290         });
1291     }
1292 
1293     /**
1294      * Maps {@code JInternalFrame.setTitle(String)} through queue
1295      */
1296     public void setTitle(final String string) {
1297         runMapping(new MapVoidAction("setTitle") {
1298             @Override
1299             public void map() {
1300                 ((JInternalFrame) getSource()).setTitle(string);
1301             }
1302         });
1303     }
1304 
1305     /**
1306      * Maps {@code JInternalFrame.setUI(InternalFrameUI)} through queue
1307      */
1308     public void setUI(final InternalFrameUI internalFrameUI) {
1309         runMapping(new MapVoidAction("setUI") {
1310             @Override
1311             public void map() {
1312                 ((JInternalFrame) getSource()).setUI(internalFrameUI);
1313             }
1314         });
1315     }
1316 
1317     /**
1318      * Maps {@code JInternalFrame.toBack()} through queue
1319      */
1320     public void toBack() {
1321         runMapping(new MapVoidAction("toBack") {
1322             @Override
1323             public void map() {
1324                 ((JInternalFrame) getSource()).toBack();
1325             }
1326         });
1327     }
1328 
1329     /**
1330      * Maps {@code JInternalFrame.toFront()} through queue
1331      */
1332     public void toFront() {
1333         runMapping(new MapVoidAction("toFront") {
1334             @Override
1335             public void map() {
1336                 ((JInternalFrame) getSource()).toFront();
1337             }
1338         });
1339     }
1340 
1341     //End of mapping                                      //
1342     ////////////////////////////////////////////////////////
1343     /**
1344      * Uses InternalframeDriver to get a title pane.
1345      *
1346      * @return a title pane.
1347      */
1348     protected Container findTitlePane() {
1349         return (Container) iDriver.getTitlePane(this);
1350     }
1351 
1352     /**
1353      * Initiaites suboperators.
1354      */
1355     protected void initOperators() {
1356         iconOperator = new JDesktopIconOperator(((JInternalFrame) getSource()).getDesktopIcon());
1357         iconOperator.copyEnvironment(this);
1358         Container titlePane = findTitlePane();
1359         if (!isIcon() && titlePane != null) {
1360             if (titleOperator == null) {
1361                 titleOperator = new ContainerOperator<>(titlePane);
1362                 int bttCount = 0;
1363                 if (getContainer(new ComponentChooser() {
1364                     @Override
1365                     public boolean checkComponent(Component comp) {
1366                         return comp instanceof JDesktopPane;
1367                     }
1368 
1369                     @Override
1370                     public String getDescription() {
1371                         return "Desctop pane";
1372                     }
1373 
1374                     @Override
1375                     public String toString() {
1376                         return "JInternalFrameOperator.initOperators.ComponentChooser{description = " + getDescription() + '}';
1377                     }
1378                 }) != null) {
1379                     minOper = new JButtonOperator(titleOperator, bttCount);
1380                     bttCount++;
1381                     if (((JInternalFrame) getSource()).isMaximizable()) {
1382                         maxOper = new JButtonOperator(titleOperator, bttCount);
1383                         bttCount++;
1384                     } else {
1385                         maxOper = null;
1386                     }
1387                 } else {
1388                     minOper = null;
1389                     maxOper = null;
1390                 }
1391                 if (isClosable()) {
1392                     closeOper = new JButtonOperator(titleOperator, bttCount);
1393                 } else {
1394                     closeOper = null;
1395                 }
1396             }
1397         } else {
1398             titleOperator = null;
1399             minOper = null;
1400             maxOper = null;
1401             closeOper = null;
1402         }
1403     }
1404 
1405     //throw exception if state is wrong
1406     private void checkIconified(boolean shouldBeIconified) {
1407         if (shouldBeIconified && !isIcon()
1408                 || !shouldBeIconified && isIcon()) {
1409             throw (new WrongInternalFrameStateException("JInternal frame should "
1410                     + (shouldBeIconified ? "" : "not")
1411                     + " be iconified to produce this operation",
1412                     getSource()));
1413         }
1414     }
1415 
1416     private static JInternalFrame findOne(ContainerOperator<?> cont, String text, int index) {
1417         Component source = waitComponent(cont,
1418                 new JInternalFrameByTitleFinder(text,
1419                         cont.getComparator()),
1420                 index);
1421         if (source instanceof JInternalFrame) {
1422             return (JInternalFrame) source;
1423         } else if (source instanceof JInternalFrame.JDesktopIcon) {
1424             return ((JInternalFrame.JDesktopIcon) source).getInternalFrame();
1425         } else {
1426             throw (new TimeoutExpiredException("No internal frame was found"));
1427         }
1428     }
1429 
1430     /**
1431      * Exception can be throwht if as a result of an attempt to produce
1432      * operation for the frame in incorrect state. Like activate iconified
1433      * frame, for example.
1434      */
1435     public static class WrongInternalFrameStateException extends JemmyInputException {
1436 
1437         private static final long serialVersionUID = 42L;
1438 
1439         /**
1440          * Constructs a JInternalFrameOperator$WrongInternalFrameStateException
1441          * object.
1442          *
1443          * @param message an exception message.
1444          * @param comp an internal frame.
1445          */
1446         public WrongInternalFrameStateException(String message, Component comp) {
1447             super(message, comp);
1448         }
1449     }
1450 
1451     /**
1452      * Allows to find component by title.
1453      */
1454     public static class JInternalFrameByTitleFinder implements ComponentChooser {
1455 
1456         String label;
1457         StringComparator comparator;
1458 
1459         /**
1460          * Constructs JInternalFrameByTitleFinder.
1461          *
1462          * @param lb a text pattern
1463          * @param comparator specifies string comparision algorithm.
1464          */
1465         public JInternalFrameByTitleFinder(String lb, StringComparator comparator) {
1466             label = lb;
1467             this.comparator = comparator;
1468         }
1469 
1470         /**
1471          * Constructs JInternalFrameByTitleFinder.
1472          *
1473          * @param lb a text pattern
1474          */
1475         public JInternalFrameByTitleFinder(String lb) {
1476             this(lb, Operator.getDefaultStringComparator());
1477         }
1478 
1479         @Override
1480         public boolean checkComponent(Component comp) {
1481             if (comp instanceof JInternalFrame || comp instanceof JInternalFrame.JDesktopIcon) {
1482                 JInternalFrame frame = null;
1483                 if (comp instanceof JInternalFrame) {
1484                     frame = (JInternalFrame) comp;
1485                 } else {
1486                     JDesktopIconOperator io = new JDesktopIconOperator((JInternalFrame.JDesktopIcon) comp);
1487                     frame = io.getInternalFrame();
1488                 }
1489                 if (frame.getTitle() != null) {
1490                     return (comparator.equals(frame.getTitle(),
1491                             label));
1492                 }
1493             }
1494             return false;
1495         }
1496 
1497         @Override
1498         public String getDescription() {
1499             return "JInternalFrame with title \"" + label + "\"";
1500         }
1501 
1502         @Override
1503         public String toString() {
1504             return "JInternalFrameByTitleFinder{" + "label=" + label + ", comparator=" + comparator + '}';
1505         }
1506     }
1507 
1508     /**
1509      * Class to operate with javax.swing.JInternalFrame.JDesktopIconOperator
1510      * component.
1511      */
1512     public static class JDesktopIconOperator extends JComponentOperator
1513             implements Outputable, Timeoutable {
1514 
1515         private TestOut output;
1516         private Timeouts timeouts;
1517 
1518         /**
1519          * Constructs JDesktopIconOperator.
1520          *
1521          * @param b a component
1522          */
1523         public JDesktopIconOperator(JInternalFrame.JDesktopIcon b) {
1524             super(b);
1525             setOutput(JemmyProperties.getCurrentOutput());
1526             setTimeouts(JemmyProperties.getCurrentTimeouts());
1527         }
1528 
1529         @Override
1530         public void setOutput(TestOut out) {
1531             output = out;
1532             super.setOutput(output.createErrorOutput());
1533         }
1534 
1535         @Override
1536         public TestOut getOutput() {
1537             return output;
1538         }
1539 
1540         @Override
1541         public void setTimeouts(Timeouts times) {
1542             timeouts = times;
1543             super.setTimeouts(timeouts);
1544         }
1545 
1546         @Override
1547         public Timeouts getTimeouts() {
1548             return timeouts;
1549         }
1550 
1551         /**
1552          * Creates an operator for the correspondent intenal frame.
1553          *
1554          * @return an operator.
1555          */
1556         public JInternalFrame getInternalFrame() {
1557             return ((JInternalFrame) getEventDispatcher().
1558                     invokeExistingMethod("getInternalFrame",
1559                             null,
1560                             null,
1561                             output));
1562         }
1563 
1564         /**
1565          * Pushs the deiconifying button.
1566          */
1567         public void pushButton() {
1568             new JButtonOperator(this).push();
1569         }
1570     }
1571 
1572     /**
1573      * Checks component type.
1574      */
1575     public static class JInternalFrameFinder implements ComponentChooser {
1576 
1577         ComponentChooser sf = null;
1578 
1579         /**
1580          * Constructs JInternalFrameFinder.
1581          *
1582          * @param sf other searching criteria.
1583          */
1584         public JInternalFrameFinder(ComponentChooser sf) {
1585             this.sf = sf;
1586         }
1587 
1588         /**
1589          * Constructs JInternalFrameFinder.
1590          */
1591         public JInternalFrameFinder() {
1592             this(ComponentSearcher.getTrueChooser("JInternalFrame or JInternalFrame.JDesktopIcon"));
1593         }
1594 
1595         @Override
1596         public boolean checkComponent(Component comp) {
1597             return ((comp instanceof JInternalFrame || comp instanceof JInternalFrame.JDesktopIcon)
1598                     && sf.checkComponent(comp));
1599         }
1600 
1601         @Override
1602         public String getDescription() {
1603             return sf.getDescription();
1604         }
1605 
1606         @Override
1607         public String toString() {
1608             return "JInternalFrameFinder{" + "sf=" + sf + '}';
1609         }
1610     }
1611 
1612 }