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