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