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.awt.Window;
29import java.awt.event.ActionListener;
30import java.io.File;
31
32import javax.swing.ComboBoxModel;
33import javax.swing.Icon;
34import javax.swing.JButton;
35import javax.swing.JComboBox;
36import javax.swing.JComponent;
37import javax.swing.JDialog;
38import javax.swing.JFileChooser;
39import javax.swing.JList;
40import javax.swing.JTextField;
41import javax.swing.JToggleButton;
42import javax.swing.ListModel;
43import javax.swing.filechooser.FileFilter;
44import javax.swing.filechooser.FileSystemView;
45import javax.swing.filechooser.FileView;
46import javax.swing.plaf.FileChooserUI;
47
48import org.netbeans.jemmy.ComponentChooser;
49import org.netbeans.jemmy.ComponentSearcher;
50import org.netbeans.jemmy.JemmyException;
51import org.netbeans.jemmy.JemmyProperties;
52import org.netbeans.jemmy.Outputable;
53import org.netbeans.jemmy.TestOut;
54import org.netbeans.jemmy.Timeoutable;
55import org.netbeans.jemmy.Timeouts;
56import org.netbeans.jemmy.Waitable;
57import org.netbeans.jemmy.Waiter;
58
59/**
60 *
61 * Class provides methods to cover main JFileChooser component functionality.
62 *
63 * @author Alexandre Iline (alexandre.iline@oracle.com)
64 *
65 */
66public class JFileChooserOperator extends JComponentOperator
67        implements Timeoutable, Outputable {
68
69    private final static long WAIT_LIST_PAINTED_TIMEOUT = 60000;
70
71    private Timeouts timeouts;
72    private TestOut output;
73    private ComponentSearcher innerSearcher;
74
75    /**
76     * Constructor.
77     *
78     * @param comp a component
79     */
80    public JFileChooserOperator(JFileChooser comp) {
81        super(comp);
82        innerSearcher = new ComponentSearcher(comp);
83        setTimeouts(JemmyProperties.getProperties().getTimeouts());
84        setOutput(JemmyProperties.getProperties().getOutput());
85    }
86
87    /**
88     * Constructor. Waits component first. Constructor can be used in
89     * complicated cases when output or timeouts should differ from default.
90     *
91     * @param env an operator to get environment from.
92     */
93    public JFileChooserOperator(Operator env) {
94        this((JFileChooser) waitComponent(JDialogOperator.
95                waitJDialog(new JFileChooserJDialogFinder(env.getOutput()),
96                        0,
97                        env.getTimeouts(),
98                        env.getOutput()),
99                new JFileChooserFinder(),
100                0,
101                env.getTimeouts(),
102                env.getOutput()));
103        copyEnvironment(env);
104    }
105
106    /**
107     * Constructor. Waits component first.
108     */
109    public JFileChooserOperator() {
110        this(getEnvironmentOperator());
111    }
112
113    /**
114     * Searches currently opened JDilog with JFileChooser inside.
115     *
116     * @return a component instance
117     */
118    public static JDialog findJFileChooserDialog() {
119        return (JDialogOperator.
120                findJDialog(new JFileChooserJDialogFinder(JemmyProperties.
121                        getCurrentOutput())));
122    }
123
124    /**
125     * Waits currently opened JDilog with JFileChooser inside.
126     *
127     * @return a component instance
128     */
129    public static JDialog waitJFileChooserDialog() {
130        return (JDialogOperator.
131                waitJDialog(new JFileChooserJDialogFinder(JemmyProperties.
132                        getCurrentOutput())));
133    }
134
135    /**
136     * Searches JFileChooser in container.
137     *
138     * @param cont a container
139     * @return a component instance
140     */
141    public static JFileChooser findJFileChooser(Container cont) {
142        return (JFileChooser) findComponent(cont, new JFileChooserFinder());
143    }
144
145    /**
146     * Searches JFileChooser in container.
147     *
148     * @param cont a container
149     * @return a component instance
150     */
151    public static JFileChooser waitJFileChooser(Container cont) {
152        return (JFileChooser) waitComponent(cont, new JFileChooserFinder());
153    }
154
155    /**
156     * Searches currently opened JFileChooser.
157     *
158     * @return a component instance
159     */
160    public static JFileChooser findJFileChooser() {
161        return findJFileChooser(findJFileChooserDialog());
162    }
163
164    /**
165     * Waits currently opened JFileChooser.
166     *
167     * @return a component instance
168     */
169    public static JFileChooser waitJFileChooser() {
170        return waitJFileChooser(waitJFileChooserDialog());
171    }
172
173    static {
174        Timeouts.initDefault("JFileChooserOperator.WaitListPaintedTimeout", WAIT_LIST_PAINTED_TIMEOUT);
175    }
176
177    @Override
178    public void setTimeouts(Timeouts timeouts) {
179        super.setTimeouts(timeouts);
180        this.timeouts = timeouts;
181    }
182
183    @Override
184    public Timeouts getTimeouts() {
185        return timeouts;
186    }
187
188    @Override
189    public void setOutput(TestOut out) {
190        output = out;
191        super.setOutput(output.createErrorOutput());
192        if (innerSearcher != null) {
193            innerSearcher.setOutput(output.createErrorOutput());
194        }
195    }
196
197    @Override
198    public TestOut getOutput() {
199        return output;
200    }
201
202    /**
203     * Returns combo box containing path (upper).
204     *
205     * @return JComboBox being used to show directories.
206     */
207    public JComboBox<?> getPathCombo() {
208        return getCombo(0);
209    }
210
211    /**
212     * Returns combo box containing file types (lower).
213     *
214     * @return JComboBox being used to show file types.
215     */
216    public JComboBox<?> getFileTypesCombo() {
217        return getCombo(1);
218    }
219
220    /**
221     * Returns approve button.
222     *
223     * @return an approve button.
224     */
225    public JButton getApproveButton() {
226        String aText = getApproveButtonText();
227        if (aText == null) {
228            aText = getUI().getApproveButtonText((JFileChooser) getSource());
229        }
230        if (aText != null) {
231            return ((JButton) innerSearcher.
232                    findComponent(new ButtonFinder(aText)));
233        } else {
234            throw (new JemmyException("JFileChooser.getApproveButtonText() "
235                    + "and getUI().getApproveButtonText "
236                    + "return null"));
237        }
238    }
239
240    /**
241     * Returns cancel button.
242     *
243     * @return a cancel button.
244     */
245    public JButton getCancelButton() {
246        return ((JButton) innerSearcher.
247                findComponent(new ComponentChooser() {
248                    @Override
249                    public boolean checkComponent(Component comp) {
250                        return (comp != null
251                                && comp instanceof JButton
252                                && comp.getParent() != null
253                                && !(comp.getParent() instanceof JComboBox)
254                                && ((JButton) comp).getText() != null
255                                && ((JButton) comp).getText().length() != 0);
256                    }
257
258                    @Override
259                    public String getDescription() {
260                        return "JButton";
261                    }
262
263                    @Override
264                    public String toString() {
265                        return "JFileChooserOperator.getCancelButton.ComponentChooser{description = " + getDescription() + '}';
266                    }
267                }, 1));
268    }
269
270    /**
271     * Returns "Home" button.
272     *
273     * @return a "home" button.
274     */
275    public JButton getHomeButton() {
276        return getNoTextButton(1);
277    }
278
279    /**
280     * Returns "Up One Level" button.
281     *
282     * @return a "Up One Level" button.
283     */
284    public JButton getUpLevelButton() {
285        return getNoTextButton(0);
286    }
287
288    /**
289     * Returns a toggle button being used to switch to list view.
290     *
291     * @return a "list mode" button.
292     */
293    public JToggleButton getListToggleButton() {
294        return getToggleButton(0);
295    }
296
297    /**
298     * Returns a toggle button being used to switch to detals view.
299     *
300     * @return a "list mode" button.
301     */
302    public JToggleButton getDetailsToggleButton() {
303        return getToggleButton(1);
304    }
305
306    /**
307     * Returns field which can be used to type path.
308     *
309     * @return a text field being used for path typing.
310     */
311    public JTextField getPathField() {
312        return ((JTextField) innerSearcher.
313                findComponent(new ComponentChooser() {
314                    @Override
315                    public boolean checkComponent(Component comp) {
316                        return (comp != null
317                                && comp instanceof JTextField);
318                    }
319
320                    @Override
321                    public String getDescription() {
322                        return "JTextField";
323                    }
324
325                    @Override
326                    public String toString() {
327                        return "JFileChooserOperator.getPathField.ComponentChooser{description = " + getDescription() + '}';
328                    }
329                }));
330    }
331
332    /**
333     * Returns file list.
334     *
335     * @return a list being used to display directory content.
336     */
337    public JList<?> getFileList() {
338        return ((JList) innerSearcher.
339                findComponent(new ComponentChooser() {
340                    @Override
341                    public boolean checkComponent(Component comp) {
342                        return (comp != null
343                                && comp instanceof JList);
344                    }
345
346                    @Override
347                    public String getDescription() {
348                        return "JList";
349                    }
350
351                    @Override
352                    public String toString() {
353                        return "JFileChooserOperator.getFileList.ComponentChooser{description = " + getDescription() + '}';
354                    }
355                }));
356    }
357
358    /**
359     * Pushes approve button.
360     */
361    public void approve() {
362        getQueueTool().waitEmpty();
363        output.printTrace("Push approve button in JFileChooser\n    : "
364                + toStringSource());
365        JButtonOperator approveOper = new JButtonOperator(getApproveButton());
366        approveOper.copyEnvironment(this);
367        approveOper.setOutput(output.createErrorOutput());
368        approveOper.push();
369    }
370
371    /**
372     * Pushes cancel button.
373     */
374    public void cancel() {
375        output.printTrace("Push cancel button in JFileChooser\n    : "
376                + toStringSource());
377        JButtonOperator cancelOper = new JButtonOperator(getCancelButton());
378        cancelOper.copyEnvironment(this);
379        cancelOper.setOutput(output.createErrorOutput());
380        cancelOper.push();
381    }
382
383    /**
384     * Types file name into text field and pushes approve button.
385     *
386     * @param fileName a file to choose.
387     */
388    public void chooseFile(String fileName) {
389        getQueueTool().waitEmpty();
390        output.printTrace("Choose file by JFileChooser\n    : " + fileName
391                + "\n    : " + toStringSource());
392        JTextFieldOperator fieldOper = new JTextFieldOperator(getPathField());
393        fieldOper.copyEnvironment(this);
394        fieldOper.setOutput(output.createErrorOutput());
395        //workaround
396        fieldOper.setText(fileName);
397        //fieldOper.clearText();
398        //fieldOper.typeText(fileName);
399        //approveSelection();
400        approve();
401    }
402
403    /**
404     * Pushes "Up One Level" button.
405     *
406     * @return new current directory
407     */
408    public File goUpLevel() {
409        getQueueTool().waitEmpty();
410        output.printTrace("Go up level in JFileChooser\n    : "
411                + toStringSource());
412        //workaround
413        setCurrentDirectory(getCurrentDirectory().getParentFile());
414        //JButtonOperator upOper = new JButtonOperator(getUpLevelButton());
415        //upOper.copyEnvironment(this);
416        //upOper.setOutput(output.createErrorOutput());
417        //upOper.push();
418        waitPainted(-1);
419        return getCurrentDirectory();
420    }
421
422    /**
423     * Pushes "Home" button.
424     *
425     * @return new current directory
426     */
427    public File goHome() {
428        getQueueTool().waitEmpty();
429        output.printTrace("Go home in JFileChooser\n    : "
430                + toStringSource());
431        JButtonOperator homeOper = new JButtonOperator(getHomeButton());
432        homeOper.copyEnvironment(this);
433        homeOper.setOutput(output.createErrorOutput());
434        homeOper.push();
435        waitPainted(-1);
436        return getCurrentDirectory();
437    }
438
439    /**
440     * Clicks on file in the list.
441     *
442     * @param index Ordinal file index.
443     * @param clickCount click count
444     */
445    public void clickOnFile(int index, int clickCount) {
446        getQueueTool().waitEmpty();
447        output.printTrace("Click " + Integer.toString(clickCount)
448                + "times on " + Integer.toString(index)
449                + "`th file in JFileChooser\n    : "
450                + toStringSource());
451        JListOperator listOper = new JListOperator(getFileList());
452        waitPainted(index);
453        listOper.copyEnvironment(this);
454        listOper.setOutput(output.createErrorOutput());
455        listOper.clickOnItem(index, clickCount);
456    }
457
458    /**
459     * Clicks on file in the list.
460     *
461     * @param file File name (foo.c). Do not use full path (/tmp/foo.c) here.
462     * @param comparator a comparator defining string comparision criteria
463     * @param clickCount click count
464     */
465    public void clickOnFile(String file, StringComparator comparator, int clickCount) {
466        output.printTrace("Click " + Integer.toString(clickCount)
467                + "times on \"" + file
468                + "\" file in JFileChooser\n    : "
469                + toStringSource());
470        clickOnFile(findFileIndex(file, comparator), clickCount);
471    }
472
473    /**
474     * Clicks on file in the list.
475     *
476     * @param file File name (foo.c). Do not use full path (/tmp/foo.c) here.
477     * @param ce Compare exactly. If true, text can be a substring of caption.
478     * @param cc Compare case sensitively. If true, both text and caption are
479     * @param clickCount click count
480     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
481     * @deprecated Use clickOnFile(String, int) or clickOnFile(String,
482     * StringComparator, int)
483     */
484    @Deprecated
485    public void clickOnFile(String file, boolean ce, boolean cc, int clickCount) {
486        clickOnFile(file, new DefaultStringComparator(ce, cc), clickCount);
487    }
488
489    /**
490     * Clicks on file in the list.
491     *
492     * @param file File name (foo.c). Do not use full path (/tmp/foo.c) here.
493     * @param clickCount click count
494     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
495     */
496    public void clickOnFile(String file, int clickCount) {
497        clickOnFile(file, getComparator(), clickCount);
498    }
499
500    /**
501     * Clicks on file in the list.
502     *
503     * @param file File name (foo.c). Do not use full path (/tmp/foo.c) here.
504     * @param comparator a comparator defining string comparision criteria
505     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
506     */
507    public void clickOnFile(String file, StringComparator comparator) {
508        clickOnFile(file, comparator, 1);
509    }
510
511    /**
512     * Clicks 1 time on file in the list.
513     *
514     * @param file File name (foo.c). Do not use full path (/tmp/foo.c) here.
515     * @param ce Compare exactly. If true, text can be a substring of caption.
516     * @param cc Compare case sensitively. If true, both text and caption are
517     * @see #clickOnFile
518     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
519     * @deprecated Use clickOnFile(String) or clickOnFile(String,
520     * StringComparator)
521     */
522    @Deprecated
523    public void clickOnFile(String file, boolean ce, boolean cc) {
524        clickOnFile(file, ce, cc, 1);
525    }
526
527    /**
528     * Clicks 1 time on file in the list.
529     *
530     * @param file File name (foo.c). Do not use full path (/tmp/foo.c) here.
531     * @see #clickOnFile
532     * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean)
533     */
534    public void clickOnFile(String file) {
535        clickOnFile(file, 1);
536    }
537
538    /**
539     * Enters into subdirectory.
540     *
541     * @param dir A directory to enter into.
542     * @param comparator a comparator defining string comparision criteria
543     * @return new current directory
544     */
545    public File enterSubDir(String dir, StringComparator comparator) {
546        getQueueTool().waitEmpty();
547        selectFile(dir, comparator);
548        int index = findFileIndex(dir, comparator);
549        waitPainted(index);
550        setCurrentDirectory(getSelectedFile());
551        return getCurrentDirectory();
552    }
553
554    /**
555     * Enters into subdir curently displayed in the list.
556     *
557     * @param dir Directory name (tmp1). Do not use full path (/tmp/tmp1) here.
558     * @param ce Compare exactly. If true, text can be a substring of caption.
559     * @param cc Compare case sensitively. If true, both text and caption are
560     * @return new current directory
561     * @see #clickOnFile
562     * @deprecated Use enterSubDir(String) or enterSubDir(String,
563     * StringComparator)
564     */
565    @Deprecated
566    public File enterSubDir(String dir, boolean ce, boolean cc) {
567        return enterSubDir(dir, new DefaultStringComparator(ce, cc));
568    }
569
570    /**
571     * Enters into subdir curently displayed in the list.
572     *
573     * @param dir Directory name (tmp1). Do not use full path (/tmp/tmp1) here.
574     * @return new current directory
575     * @see #clickOnFile
576     */
577    public File enterSubDir(String dir) {
578        return enterSubDir(dir, getComparator());
579    }
580
581    /**
582     * Selects a file curently in the list.
583     *
584     * @param file File name (foo.c). Do not use full path (/tmp/foo.c) here.
585     * @param comparator a comparator defining string comparision criteria
586     * @see #clickOnFile
587     */
588    public void selectFile(String file, StringComparator comparator) {
589        getQueueTool().waitEmpty();
590        int index = findFileIndex(file, comparator);
591        JListOperator listOper = new JListOperator(getFileList());
592        waitPainted(index);
593        listOper.copyEnvironment(this);
594        listOper.setOutput(output.createErrorOutput());
595        listOper.setSelectedIndex(index);
596    }
597
598    /**
599     * Selects a file curently in the list.
600     *
601     * @param file File name (foo.c). Do not use full path (/tmp/foo.c) here.
602     * @param ce Compare exactly. If true, text can be a substring of caption.
603     * @param cc Compare case sensitively. If true, both text and caption are
604     * @see #clickOnFile
605     * @deprecated Use selectFile(String) or selectFile(String,
606     * StringComparator)
607     */
608    @Deprecated
609    public void selectFile(String file, boolean ce, boolean cc) {
610        clickOnFile(file, ce, cc);
611    }
612
613    /**
614     * Selects a file curently in the list.
615     *
616     * @param file File name (foo.c). Do not use full path (/tmp/foo.c) here.
617     * @see #clickOnFile
618     */
619    public void selectFile(String file) {
620        clickOnFile(file);
621    }
622
623    /**
624     * Selects directory from the combo box above.
625     *
626     * @param dir Directory name (tmp1). Do not use full path (/tmp/tmp1) here.
627     * @param comparator a comparator defining string comparision criteria
628     */
629    public void selectPathDirectory(String dir, StringComparator comparator) {
630        getQueueTool().waitEmpty();
631        output.printTrace("Select \"" + dir + "\" directory in JFileChooser\n    : "
632                + toStringSource());
633        JComboBoxOperator comboOper = new JComboBoxOperator(getPathCombo());
634        comboOper.copyEnvironment(this);
635        comboOper.setOutput(output.createErrorOutput());
636        //workaround
637        comboOper.setSelectedIndex(findDirIndex(dir, comparator));
638        //comboOper.selectItem(findDirIndex(dir, comparator));
639        waitPainted(-1);
640    }
641
642    /**
643     * Selects directory from the combo box above.
644     *
645     * @param dir Directory name (tmp1). Do not use full path (/tmp/tmp1) here.
646     * @param ce Compare exactly. If true, text can be a substring of caption.
647     * @param cc Compare case sensitively. If true, both text and caption are
648     * @deprecated Use selectPathDirectory(String) or
649     * selectPathDirectory(String, StringComparator)
650     */
651    @Deprecated
652    public void selectPathDirectory(String dir, boolean ce, boolean cc) {
653        selectPathDirectory(dir, new DefaultStringComparator(ce, cc));
654    }
655
656    /**
657     * Selects directory from the combo box above.
658     *
659     * @param dir Directory name (tmp1). Do not use full path (/tmp/tmp1) here.
660     */
661    public void selectPathDirectory(String dir) {
662        selectPathDirectory(dir, getComparator());
663    }
664
665    /**
666     * Selects file type from the combo box below.
667     *
668     * @param filter a pattern for choosing a file type.
669     * @param comparator a comparator defining string comparision criteria
670     */
671    public void selectFileType(String filter, StringComparator comparator) {
672        getQueueTool().waitEmpty();
673        output.printTrace("Select \"" + filter + "\" file type in JFileChooser\n    : "
674                + toStringSource());
675        JComboBoxOperator comboOper = new JComboBoxOperator(getFileTypesCombo());
676        comboOper.copyEnvironment(this);
677        comboOper.setOutput(output.createErrorOutput());
678        //workaround
679        comboOper.setSelectedIndex(findFileTypeIndex(filter, comparator));
680        //        comboOper.selectItem(findFileTypeIndex(filter, comparator));
681        waitPainted(-1);
682    }
683
684    /**
685     * Selects file type from the combo box below.
686     *
687     * @param filter a pattern for choosing a file type.
688     * @param ce Compare exactly. If true, text can be a substring of caption.
689     * @param cc Compare case sensitively. If true, both text and caption are
690     * @deprecated Use selectFileType(String) or selectFileType(String,
691     * StringComparator)
692     */
693    @Deprecated
694    public void selectFileType(String filter, boolean ce, boolean cc) {
695        selectFileType(filter, new DefaultStringComparator(ce, cc));
696    }
697
698    /**
699     * Selects file type from the combo box below.
700     *
701     * @param filter a pattern for choosing a file type.
702     */
703    public void selectFileType(String filter) {
704        selectFileType(filter, getComparator());
705    }
706
707    /**
708     * Checks if file is currently displayed in the list.
709     *
710     * @param file File name (foo.c). Do not use full path (/tmp/foo.c) here.
711     * @param comparator a comparator defining string comparision criteria
712     * @return true if file is displayed.
713     */
714    public boolean checkFileDisplayed(String file, StringComparator comparator) {
715        waitPainted(-1);
716        return findFileIndex(file, comparator) != -1;
717    }
718
719    /**
720     * Checks if file is currently displayed in the list.
721     *
722     * @param file File name (foo.c). Do not use full path (/tmp/foo.c) here.
723     * @param ce Compare exactly. If true, text can be a substring of caption.
724     * @param cc Compare case sensitively. If true, both text and caption are
725     * @return true if file is displayed.
726     * @deprecated Use checkFileDisplayed(String) or checkFileDisplayed(String,
727     * StringComparator)
728     */
729    @Deprecated
730    public boolean checkFileDisplayed(String file, boolean ce, boolean cc) {
731        return checkFileDisplayed(file, new DefaultStringComparator(ce, cc));
732    }
733
734    /**
735     * Checks if file is currently displayed in the list.
736     *
737     * @param file File name (foo.c). Do not use full path (/tmp/foo.c) here.
738     * @return true if file is displayed.
739     */
740    public boolean checkFileDisplayed(String file) {
741        return checkFileDisplayed(file, getComparator());
742    }
743
744    /**
745     * Return count of files currently displayed.
746     *
747     * @return a number of items in the file list.
748     */
749    public int getFileCount() {
750        waitPainted(-1);
751        return getFileList().getModel().getSize();
752    }
753
754    /**
755     * Return files currently displayed.
756     *
757     * @return an array of items from the file list.
758     */
759    public File[] getFiles() {
760        waitPainted(-1);
761        ListModel<?> listModel = getFileList().getModel();
762        File[] result = new File[listModel.getSize()];
763        for (int i = 0; i < listModel.getSize(); i++) {
764            result[i] = (File) listModel.getElementAt(i);
765        }
766        return result;
767    }
768
769    /**
770     * Waits for the file list to have required number of items.
771     *
772     * @param count Number of files to wait.
773     */
774    public void waitFileCount(final int count) {
775        waitState(new ComponentChooser() {
776            @Override
777            public boolean checkComponent(Component comp) {
778                return getFileCount() == count;
779            }
780
781            @Override
782            public String getDescription() {
783                return ("Count of files to be equal "
784                        + Integer.toString(count));
785            }
786
787            @Override
788            public String toString() {
789                return "JFileChooserOperator.waitFileCount.ComponentChooser{description = " + getDescription() + '}';
790            }
791        });
792    }
793
794    /**
795     * Waits for a file to be displayed in the file list.
796     *
797     * @param fileName a file to wait.
798     */
799    public void waitFileDisplayed(final String fileName) {
800        waitState(new ComponentChooser() {
801            @Override
802            public boolean checkComponent(Component comp) {
803                return checkFileDisplayed(fileName);
804            }
805
806            @Override
807            public String getDescription() {
808                return "\"" + fileName + "\"file to be displayed";
809            }
810
811            @Override
812            public String toString() {
813                return "JFileChooserOperator.waitFileDisplayed.ComponentChooser{description = " + getDescription() + '}';
814            }
815        });
816    }
817
818    ////////////////////////////////////////////////////////
819    //Mapping                                             //
820    /**
821     * Maps {@code JFileChooser.accept(File)} through queue
822     */
823    public boolean accept(final File file) {
824        return (runMapping(new MapBooleanAction("accept") {
825            @Override
826            public boolean map() {
827                return ((JFileChooser) getSource()).accept(file);
828            }
829        }));
830    }
831
832    /**
833     * Maps {@code JFileChooser.addActionListener(ActionListener)} through queue
834     */
835    public void addActionListener(final ActionListener actionListener) {
836        runMapping(new MapVoidAction("addActionListener") {
837            @Override
838            public void map() {
839                ((JFileChooser) getSource()).addActionListener(actionListener);
840            }
841        });
842    }
843
844    /**
845     * Maps {@code JFileChooser.addChoosableFileFilter(FileFilter)} through queue
846     */
847    public void addChoosableFileFilter(final FileFilter fileFilter) {
848        runMapping(new MapVoidAction("addChoosableFileFilter") {
849            @Override
850            public void map() {
851                ((JFileChooser) getSource()).addChoosableFileFilter(fileFilter);
852            }
853        });
854    }
855
856    /**
857     * Maps {@code JFileChooser.approveSelection()} through queue
858     */
859    public void approveSelection() {
860        runMapping(new MapVoidAction("approveSelection") {
861            @Override
862            public void map() {
863                ((JFileChooser) getSource()).approveSelection();
864            }
865        });
866    }
867
868    /**
869     * Maps {@code JFileChooser.cancelSelection()} through queue
870     */
871    public void cancelSelection() {
872        runMapping(new MapVoidAction("cancelSelection") {
873            @Override
874            public void map() {
875                ((JFileChooser) getSource()).cancelSelection();
876            }
877        });
878    }
879
880    /**
881     * Maps {@code JFileChooser.changeToParentDirectory()} through queue
882     */
883    public void changeToParentDirectory() {
884        runMapping(new MapVoidAction("changeToParentDirectory") {
885            @Override
886            public void map() {
887                ((JFileChooser) getSource()).changeToParentDirectory();
888            }
889        });
890    }
891
892    /**
893     * Maps {@code JFileChooser.ensureFileIsVisible(File)} through queue
894     */
895    public void ensureFileIsVisible(final File file) {
896        runMapping(new MapVoidAction("ensureFileIsVisible") {
897            @Override
898            public void map() {
899                ((JFileChooser) getSource()).ensureFileIsVisible(file);
900            }
901        });
902    }
903
904    /**
905     * Maps {@code JFileChooser.getAcceptAllFileFilter()} through queue
906     */
907    public FileFilter getAcceptAllFileFilter() {
908        return (runMapping(new MapAction<FileFilter>("getAcceptAllFileFilter") {
909            @Override
910            public FileFilter map() {
911                return ((JFileChooser) getSource()).getAcceptAllFileFilter();
912            }
913        }));
914    }
915
916    /**
917     * Maps {@code JFileChooser.getAccessory()} through queue
918     */
919    public JComponent getAccessory() {
920        return (runMapping(new MapAction<JComponent>("getAccessory") {
921            @Override
922            public JComponent map() {
923                return ((JFileChooser) getSource()).getAccessory();
924            }
925        }));
926    }
927
928    /**
929     * Maps {@code JFileChooser.getApproveButtonMnemonic()} through queue
930     */
931    public int getApproveButtonMnemonic() {
932        return (runMapping(new MapIntegerAction("getApproveButtonMnemonic") {
933            @Override
934            public int map() {
935                return ((JFileChooser) getSource()).getApproveButtonMnemonic();
936            }
937        }));
938    }
939
940    /**
941     * Maps {@code JFileChooser.getApproveButtonText()} through queue
942     */
943    public String getApproveButtonText() {
944        return (runMapping(new MapAction<String>("getApproveButtonText") {
945            @Override
946            public String map() {
947                return ((JFileChooser) getSource()).getApproveButtonText();
948            }
949        }));
950    }
951
952    /**
953     * Maps {@code JFileChooser.getApproveButtonToolTipText()} through queue
954     */
955    public String getApproveButtonToolTipText() {
956        return (runMapping(new MapAction<String>("getApproveButtonToolTipText") {
957            @Override
958            public String map() {
959                return ((JFileChooser) getSource()).getApproveButtonToolTipText();
960            }
961        }));
962    }
963
964    /**
965     * Maps {@code JFileChooser.getChoosableFileFilters()} through queue
966     */
967    public FileFilter[] getChoosableFileFilters() {
968        return ((FileFilter[]) runMapping(new MapAction<Object>("getChoosableFileFilters") {
969            @Override
970            public Object map() {
971                return ((JFileChooser) getSource()).getChoosableFileFilters();
972            }
973        }));
974    }
975
976    /**
977     * Maps {@code JFileChooser.getCurrentDirectory()} through queue
978     */
979    public File getCurrentDirectory() {
980        return (runMapping(new MapAction<File>("getCurrentDirectory") {
981            @Override
982            public File map() {
983                return ((JFileChooser) getSource()).getCurrentDirectory();
984            }
985        }));
986    }
987
988    /**
989     * Maps {@code JFileChooser.getDescription(File)} through queue
990     */
991    public String getDescription(final File file) {
992        return (runMapping(new MapAction<String>("getDescription") {
993            @Override
994            public String map() {
995                return ((JFileChooser) getSource()).getDescription(file);
996            }
997        }));
998    }
999
1000    /**
1001     * Maps {@code JFileChooser.getDialogTitle()} through queue
1002     */
1003    public String getDialogTitle() {
1004        return (runMapping(new MapAction<String>("getDialogTitle") {
1005            @Override
1006            public String map() {
1007                return ((JFileChooser) getSource()).getDialogTitle();
1008            }
1009        }));
1010    }
1011
1012    /**
1013     * Maps {@code JFileChooser.getDialogType()} through queue
1014     */
1015    public int getDialogType() {
1016        return (runMapping(new MapIntegerAction("getDialogType") {
1017            @Override
1018            public int map() {
1019                return ((JFileChooser) getSource()).getDialogType();
1020            }
1021        }));
1022    }
1023
1024    /**
1025     * Maps {@code JFileChooser.getFileFilter()} through queue
1026     */
1027    public FileFilter getFileFilter() {
1028        return (runMapping(new MapAction<FileFilter>("getFileFilter") {
1029            @Override
1030            public FileFilter map() {
1031                return ((JFileChooser) getSource()).getFileFilter();
1032            }
1033        }));
1034    }
1035
1036    /**
1037     * Maps {@code JFileChooser.getFileSelectionMode()} through queue
1038     */
1039    public int getFileSelectionMode() {
1040        return (runMapping(new MapIntegerAction("getFileSelectionMode") {
1041            @Override
1042            public int map() {
1043                return ((JFileChooser) getSource()).getFileSelectionMode();
1044            }
1045        }));
1046    }
1047
1048    /**
1049     * Maps {@code JFileChooser.getFileSystemView()} through queue
1050     */
1051    public FileSystemView getFileSystemView() {
1052        return (runMapping(new MapAction<FileSystemView>("getFileSystemView") {
1053            @Override
1054            public FileSystemView map() {
1055                return ((JFileChooser) getSource()).getFileSystemView();
1056            }
1057        }));
1058    }
1059
1060    /**
1061     * Maps {@code JFileChooser.getFileView()} through queue
1062     */
1063    public FileView getFileView() {
1064        return (runMapping(new MapAction<FileView>("getFileView") {
1065            @Override
1066            public FileView map() {
1067                return ((JFileChooser) getSource()).getFileView();
1068            }
1069        }));
1070    }
1071
1072    /**
1073     * Maps {@code JFileChooser.getIcon(File)} through queue
1074     */
1075    public Icon getIcon(final File file) {
1076        return (runMapping(new MapAction<Icon>("getIcon") {
1077            @Override
1078            public Icon map() {
1079                return ((JFileChooser) getSource()).getIcon(file);
1080            }
1081        }));
1082    }
1083
1084    /**
1085     * Maps {@code JFileChooser.getName(File)} through queue
1086     */
1087    public String getName(final File file) {
1088        return (runMapping(new MapAction<String>("getName") {
1089            @Override
1090            public String map() {
1091                return ((JFileChooser) getSource()).getName(file);
1092            }
1093        }));
1094    }
1095
1096    /**
1097     * Maps {@code JFileChooser.getSelectedFile()} through queue
1098     */
1099    public File getSelectedFile() {
1100        return (runMapping(new MapAction<File>("getSelectedFile") {
1101            @Override
1102            public File map() {
1103                return ((JFileChooser) getSource()).getSelectedFile();
1104            }
1105        }));
1106    }
1107
1108    /**
1109     * Maps {@code JFileChooser.getSelectedFiles()} through queue
1110     */
1111    public File[] getSelectedFiles() {
1112        return ((File[]) runMapping(new MapAction<Object>("getSelectedFiles") {
1113            @Override
1114            public Object map() {
1115                return ((JFileChooser) getSource()).getSelectedFiles();
1116            }
1117        }));
1118    }
1119
1120    /**
1121     * Maps {@code JFileChooser.getTypeDescription(File)} through queue
1122     */
1123    public String getTypeDescription(final File file) {
1124        return (runMapping(new MapAction<String>("getTypeDescription") {
1125            @Override
1126            public String map() {
1127                return ((JFileChooser) getSource()).getTypeDescription(file);
1128            }
1129        }));
1130    }
1131
1132    /**
1133     * Maps {@code JFileChooser.getUI()} through queue
1134     */
1135    public FileChooserUI getUI() {
1136        return (runMapping(new MapAction<FileChooserUI>("getUI") {
1137            @Override
1138            public FileChooserUI map() {
1139                return ((JFileChooser) getSource()).getUI();
1140            }
1141        }));
1142    }
1143
1144    /**
1145     * Maps {@code JFileChooser.isDirectorySelectionEnabled()} through queue
1146     */
1147    public boolean isDirectorySelectionEnabled() {
1148        return (runMapping(new MapBooleanAction("isDirectorySelectionEnabled") {
1149            @Override
1150            public boolean map() {
1151                return ((JFileChooser) getSource()).isDirectorySelectionEnabled();
1152            }
1153        }));
1154    }
1155
1156    /**
1157     * Maps {@code JFileChooser.isFileHidingEnabled()} through queue
1158     */
1159    public boolean isFileHidingEnabled() {
1160        return (runMapping(new MapBooleanAction("isFileHidingEnabled") {
1161            @Override
1162            public boolean map() {
1163                return ((JFileChooser) getSource()).isFileHidingEnabled();
1164            }
1165        }));
1166    }
1167
1168    /**
1169     * Maps {@code JFileChooser.isFileSelectionEnabled()} through queue
1170     */
1171    public boolean isFileSelectionEnabled() {
1172        return (runMapping(new MapBooleanAction("isFileSelectionEnabled") {
1173            @Override
1174            public boolean map() {
1175                return ((JFileChooser) getSource()).isFileSelectionEnabled();
1176            }
1177        }));
1178    }
1179
1180    /**
1181     * Maps {@code JFileChooser.isMultiSelectionEnabled()} through queue
1182     */
1183    public boolean isMultiSelectionEnabled() {
1184        return (runMapping(new MapBooleanAction("isMultiSelectionEnabled") {
1185            @Override
1186            public boolean map() {
1187                return ((JFileChooser) getSource()).isMultiSelectionEnabled();
1188            }
1189        }));
1190    }
1191
1192    /**
1193     * Maps {@code JFileChooser.isTraversable(File)} through queue
1194     */
1195    public boolean isTraversable(final File file) {
1196        return (runMapping(new MapBooleanAction("isTraversable") {
1197            @Override
1198            public boolean map() {
1199                return ((JFileChooser) getSource()).isTraversable(file);
1200            }
1201        }));
1202    }
1203
1204    /**
1205     * Maps {@code JFileChooser.removeActionListener(ActionListener)}
1206     * through queue
1207     */
1208    public void removeActionListener(final ActionListener actionListener) {
1209        runMapping(new MapVoidAction("removeActionListener") {
1210            @Override
1211            public void map() {
1212                ((JFileChooser) getSource()).removeActionListener(actionListener);
1213            }
1214        });
1215    }
1216
1217    /**
1218     * Maps {@code JFileChooser.removeChoosableFileFilter(FileFilter)}
1219     * through queue
1220     */
1221    public boolean removeChoosableFileFilter(final FileFilter fileFilter) {
1222        return (runMapping(new MapBooleanAction("removeChoosableFileFilter") {
1223            @Override
1224            public boolean map() {
1225                return ((JFileChooser) getSource()).removeChoosableFileFilter(fileFilter);
1226            }
1227        }));
1228    }
1229
1230    /**
1231     * Maps {@code JFileChooser.rescanCurrentDirectory()} through queue
1232     */
1233    public void rescanCurrentDirectory() {
1234        runMapping(new MapVoidAction("rescanCurrentDirectory") {
1235            @Override
1236            public void map() {
1237                ((JFileChooser) getSource()).rescanCurrentDirectory();
1238            }
1239        });
1240    }
1241
1242    /**
1243     * Maps {@code JFileChooser.resetChoosableFileFilters()} through queue
1244     */
1245    public void resetChoosableFileFilters() {
1246        runMapping(new MapVoidAction("resetChoosableFileFilters") {
1247            @Override
1248            public void map() {
1249                ((JFileChooser) getSource()).resetChoosableFileFilters();
1250            }
1251        });
1252    }
1253
1254    /**
1255     * Maps {@code JFileChooser.setAccessory(JComponent)} through queue
1256     */
1257    public void setAccessory(final JComponent jComponent) {
1258        runMapping(new MapVoidAction("setAccessory") {
1259            @Override
1260            public void map() {
1261                ((JFileChooser) getSource()).setAccessory(jComponent);
1262            }
1263        });
1264    }
1265
1266    /**
1267     * Maps {@code JFileChooser.setApproveButtonMnemonic(char)} through queue
1268     */
1269    public void setApproveButtonMnemonic(final char c) {
1270        runMapping(new MapVoidAction("setApproveButtonMnemonic") {
1271            @Override
1272            public void map() {
1273                ((JFileChooser) getSource()).setApproveButtonMnemonic(c);
1274            }
1275        });
1276    }
1277
1278    /**
1279     * Maps {@code JFileChooser.setApproveButtonMnemonic(int)} through queue
1280     */
1281    public void setApproveButtonMnemonic(final int i) {
1282        runMapping(new MapVoidAction("setApproveButtonMnemonic") {
1283            @Override
1284            public void map() {
1285                ((JFileChooser) getSource()).setApproveButtonMnemonic(i);
1286            }
1287        });
1288    }
1289
1290    /**
1291     * Maps {@code JFileChooser.setApproveButtonText(String)} through queue
1292     */
1293    public void setApproveButtonText(final String string) {
1294        runMapping(new MapVoidAction("setApproveButtonText") {
1295            @Override
1296            public void map() {
1297                ((JFileChooser) getSource()).setApproveButtonText(string);
1298            }
1299        });
1300    }
1301
1302    /**
1303     * Maps {@code JFileChooser.setApproveButtonToolTipText(String)}
1304     * through queue
1305     */
1306    public void setApproveButtonToolTipText(final String string) {
1307        runMapping(new MapVoidAction("setApproveButtonToolTipText") {
1308            @Override
1309            public void map() {
1310                ((JFileChooser) getSource()).setApproveButtonToolTipText(string);
1311            }
1312        });
1313    }
1314
1315    /**
1316     * Maps {@code JFileChooser.setCurrentDirectory(File)} through queue
1317     */
1318    public void setCurrentDirectory(final File file) {
1319        runMapping(new MapVoidAction("setCurrentDirectory") {
1320            @Override
1321            public void map() {
1322                ((JFileChooser) getSource()).setCurrentDirectory(file);
1323            }
1324        });
1325    }
1326
1327    /**
1328     * Maps {@code JFileChooser.setDialogTitle(String)} through queue
1329     */
1330    public void setDialogTitle(final String string) {
1331        runMapping(new MapVoidAction("setDialogTitle") {
1332            @Override
1333            public void map() {
1334                ((JFileChooser) getSource()).setDialogTitle(string);
1335            }
1336        });
1337    }
1338
1339    /**
1340     * Maps {@code JFileChooser.setDialogType(int)} through queue
1341     */
1342    public void setDialogType(final int i) {
1343        runMapping(new MapVoidAction("setDialogType") {
1344            @Override
1345            public void map() {
1346                ((JFileChooser) getSource()).setDialogType(i);
1347            }
1348        });
1349    }
1350
1351    /**
1352     * Maps {@code JFileChooser.setFileFilter(FileFilter)} through queue
1353     */
1354    public void setFileFilter(final FileFilter fileFilter) {
1355        runMapping(new MapVoidAction("setFileFilter") {
1356            @Override
1357            public void map() {
1358                ((JFileChooser) getSource()).setFileFilter(fileFilter);
1359            }
1360        });
1361    }
1362
1363    /**
1364     * Maps {@code JFileChooser.setFileHidingEnabled(boolean)} through queue
1365     */
1366    public void setFileHidingEnabled(final boolean b) {
1367        runMapping(new MapVoidAction("setFileHidingEnabled") {
1368            @Override
1369            public void map() {
1370                ((JFileChooser) getSource()).setFileHidingEnabled(b);
1371            }
1372        });
1373    }
1374
1375    /**
1376     * Maps {@code JFileChooser.setFileSelectionMode(int)} through queue
1377     */
1378    public void setFileSelectionMode(final int i) {
1379        runMapping(new MapVoidAction("setFileSelectionMode") {
1380            @Override
1381            public void map() {
1382                ((JFileChooser) getSource()).setFileSelectionMode(i);
1383            }
1384        });
1385    }
1386
1387    /**
1388     * Maps {@code JFileChooser.setFileSystemView(FileSystemView)} through queue
1389     */
1390    public void setFileSystemView(final FileSystemView fileSystemView) {
1391        runMapping(new MapVoidAction("setFileSystemView") {
1392            @Override
1393            public void map() {
1394                ((JFileChooser) getSource()).setFileSystemView(fileSystemView);
1395            }
1396        });
1397    }
1398
1399    /**
1400     * Maps {@code JFileChooser.setFileView(FileView)} through queue
1401     */
1402    public void setFileView(final FileView fileView) {
1403        runMapping(new MapVoidAction("setFileView") {
1404            @Override
1405            public void map() {
1406                ((JFileChooser) getSource()).setFileView(fileView);
1407            }
1408        });
1409    }
1410
1411    /**
1412     * Maps {@code JFileChooser.setMultiSelectionEnabled(boolean)} through queue
1413     */
1414    public void setMultiSelectionEnabled(final boolean b) {
1415        runMapping(new MapVoidAction("setMultiSelectionEnabled") {
1416            @Override
1417            public void map() {
1418                ((JFileChooser) getSource()).setMultiSelectionEnabled(b);
1419            }
1420        });
1421    }
1422
1423    /**
1424     * Maps {@code JFileChooser.setSelectedFile(File)} through queue
1425     */
1426    public void setSelectedFile(final File file) {
1427        runMapping(new MapVoidAction("setSelectedFile") {
1428            @Override
1429            public void map() {
1430                ((JFileChooser) getSource()).setSelectedFile(file);
1431            }
1432        });
1433    }
1434
1435    /**
1436     * Maps {@code JFileChooser.setSelectedFiles(File[])} through queue
1437     */
1438    public void setSelectedFiles(final File[] file) {
1439        runMapping(new MapVoidAction("setSelectedFiles") {
1440            @Override
1441            public void map() {
1442                ((JFileChooser) getSource()).setSelectedFiles(file);
1443            }
1444        });
1445    }
1446
1447    /**
1448     * Maps {@code JFileChooser.showDialog(Component, String)} through queue
1449     */
1450    public int showDialog(final Component component, final String string) {
1451        return (runMapping(new MapIntegerAction("showDialog") {
1452            @Override
1453            public int map() {
1454                return ((JFileChooser) getSource()).showDialog(component, string);
1455            }
1456        }));
1457    }
1458
1459    /**
1460     * Maps {@code JFileChooser.showOpenDialog(Component)} through queue
1461     */
1462    public int showOpenDialog(final Component component) {
1463        return (runMapping(new MapIntegerAction("showOpenDialog") {
1464            @Override
1465            public int map() {
1466                return ((JFileChooser) getSource()).showOpenDialog(component);
1467            }
1468        }));
1469    }
1470
1471    /**
1472     * Maps {@code JFileChooser.showSaveDialog(Component)} through queue
1473     */
1474    public int showSaveDialog(final Component component) {
1475        return (runMapping(new MapIntegerAction("showSaveDialog") {
1476            @Override
1477            public int map() {
1478                return ((JFileChooser) getSource()).showSaveDialog(component);
1479            }
1480        }));
1481    }
1482
1483    //End of mapping                                      //
1484    ////////////////////////////////////////////////////////
1485    private void waitPainted(int index) {
1486        Waiter<Rectangle, Integer> drawingWaiter = new Waiter<>(new Waitable<Rectangle, Integer>() {
1487            @Override
1488            public Rectangle actionProduced(Integer param) {
1489                JList<?> list = getFileList();
1490                int last_one = list.getModel().getSize() - 1;
1491                if (last_one == -1) {
1492                    return new Rectangle();
1493                }
1494                int current = (param != null) ? param : 0;
1495                try {
1496                    if (list.getCellBounds(current, current) != null) {
1497                        return list.getCellBounds(last_one, last_one);
1498                    } else {
1499                        return null;
1500                    }
1501                } catch (NullPointerException e) {
1502                    //sometimes thrown from list.getCellBounds when item exists but not painted
1503                    return null;
1504                }
1505            }
1506
1507            @Override
1508            public String getDescription() {
1509                return "List drawed";
1510            }
1511
1512            @Override
1513            public String toString() {
1514                return "JFileChooserOperator.waitPainted.Waitable{description = " + getDescription() + '}';
1515            }
1516        });
1517        drawingWaiter.setTimeoutsToCloneOf(getTimeouts(), "JFileChooserOperator.WaitListPaintedTimeout");
1518        drawingWaiter.setOutput(getOutput().createErrorOutput());
1519        try {
1520            drawingWaiter.waitAction((index != -1) ? index : null);
1521        } catch (InterruptedException e) {
1522            output.printStackTrace(e);
1523        }
1524    }
1525
1526    private JComboBox<?> getCombo(int index) {
1527        return ((JComboBox) innerSearcher.
1528                findComponent(new ComponentChooser() {
1529                    @Override
1530                    public boolean checkComponent(Component comp) {
1531                        return (comp != null
1532                                && comp instanceof JComboBox);
1533                    }
1534
1535                    @Override
1536                    public String getDescription() {
1537                        return "JComboBox";
1538                    }
1539
1540                    @Override
1541                    public String toString() {
1542                        return "JFileChooserOperator.getCombo.ComponentChooser{description = " + getDescription() + '}';
1543                    }
1544                }, index));
1545    }
1546
1547    private JButton getNoTextButton(int index) {
1548        return ((JButton) innerSearcher.
1549                findComponent(new ComponentChooser() {
1550                    @Override
1551                    public boolean checkComponent(Component comp) {
1552                        return (comp != null
1553                                && comp instanceof JButton
1554                                && !(comp.getParent() instanceof JComboBox)
1555                                && (((JButton) comp).getText() == null
1556                                || ((JButton) comp).getText().length() == 0));
1557                    }
1558
1559                    @Override
1560                    public String getDescription() {
1561                        return "JButton";
1562                    }
1563
1564                    @Override
1565                    public String toString() {
1566                        return "JFileChooserOperator.getNoTextButton.ComponentChooser{description = " + getDescription() + '}';
1567                    }
1568                }, index));
1569    }
1570
1571    private JToggleButton getToggleButton(int index) {
1572        return ((JToggleButton) innerSearcher.
1573                findComponent(new ComponentChooser() {
1574                    @Override
1575                    public boolean checkComponent(Component comp) {
1576                        return (comp != null
1577                                && comp instanceof JToggleButton);
1578                    }
1579
1580                    @Override
1581                    public String getDescription() {
1582                        return "JToggleButton";
1583                    }
1584
1585                    @Override
1586                    public String toString() {
1587                        return "JFileChooserOperator.getToggleButton.ComponentChooser{description = " + getDescription() + '}';
1588                    }
1589                }, index));
1590    }
1591
1592    private int findFileIndex(final String file, final StringComparator comparator) {
1593        Waiter<Integer, Void> fileWaiter = new Waiter<>(new Waitable<Integer, Void>() {
1594            @Override
1595            public Integer actionProduced(Void obj) {
1596                File[] files = getFiles();
1597                for (int i = 0; i < files.length; i++) {
1598                    if (comparator.equals(files[i].getName(),
1599                            file)) {
1600                        return i;
1601                    }
1602                }
1603                return null;
1604            }
1605
1606            @Override
1607            public String getDescription() {
1608                return "\"" + file + "\" file to be displayed";
1609            }
1610
1611            @Override
1612            public String toString() {
1613                return "JFileChooserOperator.findFileIndex.Waitable{description = " + getDescription() + '}';
1614            }
1615        });
1616        fileWaiter.setOutput(getOutput().createErrorOutput());
1617        fileWaiter.setTimeoutsToCloneOf(getTimeouts(), "JFileChooserOperator.WaitListPaintedTimeout");
1618        try {
1619            return fileWaiter.waitAction(null);
1620        } catch (InterruptedException e) {
1621            throw (new JemmyException("Waiting has been interrupted!"));
1622        }
1623    }
1624
1625    private int findDirIndex(String dir, StringComparator comparator) {
1626        ComboBoxModel<?> cbModel = getPathCombo().getModel();
1627        for (int i = cbModel.getSize() - 1; i >= 0; i--) {
1628            if (comparator.equals(((File) cbModel.getElementAt(i)).getName(),
1629                    dir)) {
1630                return i;
1631            }
1632        }
1633        return -1;
1634    }
1635
1636    private int findFileTypeIndex(String fileType, StringComparator comparator) {
1637        ComboBoxModel<?> cbModel = getFileTypesCombo().getModel();
1638        for (int i = 0; i < cbModel.getSize(); i++) {
1639            if (comparator.equals(((FileFilter) cbModel.getElementAt(i)).getDescription(),
1640                    fileType)) {
1641                return i;
1642            }
1643        }
1644        return -1;
1645    }
1646
1647    /**
1648     * Allows to find a dialog containing JFileChooser.
1649     */
1650    public static class JFileChooserJDialogFinder implements ComponentChooser {
1651
1652        TestOut output;
1653        ComponentChooser subChooser;
1654
1655        /**
1656         * Constructs JFileChooserJDialogFinder.
1657         *
1658         * @param output an output to put searching message into.
1659         */
1660        public JFileChooserJDialogFinder(TestOut output) {
1661            this.output = output;
1662            subChooser = new JFileChooserFinder();
1663        }
1664
1665        @Override
1666        public boolean checkComponent(Component comp) {
1667            if (comp != null
1668                    && comp instanceof Window
1669                    && comp.isVisible()) {
1670                ComponentSearcher searcher
1671                        = new ComponentSearcher((Container) comp);
1672                searcher.setOutput(output);
1673                return searcher.findComponent(subChooser) != null;
1674            } else {
1675                return false;
1676            }
1677        }
1678
1679        @Override
1680        public String getDescription() {
1681            return "JFileChooser's window";
1682        }
1683
1684        @Override
1685        public String toString() {
1686            return "JFileChooserJDialogFinder{" + "subChooser=" + subChooser + '}';
1687        }
1688    }
1689
1690    /**
1691     * Checks component type.
1692     */
1693    public static class JFileChooserFinder extends Finder {
1694
1695        /**
1696         * Constructs JFileChooserFinder.
1697         *
1698         * @param sf other searching criteria.
1699         */
1700        public JFileChooserFinder(ComponentChooser sf) {
1701            super(JFileChooser.class, sf);
1702        }
1703
1704        /**
1705         * Constructs JFileChooserFinder.
1706         */
1707        public JFileChooserFinder() {
1708            super(JFileChooser.class);
1709        }
1710    }
1711
1712    private static class ButtonFinder implements ComponentChooser {
1713
1714        String text;
1715
1716        public ButtonFinder(String text) {
1717            this.text = text;
1718        }
1719
1720        @Override
1721        public boolean checkComponent(Component comp) {
1722            return (comp != null
1723                    && comp instanceof JButton
1724                    && ((JButton) comp).getText() != null
1725                    && ((JButton) comp).getText().equals(text));
1726        }
1727
1728        @Override
1729        public String getDescription() {
1730            return "\"" + text + "\" button";
1731        }
1732
1733        @Override
1734        public String toString() {
1735            return "ButtonFinder{" + "text=" + text + '}';
1736        }
1737    }
1738
1739}
1740