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