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