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