001    /*
002     * Created on Feb 26, 2008
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005     * in compliance with the License. You may obtain a copy of the License at
006     *
007     * http://www.apache.org/licenses/LICENSE-2.0
008     *
009     * Unless required by applicable law or agreed to in writing, software distributed under the License
010     * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011     * or implied. See the License for the specific language governing permissions and limitations under
012     * the License.
013     *
014     * Copyright @2008-2010 the original author or authors.
015     */
016    package org.fest.swing.driver;
017    
018    import static org.fest.swing.core.matcher.JButtonMatcher.withText;
019    import static org.fest.swing.driver.JFileChooserApproveButtonTextQuery.approveButtonTextFrom;
020    import static org.fest.swing.driver.JFileChooserCancelButtonTextQuery.cancelButtonText;
021    import static org.fest.swing.driver.JFileChooserSelectFileTask.validateAndSelectFile;
022    import static org.fest.swing.driver.JFileChooserSelectFileTask.validateAndSelectFiles;
023    import static org.fest.swing.driver.JFileChooserSetCurrentDirectoryTask.validateAndSetCurrentDirectory;
024    import static org.fest.util.Arrays.isEmpty;
025    import static org.fest.util.Strings.concat;
026    import static org.fest.util.Strings.quote;
027    
028    import java.io.File;
029    
030    import javax.swing.*;
031    
032    import org.fest.swing.annotation.RunsInEDT;
033    import org.fest.swing.core.Robot;
034    import org.fest.swing.exception.ComponentLookupException;
035    
036    /**
037     * Understands functional testing of <code>{@link JFileChooser}</code>s:
038     * <ul>
039     * <li>user input simulation</li>
040     * <li>state verification</li>
041     * <li>property value query</li>
042     * </ul>
043     * This class is intended for internal use only. Please use the classes in the package
044     * <code>{@link org.fest.swing.fixture}</code> in your tests.
045     *
046     * @author Yvonne Wang
047     * @author Alex Ruiz
048     */
049    public class JFileChooserDriver extends JComponentDriver {
050    
051      private static final String APPROVE_BUTTON = "Approve";
052      private static final String CANCEL_BUTTON = "Cancel";
053    
054      /**
055       * Creates a new </code>{@link JFileChooserDriver}</code>.
056       * @param robot the robot to use to simulate user input.
057       */
058      public JFileChooserDriver(Robot robot) {
059        super(robot);
060      }
061    
062      /**
063       * Selects the given file in the <code>{@link JFileChooser}</code>.
064       * @param fileChooser the target <code>JFileChooser</code>.
065       * @param file the file to select.
066       * @throws NullPointerException if the given file is <code>null</code>.
067       * @throws IllegalStateException if the <code>JFileChooser</code> is disabled.
068       * @throws IllegalStateException if the <code>JFileChooser</code> is not showing on the screen.
069       * @throws IllegalArgumentException if the <code>JFileChooser</code> can select directories only and the file to
070       * select is not a directory.
071       * @throws IllegalArgumentException if the <code>JFileChooser</code> cannot select directories and the file to select
072       * is a directory.
073       */
074      @RunsInEDT
075      public void selectFile(JFileChooser fileChooser, File file) {
076        if (file == null) throw new NullPointerException("The file to select should not be null");
077        validateAndSelectFile(fileChooser, file);
078      }
079    
080      /**
081       * Selects the given file in the <code>{@link JFileChooser}</code>.
082       * @param fileChooser the target <code>JFileChooser</code>.
083       * @param files the files to select.
084       * @throws NullPointerException if the given array of files is <code>null</code>.
085       * @throws IllegalArgumentException if the given array of files is empty.
086       * @throws IllegalStateException if this fixture's <code>JFileChooser</code> is disabled.
087       * @throws IllegalStateException if this fixture's <code>JFileChooser</code> is not showing on the screen.
088       * @throws IllegalStateException if this fixture's <code>JFileChooser</code> does not support multiple selection and
089       * there is more than one file to select.
090       * @throws IllegalArgumentException if this fixture's <code>JFileChooser</code> can select directories only and any of
091       * the files to select is not a directory.
092       * @throws IllegalArgumentException if this fixture's <code>JFileChooser</code> cannot select directories and any of
093       * the files to select is a directory.
094       */
095      public void selectFiles(JFileChooser fileChooser, File[] files) {
096        if (files == null) throw new NullPointerException("The files to select should not be null");
097        if (isEmpty(files)) throw new IllegalArgumentException("The array of files to select should not be empty");
098        for (File file : files)
099          if (file == null) throw new NullPointerException("The array of files to select should not contain null elements");
100        validateAndSelectFiles(fileChooser, files);
101      }
102    
103      /**
104       * Sets the current directory in the <code>{@link JFileChooser}</code> to the given one.
105       * @param fileChooser the target <code>JFileChooser</code>.
106       * @param dir the directory to set as current.
107       * @throws IllegalStateException if the <code>JFileChooser</code> is disabled.
108       * @throws IllegalStateException if the <code>JFileChooser</code> is not showing on the screen.
109       */
110      @RunsInEDT
111      public void setCurrentDirectory(JFileChooser fileChooser, File dir) {
112        validateAndSetCurrentDirectory(fileChooser, dir);
113      }
114    
115      /**
116       * Returns the text field where the user can enter the name of the file to select.
117       * @param fileChooser the target <code>JFileChooser</code>.
118       * @return the found text field.
119       * @throws ComponentLookupException if a matching text field could not be found.
120       */
121      @RunsInEDT
122      public JTextField fileNameTextBox(JFileChooser fileChooser) {
123        return robot.finder().findByType(fileChooser, JTextField.class);
124      }
125    
126      /**
127       * Finds and clicks the "Cancel" button in the given <code>{@link JFileChooser}</code>.
128       * @param fileChooser the target <code>JFileChooser</code>.
129       * @throws ComponentLookupException if the "Cancel" button cannot be found.
130       * @throws IllegalStateException if the "Cancel" button is disabled.
131       * @throws IllegalStateException if the "Cancel" button is not showing on the screen.
132       */
133      @RunsInEDT
134      public void clickCancelButton(JFileChooser fileChooser) {
135        click(cancelButton(fileChooser));
136      }
137    
138      /**
139       * Finds the "Cancel" button in the given <code>{@link JFileChooser}</code>.
140       * @param fileChooser the target <code>JFileChooser</code>.
141       * @return the found "Cancel" button.
142       * @throws ComponentLookupException if the "Cancel" button cannot be found.
143       */
144      @RunsInEDT
145      public JButton cancelButton(JFileChooser fileChooser) {
146        return findButton(fileChooser, CANCEL_BUTTON, cancelButtonText());
147      }
148    
149      /**
150       * Finds and clicks the "Approve" button in the given <code>{@link JFileChooser}</code>.
151       * @param fileChooser the target <code>JFileChooser</code>.
152       * @throws ComponentLookupException if the "Approve" button cannot be found.
153       * @throws IllegalStateException if the "Approve" button is disabled.
154       * @throws IllegalStateException if the "Approve" button is not showing on the screen.
155       */
156      @RunsInEDT
157      public void clickApproveButton(JFileChooser fileChooser) {
158        click(approveButton(fileChooser));
159      }
160    
161      /**
162       * Finds the "Approve" button in the given <code>{@link JFileChooser}</code>.
163       * @param fileChooser the target <code>JFileChooser</code>.
164       * @return the found "Approve" button.
165       * @throws ComponentLookupException if the "Approve" button cannot be found.
166       */
167      @RunsInEDT
168      public JButton approveButton(JFileChooser fileChooser) {
169        return findButton(fileChooser, APPROVE_BUTTON, approveButtonTextFrom(fileChooser));
170      }
171    
172      @RunsInEDT
173      private JButton findButton(JFileChooser fileChooser, String logicalName, String text) {
174        JButton button = robot.finder().find(fileChooser, withText(text).andShowing());
175        if (button == null) throw cannotFindButton(logicalName, text);
176        return button;
177      }
178    
179      private ComponentLookupException cannotFindButton(String name, String text) {
180        throw new ComponentLookupException(concat(
181            "Unable to find ", quote(name), " button with text ", quote(text)));
182      }
183    }