001    /*
002     * Created on Apr 10, 2007
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
005     * 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 is distributed on
010     * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011     * specific language governing permissions and limitations under the License.
012     *
013     * Copyright @2007-2010 the original author or authors.
014     */
015    package org.fest.swing.fixture;
016    
017    import static org.fest.swing.core.ComponentLookupScope.SHOWING_ONLY;
018    import static org.fest.swing.timing.Pause.pause;
019    
020    import java.awt.Component;
021    import java.awt.Container;
022    import java.awt.Dialog;
023    
024    import javax.swing.JButton;
025    import javax.swing.JCheckBox;
026    import javax.swing.JComboBox;
027    import javax.swing.JFileChooser;
028    import javax.swing.JLabel;
029    import javax.swing.JList;
030    import javax.swing.JMenuItem;
031    import javax.swing.JOptionPane;
032    import javax.swing.JPanel;
033    import javax.swing.JProgressBar;
034    import javax.swing.JRadioButton;
035    import javax.swing.JScrollBar;
036    import javax.swing.JScrollPane;
037    import javax.swing.JSlider;
038    import javax.swing.JSpinner;
039    import javax.swing.JSplitPane;
040    import javax.swing.JTabbedPane;
041    import javax.swing.JTable;
042    import javax.swing.JToggleButton;
043    import javax.swing.JToolBar;
044    import javax.swing.JTree;
045    import javax.swing.text.JTextComponent;
046    
047    import org.fest.swing.core.ComponentFinder;
048    import org.fest.swing.core.ComponentFoundCondition;
049    import org.fest.swing.core.ComponentMatcher;
050    import org.fest.swing.core.GenericTypeMatcher;
051    import org.fest.swing.core.NameMatcher;
052    import org.fest.swing.core.Robot;
053    import org.fest.swing.core.TypeMatcher;
054    import org.fest.swing.exception.ComponentLookupException;
055    import org.fest.swing.timing.Timeout;
056    
057    /**
058     * Understands lookup of <code>{@link Component}</code>s contained in a <code>{@link Container}</code>.
059     * @param <T> the type of container handled by this fixture.
060     *
061     * @author Alex Ruiz
062     * @author Yvonne Wang
063     */
064    public abstract class ContainerFixture<T extends Container> extends ComponentFixture<T> implements
065        ComponentContainerFixture {
066    
067      private final JMenuItemFinder menuItemFinder;
068    
069      /**
070       * Creates a new <code>{@link ContainerFixture}</code>.
071       * @param robot performs simulation of user events on a <code>Container</code>.
072       * @param type the type of the <code>Container</code> to find using the given <code>Robot</code>.
073       * @throws NullPointerException if <code>robot</code> is <code>null</code>.
074       * @throws NullPointerException if <code>type</code> is <code>null</code>.
075       * @throws ComponentLookupException if a matching component could not be found.
076       * @throws ComponentLookupException if more than one matching component is found.
077       * @see org.fest.swing.core.ComponentFinder#findByType(Class)
078       */
079      public ContainerFixture(Robot robot, Class<? extends T> type) {
080        super(robot, type);
081        menuItemFinder = new JMenuItemFinder(robot, target);
082      }
083    
084      /**
085       * Creates a new <code>{@link ContainerFixture}</code>.
086       * @param robot performs simulation of user events on a <code>Container</code>.
087       * @param name the name of the <code>Container</code> to find using the given <code>Robot</code>.
088       * @param type the type of the <code>Container</code> to find using the given <code>Robot</code>.
089       * @throws NullPointerException if <code>robot</code> is <code>null</code>.
090       * @throws NullPointerException if <code>type</code> is <code>null</code>.
091       * @throws ComponentLookupException if a matching component could not be found.
092       * @throws ComponentLookupException if more than one matching component is found.
093       * @see org.fest.swing.core.ComponentFinder#findByName(String, Class)
094       */
095      public ContainerFixture(Robot robot, String name, Class<? extends T> type) {
096        super(robot, name, type);
097        menuItemFinder = new JMenuItemFinder(robot, target);
098      }
099    
100      /**
101       * Creates a new <code>{@link ContainerFixture}</code>.
102       * @param robot performs simulation of user events on the given <code>Container</code>.
103       * @param target the <code>Container</code> to be.
104       * @throws NullPointerException if <code>robot</code> is <code>null</code>.
105       * @throws NullPointerException if <code>target</code> is <code>null</code>.
106       */
107      public ContainerFixture(Robot robot, T target) {
108        super(robot, target);
109        menuItemFinder = new JMenuItemFinder(robot, target);
110      }
111    
112      /** {@inheritDoc} */
113      public JButtonFixture button() {
114        return new JButtonFixture(robot, findByType(JButton.class));
115      }
116    
117      /** {@inheritDoc} */
118      public JButtonFixture button(GenericTypeMatcher<? extends JButton> matcher) {
119        return new JButtonFixture(robot, find(matcher));
120      }
121    
122      /** {@inheritDoc} */
123      public JButtonFixture button(String name) {
124        return new JButtonFixture(robot, findByName(name, JButton.class));
125      }
126    
127      /** {@inheritDoc} */
128      public JCheckBoxFixture checkBox() {
129        return new JCheckBoxFixture(robot, findByType(JCheckBox.class));
130      }
131    
132      /** {@inheritDoc} */
133      public JCheckBoxFixture checkBox(GenericTypeMatcher<? extends JCheckBox> matcher) {
134        return new JCheckBoxFixture(robot, find(matcher));
135      }
136    
137      /** {@inheritDoc} */
138      public JCheckBoxFixture checkBox(String name) {
139        return new JCheckBoxFixture(robot, findByName(name, JCheckBox.class));
140      }
141    
142      /** {@inheritDoc} */
143      public JComboBoxFixture comboBox() {
144        return new JComboBoxFixture(robot, findByType(JComboBox.class));
145      }
146    
147      /** {@inheritDoc} */
148      public JComboBoxFixture comboBox(GenericTypeMatcher<? extends JComboBox> matcher) {
149        return new JComboBoxFixture(robot, find(matcher));
150      }
151    
152      /** {@inheritDoc} */
153      public JComboBoxFixture comboBox(String name) {
154        return new JComboBoxFixture(robot, findByName(name, JComboBox.class));
155      }
156    
157      /** {@inheritDoc} */
158      public DialogFixture dialog() {
159        return dialog(DEFAULT_DIALOG_LOOKUP_TIMEOUT);
160      }
161    
162      /** {@inheritDoc} */
163      public DialogFixture dialog(Timeout timeout) {
164        TypeMatcher matcher = new TypeMatcher(Dialog.class, requireShowing());
165        return findDialog(matcher, timeout);
166      }
167    
168      /** {@inheritDoc} */
169      public DialogFixture dialog(GenericTypeMatcher<? extends Dialog> matcher) {
170        return dialog(matcher, DEFAULT_DIALOG_LOOKUP_TIMEOUT);
171      }
172    
173      /** {@inheritDoc} */
174      public DialogFixture dialog(GenericTypeMatcher<? extends Dialog> matcher, Timeout timeout) {
175        return findDialog(matcher, timeout);
176      }
177    
178      /** {@inheritDoc} */
179      public DialogFixture dialog(String name) {
180        return dialog(name, DEFAULT_DIALOG_LOOKUP_TIMEOUT);
181      }
182    
183      /** {@inheritDoc} */
184      public DialogFixture dialog(String name, Timeout timeout) {
185        NameMatcher matcher = new NameMatcher(name, Dialog.class, requireShowing());
186        return findDialog(matcher, timeout);
187      }
188    
189      private DialogFixture findDialog(ComponentMatcher matcher, Timeout timeout) {
190        String description = "dialog to be found using matcher " + matcher;
191        ComponentFoundCondition condition = new ComponentFoundCondition(description, robot.finder(), matcher);
192        pause(condition, timeout);
193        return new DialogFixture(robot, (Dialog)condition.found());
194      }
195    
196      /** {@inheritDoc} */
197      public JFileChooserFixture fileChooser() {
198        return fileChooser(DEFAULT_DIALOG_LOOKUP_TIMEOUT);
199      }
200    
201      /** {@inheritDoc} */
202      public JFileChooserFixture fileChooser(Timeout timeout) {
203        TypeMatcher matcher = new TypeMatcher(JFileChooser.class, requireShowing());
204        return findFileChooser(matcher, timeout);
205      }
206    
207      /** {@inheritDoc} */
208      public JFileChooserFixture fileChooser(GenericTypeMatcher<? extends JFileChooser> matcher) {
209        return fileChooser(matcher, DEFAULT_DIALOG_LOOKUP_TIMEOUT);
210      }
211    
212      /** {@inheritDoc} */
213      public JFileChooserFixture fileChooser(GenericTypeMatcher<? extends JFileChooser> matcher, Timeout timeout) {
214        return findFileChooser(matcher, timeout);
215      }
216    
217      /** {@inheritDoc} */
218      public JFileChooserFixture fileChooser(String name) {
219        return new JFileChooserFixture(robot, findByName(name, JFileChooser.class));
220      }
221    
222      /** {@inheritDoc} */
223      public JFileChooserFixture fileChooser(String name, Timeout timeout) {
224        NameMatcher matcher = new NameMatcher(name, JFileChooser.class, requireShowing());
225        return findFileChooser(matcher, timeout);
226      }
227    
228      private JFileChooserFixture findFileChooser(ComponentMatcher matcher, Timeout timeout) {
229        String description = "file chooser to be found using matcher " + matcher;
230        ComponentFoundCondition condition = new ComponentFoundCondition(description, robot.finder(), matcher);
231        pause(condition, timeout);
232        return new JFileChooserFixture(robot, (JFileChooser)condition.found());
233      }
234    
235      /** {@inheritDoc} */
236      public JLabelFixture label() {
237        return new JLabelFixture(robot, findByType(JLabel.class));
238      }
239    
240      /** {@inheritDoc} */
241      public JLabelFixture label(GenericTypeMatcher<? extends JLabel> matcher) {
242        return new JLabelFixture(robot, find(matcher));
243      }
244    
245      /** {@inheritDoc} */
246      public JLabelFixture label(String name) {
247        return new JLabelFixture(robot, findByName(name, JLabel.class));
248      }
249    
250      /** {@inheritDoc} */
251      public JListFixture list() {
252        return new JListFixture(robot, findByType(JList.class));
253      }
254    
255      /** {@inheritDoc} */
256      public JListFixture list(GenericTypeMatcher<? extends JList> matcher) {
257        return new JListFixture(robot, find(matcher));
258      }
259    
260      /** {@inheritDoc} */
261      public JListFixture list(String name) {
262        return new JListFixture(robot, findByName(name, JList.class));
263      }
264    
265      /** {@inheritDoc} */
266      public JMenuItemFixture menuItemWithPath(String... path) {
267        return new JMenuItemFixture(robot, menuItemFinder.menuItemWithPath(path));
268      }
269    
270      /** {@inheritDoc} */
271      public JMenuItemFixture menuItem(String name) {
272        boolean requireShowing = SHOWING_ONLY.equals(robot.settings().componentLookupScope());
273        return new JMenuItemFixture(robot, finder().findByName(target, name, JMenuItem.class, requireShowing));
274      }
275    
276      /** {@inheritDoc} */
277      public JMenuItemFixture menuItem(GenericTypeMatcher<? extends JMenuItem> matcher) {
278        return new JMenuItemFixture(robot, find(matcher));
279      }
280    
281      /** {@inheritDoc} */
282      public JOptionPaneFixture optionPane() {
283        return optionPane(DEFAULT_DIALOG_LOOKUP_TIMEOUT);
284      }
285    
286      /** {@inheritDoc} */
287      public JOptionPaneFixture optionPane(Timeout timeout) {
288        TypeMatcher matcher = new TypeMatcher(JOptionPane.class, requireShowing());
289        String description = "option pane to be found using matcher " + matcher;
290        ComponentFoundCondition condition = new ComponentFoundCondition(description, robot.finder(), matcher);
291        pause(condition, timeout);
292        return new JOptionPaneFixture(robot, (JOptionPane)condition.found());
293      }
294    
295      /** {@inheritDoc} */
296      public JPanelFixture panel() {
297        return new JPanelFixture(robot, findByType(JPanel.class));
298      }
299    
300      /** {@inheritDoc} */
301      public JPanelFixture panel(GenericTypeMatcher<? extends JPanel> matcher) {
302        return new JPanelFixture(robot, find(matcher));
303      }
304    
305      /** {@inheritDoc} */
306      public JPanelFixture panel(String name) {
307        return new JPanelFixture(robot, findByName(name, JPanel.class));
308      }
309    
310      /** {@inheritDoc} */
311      public JProgressBarFixture progressBar() {
312        return new JProgressBarFixture(robot, findByType(JProgressBar.class));
313      }
314    
315      /** {@inheritDoc} */
316      public JProgressBarFixture progressBar(GenericTypeMatcher<? extends JProgressBar> matcher) {
317        return new JProgressBarFixture(robot, find(matcher));
318      }
319    
320      /** {@inheritDoc} */
321      public JProgressBarFixture progressBar(String name) {
322        return new JProgressBarFixture(robot, findByName(name, JProgressBar.class));
323      }
324    
325      /** {@inheritDoc} */
326      public JRadioButtonFixture radioButton() {
327        return new JRadioButtonFixture(robot, findByType(JRadioButton.class));
328      }
329    
330      /** {@inheritDoc} */
331      public JRadioButtonFixture radioButton(GenericTypeMatcher<? extends JRadioButton> matcher) {
332        return new JRadioButtonFixture(robot, find(matcher));
333      }
334    
335      /** {@inheritDoc} */
336      public JRadioButtonFixture radioButton(String name) {
337        return new JRadioButtonFixture(robot, findByName(name, JRadioButton.class));
338      }
339    
340      /** {@inheritDoc} */
341      public JScrollBarFixture scrollBar() {
342        return new JScrollBarFixture(robot, findByType(JScrollBar.class));
343      }
344    
345      /** {@inheritDoc} */
346      public JScrollBarFixture scrollBar(GenericTypeMatcher<? extends JScrollBar> matcher) {
347        return new JScrollBarFixture(robot, find(matcher));
348      }
349    
350      /** {@inheritDoc} */
351      public JScrollBarFixture scrollBar(String name) {
352        return new JScrollBarFixture(robot, findByName(name, JScrollBar.class));
353      }
354    
355      /** {@inheritDoc} */
356      public JScrollPaneFixture scrollPane() {
357        return new JScrollPaneFixture(robot, findByType(JScrollPane.class));
358      }
359    
360      /** {@inheritDoc} */
361      public JScrollPaneFixture scrollPane(GenericTypeMatcher<? extends JScrollPane> matcher) {
362        return new JScrollPaneFixture(robot, find(matcher));
363      }
364    
365      /** {@inheritDoc} */
366      public JScrollPaneFixture scrollPane(String name) {
367        return new JScrollPaneFixture(robot, findByName(name, JScrollPane.class));
368      }
369    
370      /** {@inheritDoc} */
371      public JSliderFixture slider() {
372        return new JSliderFixture(robot, findByType(JSlider.class));
373      }
374    
375      /** {@inheritDoc} */
376      public JSliderFixture slider(GenericTypeMatcher<? extends JSlider> matcher) {
377        return new JSliderFixture(robot, find(matcher));
378      }
379    
380      /** {@inheritDoc} */
381      public JSliderFixture slider(String name) {
382        return new JSliderFixture(robot, findByName(name, JSlider.class));
383      }
384    
385      /** {@inheritDoc} */
386      public JSpinnerFixture spinner() {
387        return new JSpinnerFixture(robot, findByType(JSpinner.class));
388      }
389    
390      /** {@inheritDoc} */
391      public JSpinnerFixture spinner(GenericTypeMatcher<? extends JSpinner> matcher) {
392        return new JSpinnerFixture(robot, find(matcher));
393      }
394    
395      /** {@inheritDoc} */
396      public JSpinnerFixture spinner(String name) {
397        return new JSpinnerFixture(robot, findByName(name, JSpinner.class));
398      }
399    
400      /** {@inheritDoc} */
401      public JSplitPaneFixture splitPane() {
402        return new JSplitPaneFixture(robot, findByType(JSplitPane.class));
403      }
404    
405      /** {@inheritDoc} */
406      public JSplitPaneFixture splitPane(GenericTypeMatcher<? extends JSplitPane> matcher) {
407        return new JSplitPaneFixture(robot, find(matcher));
408      }
409    
410      /** {@inheritDoc} */
411      public JSplitPaneFixture splitPane(String name) {
412        return new JSplitPaneFixture(robot, findByName(name, JSplitPane.class));
413      }
414    
415      /** {@inheritDoc} */
416      public JTabbedPaneFixture tabbedPane() {
417        return new JTabbedPaneFixture(robot, findByType(JTabbedPane.class));
418      }
419    
420      /** {@inheritDoc} */
421      public JTabbedPaneFixture tabbedPane(GenericTypeMatcher<? extends JTabbedPane> matcher) {
422        return new JTabbedPaneFixture(robot, find(matcher));
423      }
424    
425      /** {@inheritDoc} */
426      public JTabbedPaneFixture tabbedPane(String name) {
427        return new JTabbedPaneFixture(robot, findByName(name, JTabbedPane.class));
428      }
429    
430      /** {@inheritDoc} */
431      public JTableFixture table() {
432        return new JTableFixture(robot, findByType(JTable.class));
433      }
434    
435      /** {@inheritDoc} */
436      public JTableFixture table(GenericTypeMatcher<? extends JTable> matcher) {
437        return new JTableFixture(robot, find(matcher));
438      }
439    
440      /** {@inheritDoc} */
441      public JTableFixture table(String name) {
442        return new JTableFixture(robot, findByName(name, JTable.class));
443      }
444    
445      /** {@inheritDoc} */
446      public JTextComponentFixture textBox() {
447        return new JTextComponentFixture(robot, findByType(JTextComponent.class));
448      }
449    
450      /** {@inheritDoc} */
451      public JTextComponentFixture textBox(GenericTypeMatcher<? extends JTextComponent> matcher) {
452        return new JTextComponentFixture(robot, find(matcher));
453      }
454    
455      /** {@inheritDoc} */
456      public JTextComponentFixture textBox(String name) {
457        return new JTextComponentFixture(robot, findByName(name, JTextComponent.class));
458      }
459    
460      /** {@inheritDoc} */
461      public JToggleButtonFixture toggleButton() {
462        return new JToggleButtonFixture(robot, findByType(JToggleButton.class));
463      }
464    
465      /** {@inheritDoc} */
466      public JToggleButtonFixture toggleButton(GenericTypeMatcher<? extends JToggleButton> matcher) {
467        return new JToggleButtonFixture(robot, find(matcher));
468      }
469    
470      /** {@inheritDoc} */
471      public JToggleButtonFixture toggleButton(String name) {
472        return new JToggleButtonFixture(robot, findByName(name, JToggleButton.class));
473      }
474    
475      /** {@inheritDoc} */
476      public JToolBarFixture toolBar() {
477        return new JToolBarFixture(robot, findByType(JToolBar.class));
478      }
479    
480      /** {@inheritDoc} */
481      public JToolBarFixture toolBar(GenericTypeMatcher<? extends JToolBar> matcher) {
482        return new JToolBarFixture(robot, find(matcher));
483      }
484    
485      /** {@inheritDoc} */
486      public JToolBarFixture toolBar(String name) {
487        return new JToolBarFixture(robot, findByName(name, JToolBar.class));
488      }
489    
490      /** {@inheritDoc} */
491      public JTreeFixture tree() {
492        return new JTreeFixture(robot, findByType(JTree.class));
493      }
494    
495      /** {@inheritDoc} */
496      public JTreeFixture tree(GenericTypeMatcher<? extends JTree> matcher) {
497        return new JTreeFixture(robot, find(matcher));
498      }
499    
500      /** {@inheritDoc} */
501      public JTreeFixture tree(String name) {
502        return new JTreeFixture(robot, findByName(name, JTree.class));
503      }
504    
505      /**
506       * Finds a component by type, contained in this fixture's <code>{@link Container}</code>.
507       * @param <C> the generic type of the component to find.
508       * @param type the type of component to find.
509       * @return the found component.
510       * @throws ComponentLookupException if a matching component could not be found.
511       * @throws ComponentLookupException if more than one matching component is found.
512       */
513      protected final <C extends Component> C findByType(Class<C> type) {
514        return finder().findByType(target, type, requireShowing());
515      }
516    
517      /**
518       * Finds a component by name and type, contained in this fixture's <code>{@link Container}</code>.
519       * @param <C> the generic type of the component to find.
520       * @param name the name of the component to find.
521       * @param type the type of component to find.
522       * @return the found component.
523       * @throws ComponentLookupException if a matching component could not be found.
524       * @throws ComponentLookupException if more than one matching component is found.
525       */
526      protected final <C extends Component> C findByName(String name, Class<C> type) {
527        return finder().findByName(target, name, type, requireShowing());
528      }
529    
530      /**
531       * Finds a <code>{@link Component}</code> using the given <code>{@link GenericTypeMatcher}</code>, contained in this
532       * fixture's <code>{@link Container}</code>.
533       * @param <C> the generic type of component the given matcher can handle.
534       * @param matcher the matcher to use to find the component.
535       * @return the found component.
536       * @throws ComponentLookupException if a matching component could not be found.
537       * @throws ComponentLookupException if more than one matching component is found.
538       */
539      protected final <C extends Component> C find(GenericTypeMatcher<? extends C> matcher) {
540        return finder().find(target, matcher);
541      }
542    
543      /** {@inheritDoc} */
544      public <C extends Component, F extends ComponentFixture<C>> F with(ComponentFixtureExtension<C, F> extension) {
545        return extension.createFixture(robot, target);
546      }
547    
548      /**
549       * Returns the <code>{@link ComponentFinder}</code> contained in this fixture's <code>{@link Robot}</code>.
550       * @return the <code>ComponentFinder</code> contained in this fixture's <code>Robot</code>.
551       */
552      protected final ComponentFinder finder() { return robot.finder(); }
553    }