JPopupMenuOperator.java revision 13978:1993af50385d
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.Dimension;
28import java.awt.Insets;
29import java.awt.Window;
30import java.awt.event.KeyEvent;
31import java.awt.event.MouseEvent;
32import java.util.Hashtable;
33
34import javax.swing.JMenu;
35import javax.swing.JMenuItem;
36import javax.swing.JPopupMenu;
37import javax.swing.MenuElement;
38import javax.swing.MenuSelectionManager;
39import javax.swing.SingleSelectionModel;
40import javax.swing.event.PopupMenuListener;
41import javax.swing.plaf.PopupMenuUI;
42
43import org.netbeans.jemmy.Action;
44import org.netbeans.jemmy.ComponentChooser;
45import org.netbeans.jemmy.ComponentSearcher;
46import org.netbeans.jemmy.JemmyException;
47import org.netbeans.jemmy.JemmyProperties;
48import org.netbeans.jemmy.Outputable;
49import org.netbeans.jemmy.QueueTool;
50import org.netbeans.jemmy.TestOut;
51import org.netbeans.jemmy.TimeoutExpiredException;
52import org.netbeans.jemmy.Timeoutable;
53import org.netbeans.jemmy.Timeouts;
54import org.netbeans.jemmy.WindowWaiter;
55import org.netbeans.jemmy.drivers.DriverManager;
56import org.netbeans.jemmy.drivers.MenuDriver;
57
58/**
59 * <BR><BR>Timeouts used: <BR>
60 * JMenuOperator.WaitBeforePopupTimeout - time to sleep before popup expanding
61 * <BR>
62 * JMenuOperator.WaitPopupTimeout - time to wait popup displayed <BR>
63 * ComponentOperator.WaitComponentTimeout - time to wait button displayed <BR>
64 * WindowWaiter.WaitWindowTimeout - time to wait popup window displayed <BR>
65 * WindowWaiter.AfterWindowTimeout - time to sleep after popup window has been
66 * dispayed <BR>.
67 *
68 * @see org.netbeans.jemmy.Timeouts
69 *
70 * @author Alexandre Iline (alexandre.iline@oracle.com)
71 *
72 */
73public class JPopupMenuOperator extends JComponentOperator
74        implements Outputable, Timeoutable {
75
76    /**
77     * Identifier for a "label" property.
78     *
79     * @see #getDump
80     */
81    public static final String LABEL_DPROP = "Label";
82
83    private TestOut output;
84    private Timeouts timeouts;
85    private MenuDriver driver;
86
87    /**
88     * Constructor.
89     *
90     * @param popup a component
91     */
92    public JPopupMenuOperator(JPopupMenu popup) {
93        super(popup);
94        driver = DriverManager.getMenuDriver(getClass());
95    }
96
97    /**
98     * Constructs a JPopupMenuOperator object.
99     *
100     * @param cont a container
101     * @param chooser a component chooser specifying searching criteria.
102     * @param index an index between appropriate ones.
103     */
104    public JPopupMenuOperator(ContainerOperator<?> cont, ComponentChooser chooser, int index) {
105        this((JPopupMenu) cont.
106                waitSubComponent(new JPopupMenuFinder(chooser),
107                        index));
108        copyEnvironment(cont);
109    }
110
111    /**
112     * Constructs a JPopupMenuOperator object.
113     *
114     * @param cont a container
115     * @param chooser a component chooser specifying searching criteria.
116     */
117    public JPopupMenuOperator(ContainerOperator<?> cont, ComponentChooser chooser) {
118        this(cont, chooser, 0);
119    }
120
121    /**
122     * Constructor. Waits component first. Constructor can be used in
123     * complicated cases when output or timeouts should differ from default.
124     *
125     * @param env an operator to copy environment from.
126     * @throws TimeoutExpiredException
127     */
128    public JPopupMenuOperator(Operator env) {
129        this((JPopupMenu) waitComponent(WindowOperator.
130                waitWindow(new JPopupWindowFinder(),
131                        0,
132                        env.getTimeouts(),
133                        env.getOutput()),
134                new JPopupMenuFinder(),
135                0,
136                env.getTimeouts(),
137                env.getOutput()));
138        copyEnvironment(env);
139    }
140
141    /**
142     * Constructor. Waits component in container first. Uses cont's timeout and
143     * output for waiting and to init operator.
144     *
145     * @param cont a container
146     * @throws TimeoutExpiredException
147     */
148    public JPopupMenuOperator(ContainerOperator<?> cont) {
149        this((JPopupMenu) waitComponent(cont,
150                new JPopupMenuFinder(),
151                0));
152        copyEnvironment(cont);
153    }
154
155    /**
156     * Constructor. Waits component first.
157     *
158     * @throws TimeoutExpiredException
159     */
160    public JPopupMenuOperator() {
161        this(Operator.getEnvironmentOperator());
162    }
163
164    /**
165     * Searches JPopupMenu in container.
166     *
167     * @param cont Container to search component in.
168     * @param chooser a component chooser specifying searching criteria.
169     * @param index Ordinal component index.
170     * @return JPopupMenu instance or null if component was not found.
171     */
172    public static JPopupMenu findJPopupMenu(Container cont, ComponentChooser chooser, int index) {
173        return (JPopupMenu) findComponent(cont, new JPopupMenuFinder(chooser), index);
174    }
175
176    /**
177     * Searches JPopupMenu in container.
178     *
179     * @param cont Container to search component in.
180     * @param chooser a component chooser specifying searching criteria.
181     * @return JPopupMenu instance or null if component was not found.
182     */
183    public static JPopupMenu findJPopupMenu(Container cont, ComponentChooser chooser) {
184        return findJPopupMenu(cont, chooser, 0);
185    }
186
187    /**
188     * Waits JPopupMenu in container.
189     *
190     * @param cont Container to search component in.
191     * @param chooser a component chooser specifying searching criteria.
192     * @param index Ordinal component index.
193     * @return JPopupMenu instance.
194     * @throws TimeoutExpiredException
195     */
196    public static JPopupMenu waitJPopupMenu(Container cont, ComponentChooser chooser, int index) {
197        return (JPopupMenu) waitComponent(cont, new JPopupMenuFinder(chooser), index);
198    }
199
200    /**
201     * Waits JPopupMenu in container.
202     *
203     * @param cont Container to search component in.
204     * @param chooser a component chooser specifying searching criteria.
205     * @return JPopupMenu instance.
206     * @throws TimeoutExpiredException
207     */
208    public static JPopupMenu waitJPopupMenu(Container cont, ComponentChooser chooser) {
209        return waitJPopupMenu(cont, chooser, 0);
210    }
211
212    /**
213     * Searches for a window which contains JPopupMenu.
214     *
215     * @param chooser a component chooser specifying criteria for JPopupMenu.
216     * @return a window containing JPopupMenu.
217     */
218    public static Window findJPopupWindow(ComponentChooser chooser) {
219        return WindowWaiter.getWindow(new JPopupWindowFinder(chooser));
220    }
221
222    /**
223     * Waits for a window which contains JPopupMenu.
224     *
225     * @param chooser a component chooser specifying criteria for JPopupMenu.
226     * @return a window containing JPopupMenu.
227     * @throws TimeoutExpiredException
228     */
229    public static Window waitJPopupWindow(ComponentChooser chooser) {
230        try {
231            return (new WindowWaiter()).waitWindow(new JPopupWindowFinder(chooser));
232        } catch (InterruptedException e) {
233            return null;
234        }
235    }
236
237    /**
238     * Waits popup defined by {@code popupChooser} parameter.
239     *
240     * @param popupChooser a component chooser specifying criteria for
241     * JPopupMenu.
242     * @return a JPopupMenu fitting the criteria.
243     */
244    public static JPopupMenuOperator waitJPopupMenu(final ComponentChooser popupChooser) {
245        try {
246            WindowOperator wind = new WindowOperator(new WindowWaiter().waitWindow(new ComponentChooser() {
247                @Override
248                public boolean checkComponent(Component comp) {
249                    ComponentSearcher searcher = new ComponentSearcher((Container) comp);
250                    searcher.setOutput(JemmyProperties.getCurrentOutput().createErrorOutput());
251                    return searcher.findComponent(popupChooser) != null;
252                }
253
254                @Override
255                public String getDescription() {
256                    return "Window containing \"" + popupChooser.getDescription() + "\" popup";
257                }
258
259                @Override
260                public String toString() {
261                    return "JPopupMenuOperator.waitJPopupMenu.ComponentChooser{description = " + getDescription() + '}';
262                }
263            }));
264            return new JPopupMenuOperator(wind);
265        } catch (InterruptedException e) {
266            throw (new JemmyException("Popup waiting has been interrupted", e));
267        }
268    }
269
270    /**
271     * Waits popup containing menu item with {@code menuItemText} text.
272     *
273     * @param menuItemText a text of a menu item which supposed to be displayed
274     * inside the popup.
275     * @return a JPopupMenu fitting the criteria.
276     */
277    public static JPopupMenuOperator waitJPopupMenu(final String menuItemText) {
278        return (waitJPopupMenu(new ComponentChooser() {
279            @Override
280            public boolean checkComponent(Component comp) {
281                if (comp instanceof JPopupMenu) {
282                    ComponentSearcher searcher = new ComponentSearcher((Container) comp);
283                    searcher.setOutput(JemmyProperties.getCurrentOutput().createErrorOutput());
284                    return (searcher.findComponent(new JMenuItemOperator.JMenuItemByLabelFinder(menuItemText,
285                            Operator.getDefaultStringComparator()))
286                            != null);
287                } else {
288                    return false;
289                }
290            }
291
292            @Override
293            public String getDescription() {
294                return "Popup containing \"" + menuItemText + "\" menu item";
295            }
296
297            @Override
298            public String toString() {
299                return "JPopupMenuOperator.waitJPopupMenu.ComponentChooser{description = " + getDescription() + '}';
300            }
301        }));
302    }
303
304    /**
305     * Calls popup by clicking on (x, y) point in component.
306     *
307     * @param oper Component operator to call popup on.
308     * @param x X coordinate of click point in the component coordinate system.
309     * @param y Y coordinate of click point in the component coordinate system.
310     * @param mouseButton Mouse button mask to call popup.
311     * @return an opened JPopupMenu
312     * @throws TimeoutExpiredException
313     */
314    public static JPopupMenu callPopup(final ComponentOperator oper, int x, int y, int mouseButton) {
315        oper.makeComponentVisible();
316        //1.5 workaround
317        if (System.getProperty("java.specification.version").compareTo("1.4") > 0) {
318            QueueTool qt = new QueueTool();
319            qt.setOutput(oper.getOutput().createErrorOutput());
320            qt.waitEmpty(10);
321            qt.waitEmpty(10);
322            qt.waitEmpty(10);
323        }
324        //end of 1.5 workaround
325        oper.clickForPopup(x, y, mouseButton);
326        oper.getTimeouts().sleep("JMenuOperator.WaitBeforePopupTimeout");
327        return (waitJPopupMenu(waitJPopupWindow(new ComponentChooser() {
328            @Override
329            public boolean checkComponent(Component cmp) {
330                Component invoker = ((JPopupMenu) cmp).getInvoker();
331                return (invoker == oper.getSource()
332                        || (invoker instanceof Container
333                        && ((Container) invoker).isAncestorOf(oper.getSource()))
334                        || (oper.getSource() instanceof Container
335                        && ((Container) oper.getSource()).isAncestorOf(invoker)));
336            }
337
338            @Override
339            public String getDescription() {
340                return "Popup menu";
341            }
342
343            @Override
344            public String toString() {
345                return "JPopupMenuOperator.callPopup.ComponentChooser{description = " + getDescription() + '}';
346            }
347        }),
348                ComponentSearcher.getTrueChooser("Popup menu")));
349    }
350
351    /**
352     * Calls popup by clicking on (x, y) point in component.
353     *
354     * @param oper Component operator to call popup on.
355     * @param x X coordinate of click point in the component coordinate system.
356     * @param y Y coordinate of click point in the component coordinate system.
357     * @return an opened JPopupMenu
358     * @see ComponentOperator#getPopupMouseButton()
359     * @throws TimeoutExpiredException
360     */
361    public static JPopupMenu callPopup(ComponentOperator oper, int x, int y) {
362        return callPopup(oper, x, y, getPopupMouseButton());
363    }
364
365    /**
366     * Calls popup by clicking on (x, y) point in component.
367     *
368     * @param comp Component to call popup on.
369     * @param x X coordinate of click point in the component coordinate system.
370     * @param y Y coordinate of click point in the component coordinate system.
371     * @param mouseButton Mouse button mask to call popup.
372     * @return an opened JPopupMenu
373     * @throws TimeoutExpiredException
374     */
375    public static JPopupMenu callPopup(Component comp, int x, int y, int mouseButton) {
376        return callPopup(new ComponentOperator(comp), x, y, mouseButton);
377    }
378
379    /**
380     * Calls popup by clicking on (x, y) point in component.
381     *
382     * @param comp Component to call popup on.
383     * @param x X coordinate of click point in the component coordinate system.
384     * @param y Y coordinate of click point in the component coordinate system.
385     * @return an opened JPopupMenu
386     * @see ComponentOperator#getPopupMouseButton()
387     * @throws TimeoutExpiredException
388     */
389    public static JPopupMenu callPopup(Component comp, int x, int y) {
390        return callPopup(comp, x, y, getPopupMouseButton());
391    }
392
393    /**
394     * Calls popup by clicking component center.
395     *
396     * @param comp Component to call popup on.
397     * @param mouseButton Mouse button mask to call popup.
398     * @return an opened JPopupMenu
399     * @throws TimeoutExpiredException
400     */
401    public static JPopupMenu callPopup(Component comp, int mouseButton) {
402        ComponentOperator co = new ComponentOperator(comp);
403        co.makeComponentVisible();
404        co.clickForPopup(mouseButton);
405        return (findJPopupMenu(waitJPopupWindow(ComponentSearcher.getTrueChooser("Popup menu window")),
406                ComponentSearcher.getTrueChooser("Popup menu")));
407    }
408
409    /**
410     * Calls popup by clicking component center.
411     *
412     * @param comp Component to call popup on.
413     * @return an opened JPopupMenu
414     * @see ComponentOperator#getPopupMouseButton()
415     * @throws TimeoutExpiredException
416     */
417    public static JPopupMenu callPopup(Component comp) {
418        return callPopup(comp, getPopupMouseButton());
419    }
420
421    static {
422        //necessary to init timeouts
423        JMenuOperator.performInit();
424    }
425
426    @Override
427    public void setOutput(TestOut out) {
428        super.setOutput(out);
429        output = out;
430    }
431
432    @Override
433    public TestOut getOutput() {
434        return output;
435    }
436
437    @Override
438    public void setTimeouts(Timeouts times) {
439        super.setTimeouts(times);
440        timeouts = times;
441    }
442
443    @Override
444    public Timeouts getTimeouts() {
445        return timeouts;
446    }
447
448    @Override
449    public void copyEnvironment(Operator anotherOperator) {
450        super.copyEnvironment(anotherOperator);
451        driver = DriverManager.getMenuDriver(this);
452    }
453
454    /**
455     * Pushes menu.
456     *
457     * @param choosers Array of choosers to find menuItems to push.
458     * @return Last pushed JMenuItem.
459     * @throws TimeoutExpiredException
460     */
461    public JMenuItem pushMenu(final ComponentChooser[] choosers) {
462        return ((JMenuItem) produceTimeRestricted(new Action<Object, Void>() {
463            @Override
464            public Object launch(Void obj) {
465                //TDB 1.5 menu workaround
466                getQueueTool().waitEmpty();
467                Object result = driver.pushMenu(JPopupMenuOperator.this,
468                        JMenuOperator.converChoosers(choosers));
469                getQueueTool().waitEmpty();
470                return result;
471            }
472
473            @Override
474            public String getDescription() {
475                return JMenuOperator.createDescription(choosers);
476            }
477
478            @Override
479            public String toString() {
480                return "JPopupMenuOperator.pushMenu.ComponentChooser{description = " + getDescription() + '}';
481            }
482        }, "JMenuOperator.PushMenuTimeout"));
483    }
484
485    /**
486     * Executes {@code pushMenu(choosers)} in a separate thread.
487     *
488     * @param choosers Array of choosers to find menuItems to push.
489     * @see #pushMenu(ComponentChooser[])
490     */
491    public void pushMenuNoBlock(final ComponentChooser[] choosers) {
492        produceNoBlocking(new NoBlockingAction<Object, Void>("Menu pushing") {
493            @Override
494            public Object doAction(Void param) {
495                //TDB 1.5 menu workaround
496                getQueueTool().waitEmpty();
497                Object result = driver.pushMenu(JPopupMenuOperator.this,
498                        JMenuOperator.converChoosers(choosers));
499                getQueueTool().waitEmpty();
500                return result;
501            }
502        });
503    }
504
505    /**
506     * Pushes menu.
507     *
508     * @param names an array of menu texts.
509     * @param comparator a string comparision algorithm
510     * @return Last pushed JMenuItem.
511     * @throws TimeoutExpiredException
512     */
513    public JMenuItem pushMenu(String[] names, StringComparator comparator) {
514        return pushMenu(JMenuItemOperator.createChoosers(names, comparator));
515    }
516
517    /**
518     * Pushes menu.
519     *
520     * @param names Menu items texts.
521     * @param ce Compare text exactly.
522     * @param ccs Compare text case sensitively.
523     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
524     * @return Last pushed JMenuItem.
525     * @throws TimeoutExpiredException
526     * @deprecated Use pushMenu(String[]) or pushMenu(String[],
527     * StringComparator)
528     */
529    @Deprecated
530    public JMenuItem pushMenu(String[] names, boolean ce, boolean ccs) {
531        return pushMenu(names, new DefaultStringComparator(ce, ccs));
532    }
533
534    /**
535     * Executes {@code pushMenu(names, ce, ccs)} in a separate thread.
536     *
537     * @param names an array of menu texts.
538     * @param comparator a string comparision algorithm
539     */
540    public void pushMenuNoBlock(String[] names, StringComparator comparator) {
541        pushMenuNoBlock(JMenuItemOperator.createChoosers(names, comparator));
542    }
543
544    /**
545     * Executes {@code pushMenu(names, ce, ccs)} in a separate thread.
546     *
547     * @param names Menu items texts.
548     * @param ce Compare text exactly.
549     * @param ccs Compare text case sensitively.
550     * @see #pushMenu(String[], boolean,boolean)
551     * @deprecated Use pushMenuNoBlock(String[]) or pushMenuNoBlock(String[],
552     * StringComparator)
553     */
554    @Deprecated
555    public void pushMenuNoBlock(String[] names, boolean ce, boolean ccs) {
556        pushMenuNoBlock(names, new DefaultStringComparator(ce, ccs));
557    }
558
559    /**
560     * Pushes menu.
561     *
562     * @param names Menu items texts.
563     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
564     * @return Last pushed JMenuItem.
565     * @throws TimeoutExpiredException
566     */
567    public JMenuItem pushMenu(String[] names) {
568        return pushMenu(names, getComparator());
569    }
570
571    /**
572     * Executes {@code pushMenu(names)} in a separate thread.
573     *
574     * @param names Menu items texts.
575     * @see #pushMenu(String[])
576     */
577    public void pushMenuNoBlock(String[] names) {
578        pushMenuNoBlock(names, getComparator());
579    }
580
581    /**
582     * Pushes menu.
583     *
584     * @param path a menu path.
585     * @param delim a path delimiter.
586     * @param comparator a string comparision algorithm
587     * @return Last pushed JMenuItem.
588     * @throws TimeoutExpiredException
589     */
590    public JMenuItem pushMenu(String path, String delim, StringComparator comparator) {
591        return pushMenu(parseString(path, delim), comparator);
592    }
593
594    /**
595     * Pushes menu. Uses PathParser assigned to this operator.
596     *
597     * @param path a menu path.
598     * @param comparator a string comparision algorithm
599     * @return Last pushed JMenuItem.
600     * @throws TimeoutExpiredException
601     */
602    public JMenuItem pushMenu(String path, StringComparator comparator) {
603        return pushMenu(parseString(path), comparator);
604    }
605
606    /**
607     * Pushes menu.
608     *
609     * @param path String menupath representation ("File/New", for example).
610     * @param delim String menupath divider ("/").
611     * @param ce Compare text exactly.
612     * @param ccs Compare text case sensitively.
613     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
614     * @return Last pushed JMenuItem.
615     * @throws TimeoutExpiredException
616     * @deprecated Use pushMenu(String, String) or pushMenu(String, String,
617     * StringComparator)
618     */
619    @Deprecated
620    public JMenuItem pushMenu(String path, String delim, boolean ce, boolean ccs) {
621        return pushMenu(parseString(path, delim), ce, ccs);
622    }
623
624    /**
625     * Executes {@code pushMenu(names, delim, comparator)} in a separate
626     * thread.
627     *
628     * @param path a menu path.
629     * @param delim a path delimiter.
630     * @param comparator a string comparision algorithm
631     */
632    public void pushMenuNoBlock(String path, String delim, StringComparator comparator) {
633        pushMenuNoBlock(parseString(path, delim), comparator);
634    }
635
636    /**
637     * Executes {@code pushMenu(names, comparator)} in a separate thread.
638     * Uses PathParser assigned to this operator.
639     *
640     * @param path a menu path.
641     * @param comparator a string comparision algorithm
642     */
643    public void pushMenuNoBlock(String path, StringComparator comparator) {
644        pushMenuNoBlock(parseString(path), comparator);
645    }
646
647    /**
648     * Executes {@code pushMenu(path, delim, ce, ccs)} in a separate
649     * thread.
650     *
651     * @param path String menupath representation ("File/New", for example).
652     * @param delim String menupath divider ("/").
653     * @param ce Compare text exactly.
654     * @param ccs Compare text case sensitively.
655     * @see #pushMenu
656     * @deprecated Use pushMenuNoBlock(String, String) or
657     * pushMenuNoBlock(String, String, StringComparator)
658     */
659    @Deprecated
660    public void pushMenuNoBlock(String path, String delim, boolean ce, boolean ccs) {
661        pushMenuNoBlock(parseString(path, delim), ce, ccs);
662    }
663
664    /**
665     * Pushes menu.
666     *
667     * @param path String menupath representation ("File/New", for example).
668     * @param delim String menupath divider ("/").
669     * @return Last pushed JMenuItem.
670     * @throws TimeoutExpiredException
671     */
672    public JMenuItem pushMenu(String path, String delim) {
673        return pushMenu(parseString(path, delim));
674    }
675
676    /**
677     * Pushes menu. Uses PathParser assigned to this operator.
678     *
679     * @param path String menupath representation ("File/New", for example).
680     * @return Last pushed JMenuItem.
681     * @throws TimeoutExpiredException
682     */
683    public JMenuItem pushMenu(String path) {
684        return pushMenu(parseString(path));
685    }
686
687    /**
688     * Executes {@code pushMenu(path, delim)} in a separate thread.
689     *
690     * @param path String menupath representation ("File/New", for example).
691     * @param delim String menupath divider ("/").
692     */
693    public void pushMenuNoBlock(String path, String delim) {
694        pushMenuNoBlock(parseString(path, delim));
695    }
696
697    /**
698     * Executes {@code pushMenu(path)} in a separate thread.
699     *
700     * @param path String menupath representation ("File/New", for example).
701     */
702    public void pushMenuNoBlock(String path) {
703        pushMenuNoBlock(parseString(path));
704    }
705
706    public JMenuItemOperator[] showMenuItems(ComponentChooser[] choosers) {
707        if (choosers == null || choosers.length == 0) {
708            return JMenuItemOperator.getMenuItems((MenuElement) getSource(), this);
709        } else {
710            return JMenuItemOperator.getMenuItems((JMenu) pushMenu(choosers), this);
711        }
712    }
713
714    /**
715     * Shows submenu of menu specified by a {@code path} parameter.
716     *
717     * @param path an array of menu texts.
718     * @param comparator a string comparision algorithm
719     * @return an array of operators created tor items from the submenu.
720     * @throws TimeoutExpiredException
721     */
722    public JMenuItemOperator[] showMenuItems(String[] path, StringComparator comparator) {
723        if (path == null || path.length == 0) {
724            return JMenuItemOperator.getMenuItems((MenuElement) getSource(), this);
725        } else {
726            return JMenuItemOperator.getMenuItems((JMenu) pushMenu(path, comparator), this);
727        }
728    }
729
730    /**
731     * Shows submenu of menu specified by a {@code path} parameter. Uses
732     * StringComparator assigned to the operator.
733     *
734     * @param path an array of menu texts.
735     * @return an array of operators created tor items from the submenu.
736     * @throws TimeoutExpiredException
737     */
738    public JMenuItemOperator[] showMenuItems(String[] path) {
739        return showMenuItems(path, getComparator());
740    }
741
742    /**
743     * Shows submenu of menu specified by a {@code path} parameter.
744     *
745     * @param path a string identifying the menu path.
746     * @param delim a path delimiter.
747     * @param comparator a string comparision algorithm
748     * @return an array of operators created tor items from the submenu.
749     * @throws TimeoutExpiredException
750     */
751    public JMenuItemOperator[] showMenuItems(String path, String delim, StringComparator comparator) {
752        return showMenuItems(parseString(path, delim), comparator);
753    }
754
755    /**
756     * Shows submenu of menu specified by a {@code path} parameter. Uses
757     * PathParser assigned to this operator.
758     *
759     * @param path a string identifying the menu path.
760     * @param comparator a string comparision algorithm
761     * @return an array of operators created tor items from the submenu.
762     * @throws TimeoutExpiredException
763     */
764    public JMenuItemOperator[] showMenuItems(String path, StringComparator comparator) {
765        return showMenuItems(parseString(path), comparator);
766    }
767
768    /**
769     * Shows submenu of menu specified by a {@code path} parameter. Uses
770     * StringComparator assigned to the operator.
771     *
772     * @param path a string identifying the menu path.
773     * @param delim a path delimiter.
774     * @return an array of operators created tor items from the submenu.
775     * @throws TimeoutExpiredException
776     */
777    public JMenuItemOperator[] showMenuItems(String path, String delim) {
778        return showMenuItems(path, delim, getComparator());
779    }
780
781    /**
782     * Shows submenu of menu specified by a {@code path} parameter. Uses
783     * PathParser assigned to this operator. Uses StringComparator assigned to
784     * the operator.
785     *
786     * @param path a string identifying the menu path.
787     * @return an array of operators created tor items from the submenu.
788     * @throws TimeoutExpiredException
789     */
790    public JMenuItemOperator[] showMenuItems(String path) {
791        return showMenuItems(path, getComparator());
792    }
793
794    public JMenuItemOperator showMenuItem(ComponentChooser[] choosers) {
795        ComponentChooser[] parentPath = getParentPath(choosers);
796        JMenu menu;
797        ContainerOperator<?> menuCont;
798        if (parentPath.length > 0) {
799            menu = (JMenu) pushMenu(getParentPath(choosers));
800            menuCont = new ContainerOperator<>(menu.getPopupMenu());
801            menuCont.copyEnvironment(this);
802        } else {
803            menuCont = this;
804        }
805        JMenuItemOperator result = new JMenuItemOperator(menuCont, choosers[choosers.length - 1]);
806        result.copyEnvironment(this);
807        return result;
808    }
809
810    /**
811     * Expends all menus to show menu item specified by a {@code path}
812     * parameter.
813     *
814     * @param path an array of menu texts.
815     * @param comparator a string comparision algorithm
816     * @return an operator for the last menu item in path.
817     * @throws TimeoutExpiredException
818     */
819    public JMenuItemOperator showMenuItem(String[] path, StringComparator comparator) {
820        String[] parentPath = getParentPath(path);
821        JMenu menu;
822        ContainerOperator<?> menuCont;
823        if (parentPath.length > 0) {
824            menu = (JMenu) pushMenu(getParentPath(path), comparator);
825            menuCont = new ContainerOperator<>(menu.getPopupMenu());
826            menuCont.copyEnvironment(this);
827        } else {
828            menuCont = this;
829        }
830        JMenuItemOperator result = new JMenuItemOperator(menuCont, path[path.length - 1]);
831        result.copyEnvironment(this);
832        return result;
833    }
834
835    /**
836     * Expands all menus to show menu item specified by a {@code path}
837     * parameter.
838     *
839     * @param path an array of menu texts.
840     * @return an operator for the last menu item in path.
841     * @throws TimeoutExpiredException
842     */
843    public JMenuItemOperator showMenuItem(String[] path) {
844        return showMenuItem(path, getComparator());
845    }
846
847    /**
848     * Expands all menus to show menu item specified by a {@code path}
849     * parameter.
850     *
851     * @param path a string identifying the menu path.
852     * @param delim a path delimiter.
853     * @param comparator a string comparision algorithm
854     * @return an operator for the last menu item in path.
855     * @throws TimeoutExpiredException
856     */
857    public JMenuItemOperator showMenuItem(String path, String delim, StringComparator comparator) {
858        return showMenuItem(parseString(path, delim), comparator);
859    }
860
861    /**
862     * Expands all menus to show menu item specified by a {@code path}
863     * parameter. Uses PathParser assigned to this operator.
864     *
865     * @param path a string identifying the menu path.
866     * @param comparator a string comparision algorithm
867     * @return an operator for the last menu item in path.
868     * @throws TimeoutExpiredException
869     */
870    public JMenuItemOperator showMenuItem(String path, StringComparator comparator) {
871        return showMenuItem(parseString(path), comparator);
872    }
873
874    /**
875     * Expands all menus to show menu item specified by a {@code path}
876     * parameter. Uses StringComparator assigned to the operator.
877     *
878     * @param path a string identifying the menu path.
879     * @param delim a path delimiter.
880     * @return an operator for the last menu item in path.
881     * @throws TimeoutExpiredException
882     */
883    public JMenuItemOperator showMenuItem(String path, String delim) {
884        return showMenuItem(path, delim, getComparator());
885    }
886
887    /**
888     * Expands all menus to show menu item specified by a {@code path}
889     * parameter. Uses PathParser assigned to this operator. Uses
890     * StringComparator assigned to the operator.
891     *
892     * @param path a string identifying the menu path.
893     * @return an array of operators created tor items from the submenu.
894     * @throws TimeoutExpiredException
895     */
896    public JMenuItemOperator showMenuItem(String path) {
897        return showMenuItem(path, getComparator());
898    }
899
900    @Override
901    public Hashtable<String, Object> getDump() {
902        Hashtable<String, Object> result = super.getDump();
903        if (((JPopupMenu) getSource()).getLabel() != null) {
904            result.put(LABEL_DPROP, ((JPopupMenu) getSource()).getLabel());
905        }
906        return result;
907    }
908
909    ////////////////////////////////////////////////////////
910    //Mapping                                             //
911    /**
912     * Maps {@code JPopupMenu.add(String)} through queue
913     */
914    public JMenuItem add(final String string) {
915        return (runMapping(new MapAction<JMenuItem>("add") {
916            @Override
917            public JMenuItem map() {
918                return ((JPopupMenu) getSource()).add(string);
919            }
920        }));
921    }
922
923    /**
924     * Maps {@code JPopupMenu.add(Action)} through queue
925     */
926    public JMenuItem add(final javax.swing.Action action) {
927        return (runMapping(new MapAction<JMenuItem>("add") {
928            @Override
929            public JMenuItem map() {
930                return ((JPopupMenu) getSource()).add(action);
931            }
932        }));
933    }
934
935    /**
936     * Maps {@code JPopupMenu.add(JMenuItem)} through queue
937     */
938    public JMenuItem add(final JMenuItem jMenuItem) {
939        return (runMapping(new MapAction<JMenuItem>("add") {
940            @Override
941            public JMenuItem map() {
942                return ((JPopupMenu) getSource()).add(jMenuItem);
943            }
944        }));
945    }
946
947    /**
948     * Maps {@code JPopupMenu.addPopupMenuListener(PopupMenuListener)}
949     * through queue
950     */
951    public void addPopupMenuListener(final PopupMenuListener popupMenuListener) {
952        runMapping(new MapVoidAction("addPopupMenuListener") {
953            @Override
954            public void map() {
955                ((JPopupMenu) getSource()).addPopupMenuListener(popupMenuListener);
956            }
957        });
958    }
959
960    /**
961     * Maps {@code JPopupMenu.addSeparator()} through queue
962     */
963    public void addSeparator() {
964        runMapping(new MapVoidAction("addSeparator") {
965            @Override
966            public void map() {
967                ((JPopupMenu) getSource()).addSeparator();
968            }
969        });
970    }
971
972    /**
973     * Maps {@code JPopupMenu.getComponentIndex(Component)} through queue
974     */
975    public int getComponentIndex(final Component component) {
976        return (runMapping(new MapIntegerAction("getComponentIndex") {
977            @Override
978            public int map() {
979                return ((JPopupMenu) getSource()).getComponentIndex(component);
980            }
981        }));
982    }
983
984    /**
985     * Maps {@code JPopupMenu.getInvoker()} through queue
986     */
987    public Component getInvoker() {
988        return (runMapping(new MapAction<Component>("getInvoker") {
989            @Override
990            public Component map() {
991                return ((JPopupMenu) getSource()).getInvoker();
992            }
993        }));
994    }
995
996    /**
997     * Maps {@code JPopupMenu.getLabel()} through queue
998     */
999    public String getLabel() {
1000        return (runMapping(new MapAction<String>("getLabel") {
1001            @Override
1002            public String map() {
1003                return ((JPopupMenu) getSource()).getLabel();
1004            }
1005        }));
1006    }
1007
1008    /**
1009     * Maps {@code JPopupMenu.getMargin()} through queue
1010     */
1011    public Insets getMargin() {
1012        return (runMapping(new MapAction<Insets>("getMargin") {
1013            @Override
1014            public Insets map() {
1015                return ((JPopupMenu) getSource()).getMargin();
1016            }
1017        }));
1018    }
1019
1020    /**
1021     * Maps {@code JPopupMenu.getSelectionModel()} through queue
1022     */
1023    public SingleSelectionModel getSelectionModel() {
1024        return (runMapping(new MapAction<SingleSelectionModel>("getSelectionModel") {
1025            @Override
1026            public SingleSelectionModel map() {
1027                return ((JPopupMenu) getSource()).getSelectionModel();
1028            }
1029        }));
1030    }
1031
1032    /**
1033     * Maps {@code JPopupMenu.getSubElements()} through queue
1034     */
1035    public MenuElement[] getSubElements() {
1036        return ((MenuElement[]) runMapping(new MapAction<Object>("getSubElements") {
1037            @Override
1038            public Object map() {
1039                return ((JPopupMenu) getSource()).getSubElements();
1040            }
1041        }));
1042    }
1043
1044    /**
1045     * Maps {@code JPopupMenu.getUI()} through queue
1046     */
1047    public PopupMenuUI getUI() {
1048        return (runMapping(new MapAction<PopupMenuUI>("getUI") {
1049            @Override
1050            public PopupMenuUI map() {
1051                return ((JPopupMenu) getSource()).getUI();
1052            }
1053        }));
1054    }
1055
1056    /**
1057     * Maps {@code JPopupMenu.insert(Component, int)} through queue
1058     */
1059    public void insert(final Component component, final int i) {
1060        runMapping(new MapVoidAction("insert") {
1061            @Override
1062            public void map() {
1063                ((JPopupMenu) getSource()).insert(component, i);
1064            }
1065        });
1066    }
1067
1068    /**
1069     * Maps {@code JPopupMenu.insert(Action, int)} through queue
1070     */
1071    public void insert(final javax.swing.Action action, final int i) {
1072        runMapping(new MapVoidAction("insert") {
1073            @Override
1074            public void map() {
1075                ((JPopupMenu) getSource()).insert(action, i);
1076            }
1077        });
1078    }
1079
1080    /**
1081     * Maps {@code JPopupMenu.isBorderPainted()} through queue
1082     */
1083    public boolean isBorderPainted() {
1084        return (runMapping(new MapBooleanAction("isBorderPainted") {
1085            @Override
1086            public boolean map() {
1087                return ((JPopupMenu) getSource()).isBorderPainted();
1088            }
1089        }));
1090    }
1091
1092    /**
1093     * Maps {@code JPopupMenu.isLightWeightPopupEnabled()} through queue
1094     */
1095    public boolean isLightWeightPopupEnabled() {
1096        return (runMapping(new MapBooleanAction("isLightWeightPopupEnabled") {
1097            @Override
1098            public boolean map() {
1099                return ((JPopupMenu) getSource()).isLightWeightPopupEnabled();
1100            }
1101        }));
1102    }
1103
1104    /**
1105     * Maps {@code JPopupMenu.menuSelectionChanged(boolean)} through queue
1106     */
1107    public void menuSelectionChanged(final boolean b) {
1108        runMapping(new MapVoidAction("menuSelectionChanged") {
1109            @Override
1110            public void map() {
1111                ((JPopupMenu) getSource()).menuSelectionChanged(b);
1112            }
1113        });
1114    }
1115
1116    /**
1117     * Maps {@code JPopupMenu.pack()} through queue
1118     */
1119    public void pack() {
1120        runMapping(new MapVoidAction("pack") {
1121            @Override
1122            public void map() {
1123                ((JPopupMenu) getSource()).pack();
1124            }
1125        });
1126    }
1127
1128    /**
1129     * Maps
1130     * {@code JPopupMenu.processKeyEvent(KeyEvent, MenuElement[], MenuSelectionManager)}
1131     * through queue
1132     */
1133    public void processKeyEvent(final KeyEvent keyEvent, final MenuElement[] menuElement, final MenuSelectionManager menuSelectionManager) {
1134        runMapping(new MapVoidAction("processKeyEvent") {
1135            @Override
1136            public void map() {
1137                ((JPopupMenu) getSource()).processKeyEvent(keyEvent, menuElement, menuSelectionManager);
1138            }
1139        });
1140    }
1141
1142    /**
1143     * Maps
1144     * {@code JPopupMenu.processMouseEvent(MouseEvent, MenuElement[], MenuSelectionManager)}
1145     * through queue
1146     */
1147    public void processMouseEvent(final MouseEvent mouseEvent, final MenuElement[] menuElement, final MenuSelectionManager menuSelectionManager) {
1148        runMapping(new MapVoidAction("processMouseEvent") {
1149            @Override
1150            public void map() {
1151                ((JPopupMenu) getSource()).processMouseEvent(mouseEvent, menuElement, menuSelectionManager);
1152            }
1153        });
1154    }
1155
1156    /**
1157     * Maps {@code JPopupMenu.removePopupMenuListener(PopupMenuListener)}
1158     * through queue
1159     */
1160    public void removePopupMenuListener(final PopupMenuListener popupMenuListener) {
1161        runMapping(new MapVoidAction("removePopupMenuListener") {
1162            @Override
1163            public void map() {
1164                ((JPopupMenu) getSource()).removePopupMenuListener(popupMenuListener);
1165            }
1166        });
1167    }
1168
1169    /**
1170     * Maps {@code JPopupMenu.setBorderPainted(boolean)} through queue
1171     */
1172    public void setBorderPainted(final boolean b) {
1173        runMapping(new MapVoidAction("setBorderPainted") {
1174            @Override
1175            public void map() {
1176                ((JPopupMenu) getSource()).setBorderPainted(b);
1177            }
1178        });
1179    }
1180
1181    /**
1182     * Maps {@code JPopupMenu.setInvoker(Component)} through queue
1183     */
1184    public void setInvoker(final Component component) {
1185        runMapping(new MapVoidAction("setInvoker") {
1186            @Override
1187            public void map() {
1188                ((JPopupMenu) getSource()).setInvoker(component);
1189            }
1190        });
1191    }
1192
1193    /**
1194     * Maps {@code JPopupMenu.setLabel(String)} through queue
1195     */
1196    public void setLabel(final String string) {
1197        runMapping(new MapVoidAction("setLabel") {
1198            @Override
1199            public void map() {
1200                ((JPopupMenu) getSource()).setLabel(string);
1201            }
1202        });
1203    }
1204
1205    /**
1206     * Maps {@code JPopupMenu.setLightWeightPopupEnabled(boolean)} through queue
1207     */
1208    public void setLightWeightPopupEnabled(final boolean b) {
1209        runMapping(new MapVoidAction("setLightWeightPopupEnabled") {
1210            @Override
1211            public void map() {
1212                ((JPopupMenu) getSource()).setLightWeightPopupEnabled(b);
1213            }
1214        });
1215    }
1216
1217    /**
1218     * Maps {@code JPopupMenu.setPopupSize(int, int)} through queue
1219     */
1220    public void setPopupSize(final int i, final int i1) {
1221        runMapping(new MapVoidAction("setPopupSize") {
1222            @Override
1223            public void map() {
1224                ((JPopupMenu) getSource()).setPopupSize(i, i1);
1225            }
1226        });
1227    }
1228
1229    /**
1230     * Maps {@code JPopupMenu.setPopupSize(Dimension)} through queue
1231     */
1232    public void setPopupSize(final Dimension dimension) {
1233        runMapping(new MapVoidAction("setPopupSize") {
1234            @Override
1235            public void map() {
1236                ((JPopupMenu) getSource()).setPopupSize(dimension);
1237            }
1238        });
1239    }
1240
1241    /**
1242     * Maps {@code JPopupMenu.setSelected(Component)} through queue
1243     */
1244    public void setSelected(final Component component) {
1245        runMapping(new MapVoidAction("setSelected") {
1246            @Override
1247            public void map() {
1248                ((JPopupMenu) getSource()).setSelected(component);
1249            }
1250        });
1251    }
1252
1253    /**
1254     * Maps {@code JPopupMenu.setSelectionModel(SingleSelectionModel)}
1255     * through queue
1256     */
1257    public void setSelectionModel(final SingleSelectionModel singleSelectionModel) {
1258        runMapping(new MapVoidAction("setSelectionModel") {
1259            @Override
1260            public void map() {
1261                ((JPopupMenu) getSource()).setSelectionModel(singleSelectionModel);
1262            }
1263        });
1264    }
1265
1266    /**
1267     * Maps {@code JPopupMenu.setUI(PopupMenuUI)} through queue
1268     */
1269    public void setUI(final PopupMenuUI popupMenuUI) {
1270        runMapping(new MapVoidAction("setUI") {
1271            @Override
1272            public void map() {
1273                ((JPopupMenu) getSource()).setUI(popupMenuUI);
1274            }
1275        });
1276    }
1277
1278    /**
1279     * Maps {@code JPopupMenu.show(Component, int, int)} through queue
1280     */
1281    public void show(final Component component, final int i, final int i1) {
1282        runMapping(new MapVoidAction("show") {
1283            @Override
1284            public void map() {
1285                ((JPopupMenu) getSource()).show(component, i, i1);
1286            }
1287        });
1288    }
1289
1290    //End of mapping                                      //
1291    ////////////////////////////////////////////////////////
1292    /**
1293     * Checks component type.
1294     */
1295    public static class JPopupMenuFinder extends Finder {
1296
1297        /**
1298         * Constructs JPopupMenuFinder.
1299         *
1300         * @param sf other searching criteria.
1301         */
1302        public JPopupMenuFinder(ComponentChooser sf) {
1303            super(JPopupMenu.class, sf);
1304        }
1305
1306        /**
1307         * Constructs JPopupMenuFinder.
1308         */
1309        public JPopupMenuFinder() {
1310            super(JPopupMenu.class);
1311        }
1312
1313        @Override
1314        public boolean checkComponent(Component comp) {
1315            return (comp.isShowing()
1316                    && super.checkComponent(comp));
1317        }
1318    }
1319
1320    /**
1321     * Allwos to find a window containing JPopupMenu.
1322     */
1323    public static class JPopupWindowFinder implements ComponentChooser {
1324
1325        ComponentChooser subFinder;
1326        ComponentChooser ppFinder;
1327
1328        /**
1329         * Constructs JPopupWindowFinder.
1330         *
1331         * @param sf searching criteria for a JPopupMenu inside the window..
1332         */
1333        public JPopupWindowFinder(ComponentChooser sf) {
1334            subFinder = new JPopupMenuFinder(sf);
1335            ppFinder = new ComponentChooser() {
1336                @Override
1337                public boolean checkComponent(Component comp) {
1338                    return (comp.isShowing()
1339                            && comp.isVisible()
1340                            && subFinder.checkComponent(comp));
1341                }
1342
1343                @Override
1344                public String getDescription() {
1345                    return subFinder.getDescription();
1346                }
1347
1348                @Override
1349                public String toString() {
1350                    return "JPopupMenuOperator.JPopupWindowFinder.ComponentChooser{description = " + getDescription() + '}';
1351                }
1352            };
1353        }
1354
1355        /**
1356         * Constructs JPopupWindowFinder.
1357         */
1358        public JPopupWindowFinder() {
1359            this(ComponentSearcher.getTrueChooser("Any JPopupWindow"));
1360        }
1361
1362        @Override
1363        public boolean checkComponent(Component comp) {
1364            if (comp.isShowing() && comp instanceof Window) {
1365                ComponentSearcher cs = new ComponentSearcher((Container) comp);
1366                cs.setOutput(JemmyProperties.getCurrentOutput().createErrorOutput());
1367                return (cs.findComponent(ppFinder)
1368                        != null);
1369            }
1370            return false;
1371        }
1372
1373        @Override
1374        public String getDescription() {
1375            return subFinder.getDescription();
1376        }
1377
1378        @Override
1379        public String toString() {
1380            return "JPopupWindowFinder{" + "subFinder=" + subFinder + ", ppFinder=" + ppFinder + '}';
1381        }
1382    }
1383
1384}
1385