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