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