001    /*
002     * Created on Dec 25, 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 java.awt.Point;
018    import java.util.regex.Pattern;
019    
020    import javax.swing.JScrollBar;
021    import javax.swing.JScrollPane;
022    
023    import org.fest.swing.core.*;
024    import org.fest.swing.driver.JScrollPaneDriver;
025    import org.fest.swing.exception.ComponentLookupException;
026    import org.fest.swing.exception.WaitTimedOutError;
027    import org.fest.swing.timing.Timeout;
028    
029    /**
030     * Understands functional testing of <code>{@link JScrollPane}</code>s:
031     * <ul>
032     * <li>user input simulation</li>
033     * <li>state verification</li>
034     * <li>property value query</li>
035     * </ul>
036     *
037     * @author Yvonne Wang
038     * @author Alex Ruiz
039     */
040    public class JScrollPaneFixture extends ComponentFixture<JScrollPane> implements CommonComponentFixture,
041        JPopupMenuInvokerFixture, JComponentFixture {
042    
043      private JScrollPaneDriver driver;
044    
045      /**
046       * Creates a new <code>{@link JScrollPaneFixture}</code>.
047       * @param robot performs simulation of user events on the given <code>JScrollPane</code>.
048       * @param target the <code>JScrollPane</code> to be managed by this fixture.
049       * @throws NullPointerException if <code>robot</code> is <code>null</code>.
050       * @throws IllegalArgumentException if <code>target</code> is <code>null</code>.
051       */
052      public JScrollPaneFixture(Robot robot, JScrollPane target) {
053        super(robot, target);
054        driver(newComponentDriver());
055      }
056    
057      /**
058       * Sets the <code>{@link JScrollPaneDriver}</code> to be used by this fixture.
059       * @param newDriver the new <code>JScrollPaneDriver</code>.
060       * @throws NullPointerException if the given driver is <code>null</code>.
061       */
062      protected final void driver(JScrollPaneDriver newDriver) {
063        validateNotNull(newDriver);
064        driver = newDriver;
065      }
066    
067      /**
068       * Creates a new <code>{@link JScrollPaneFixture}</code>.
069       * @param robot performs simulation of user events on a <code>JScrollPane</code>.
070       * @param panelName the name of the <code>JScrollPane</code> to find using the given <code>Robot</code>.
071       * @throws NullPointerException if <code>robot</code> is <code>null</code>.
072       * @throws ComponentLookupException if a matching <code>JScrollPane</code> could not be found.
073       * @throws ComponentLookupException if more than one matching <code>JScrollPane</code> is found.
074       */
075      public JScrollPaneFixture(Robot robot, String panelName) {
076        super(robot, panelName, JScrollPane.class);
077        driver = newComponentDriver();
078      }
079    
080      private JScrollPaneDriver newComponentDriver() {
081        return new JScrollPaneDriver(robot);
082      }
083    
084      /**
085       * Returns a <code>{@link JScrollBarFixture}</code> managing the horizontal <code>{@link JScrollBar}</code> of this
086       * target's <code>{@link JScrollPane}</code>.
087       * @return a fixture managing the horizontal <code>JScrollBar</code> of this target's <code>JScrollPane</code>.
088       */
089      public JScrollBarFixture horizontalScrollBar() {
090        return scrollBarFixture(driver.horizontalScrollBarIn(target));
091      }
092    
093      /**
094       * Returns a <code>{@link JScrollBarFixture}</code> managing the vertical <code>{@link JScrollBar}</code> of this
095       * target's <code>{@link JScrollPane}</code>.
096       * @return a fixture managing the vertical <code>JScrollBar</code> of this target's <code>JScrollPane</code>.
097       */
098      public JScrollBarFixture verticalScrollBar() {
099        return scrollBarFixture(driver.verticalScrollBarIn(target));
100      }
101    
102      private JScrollBarFixture scrollBarFixture(JScrollBar scrollBar) {
103        return new JScrollBarFixture(robot, scrollBar);
104      }
105    
106      /**
107       * Simulates a user clicking this fixture's <code>{@link JScrollPane}</code>.
108       * @return this fixture.
109       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is disabled.
110       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is not showing on the screen.
111       */
112      public JScrollPaneFixture click() {
113        driver.click(target);
114        return this;
115      }
116    
117      /**
118       * Simulates a user clicking this fixture's <code>{@link JScrollPane}</code>.
119       * @param button the button to click.
120       * @return this fixture.
121       * @throws NullPointerException if the given <code>MouseButton</code> is <code>null</code>.
122       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is disabled.
123       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is not showing on the screen.
124       */
125      public JScrollPaneFixture click(MouseButton button) {
126        driver.click(target, button);
127        return this;
128      }
129    
130      /**
131       * Simulates a user clicking this fixture's <code>{@link JScrollPane}</code>.
132       * @param mouseClickInfo specifies the button to click and the times the button should be clicked.
133       * @return this fixture.
134       * @throws NullPointerException if the given <code>MouseClickInfo</code> is <code>null</code>.
135       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is disabled.
136       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is not showing on the screen.
137       */
138      public JScrollPaneFixture click(MouseClickInfo mouseClickInfo) {
139        driver.click(target, mouseClickInfo);
140        return this;
141      }
142    
143      /**
144       * Simulates a user double-clicking this fixture's <code>{@link JScrollPane}</code>.
145       * @return this fixture.
146       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is disabled.
147       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is not showing on the screen.
148       */
149      public JScrollPaneFixture doubleClick() {
150        driver.doubleClick(target);
151        return this;
152      }
153    
154      /**
155       * Simulates a user right-clicking this fixture's <code>{@link JScrollPane}</code>.
156       * @return this fixture.
157       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is disabled.
158       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is not showing on the screen.
159       */
160      public JScrollPaneFixture rightClick() {
161        driver.rightClick(target);
162        return this;
163      }
164    
165      /**
166       * Gives input focus to this fixture's <code>{@link JScrollPane}</code>.
167       * @return this fixture.
168       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is disabled.
169       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is not showing on the screen.
170       */
171      public JScrollPaneFixture focus() {
172        driver.focus(target);
173        return this;
174      }
175    
176      /**
177       * Simulates a user pressing given key with the given modifiers on this fixture's <code>{@link JScrollPane}</code>.
178       * Modifiers is a mask from the available <code>{@link java.awt.event.InputEvent}</code> masks.
179       * @param keyPressInfo specifies the key and modifiers to press.
180       * @return this fixture.
181       * @throws NullPointerException if the given <code>KeyPressInfo</code> is <code>null</code>.
182       * @throws IllegalArgumentException if the given code is not a valid key code.
183       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is disabled.
184       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is not showing on the screen.
185       * @see KeyPressInfo
186       */
187      public JScrollPaneFixture pressAndReleaseKey(KeyPressInfo keyPressInfo) {
188        driver.pressAndReleaseKey(target, keyPressInfo);
189        return this;
190      }
191    
192      /**
193       * Simulates a user pressing and releasing the given keys on the <code>{@link JScrollPane}</code> managed by this
194       * fixture.
195       * @param keyCodes one or more codes of the keys to press.
196       * @return this fixture.
197       * @throws NullPointerException if the given array of codes is <code>null</code>.
198       * @throws IllegalArgumentException if any of the given code is not a valid key code.
199       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is disabled.
200       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is not showing on the screen.
201       * @see java.awt.event.KeyEvent
202       */
203      public JScrollPaneFixture pressAndReleaseKeys(int... keyCodes) {
204        driver.pressAndReleaseKeys(target, keyCodes);
205        return this;
206      }
207    
208      /**
209       * Simulates a user pressing the given key on this fixture's <code>{@link JScrollPane}</code>.
210       * @param keyCode the code of the key to press.
211       * @return this fixture.
212       * @throws IllegalArgumentException if any of the given code is not a valid key code.
213       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is disabled.
214       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is not showing on the screen.
215       * @see java.awt.event.KeyEvent
216       */
217      public JScrollPaneFixture pressKey(int keyCode) {
218        driver.pressKey(target, keyCode);
219        return this;
220      }
221    
222      /**
223       * Simulates a user releasing the given key on this fixture's <code>{@link JScrollPane}</code>.
224       * @param keyCode the code of the key to release.
225       * @return this fixture.
226       * @throws IllegalArgumentException if any of the given code is not a valid key code.
227       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is disabled.
228       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is not showing on the screen.
229       * @see java.awt.event.KeyEvent
230       */
231      public JScrollPaneFixture releaseKey(int keyCode) {
232        driver.releaseKey(target, keyCode);
233        return this;
234      }
235    
236      /**
237       * Asserts that this fixture's <code>{@link JScrollPane}</code> has input focus.
238       * @return this fixture.
239       * @throws AssertionError if this fixture's <code>JScrollPane</code> does not have input focus.
240       */
241      public JScrollPaneFixture requireFocused() {
242        driver.requireFocused(target);
243        return this;
244      }
245    
246      /**
247       * Asserts that this fixture's <code>{@link JScrollPane}</code> is enabled.
248       * @return this fixture.
249       * @throws AssertionError if this fixture's <code>JScrollPane</code> is disabled.
250       */
251      public JScrollPaneFixture requireEnabled() {
252        driver.requireEnabled(target);
253        return this;
254      }
255    
256      /**
257       * Asserts that this fixture's <code>{@link JScrollPane}</code> is enabled.
258       * @param timeout the time this fixture will wait for the component to be enabled.
259       * @return this fixture.
260       * @throws WaitTimedOutError if this fixture's <code>JScrollPane</code> is never enabled.
261       */
262      public JScrollPaneFixture requireEnabled(Timeout timeout) {
263        driver.requireEnabled(target, timeout);
264        return this;
265      }
266    
267      /**
268       * Asserts that this fixture's <code>{@link JScrollPane}</code> is disabled.
269       * @return this fixture.
270       * @throws AssertionError if this fixture's <code>JScrollPane</code> is enabled.
271       */
272      public JScrollPaneFixture requireDisabled() {
273        driver.requireDisabled(target);
274        return this;
275      }
276    
277      /**
278       * Asserts that this fixture's <code>{@link JScrollPane}</code> is visible.
279       * @return this fixture.
280       * @throws AssertionError if this fixture's <code>JScrollPane</code> is not visible.
281       */
282      public JScrollPaneFixture requireVisible() {
283        driver.requireVisible(target);
284        return this;
285      }
286    
287      /**
288       * Asserts that this fixture's <code>{@link JScrollPane}</code> is not visible.
289       * @return this fixture.
290       * @throws AssertionError if this fixture's <code>JScrollPane</code> is visible.
291       */
292      public JScrollPaneFixture requireNotVisible() {
293        driver.requireNotVisible(target);
294        return this;
295      }
296    
297      /**
298       * Asserts that the toolTip in this fixture's <code>{@link JScrollPane}</code> matches the given value.
299       * @param expected the given value. It can be a regular expression.
300       * @return this fixture.
301       * @throws AssertionError if the toolTip in this fixture's <code>JScrollPane</code> does not match the given value.
302       * @since 1.2
303       */
304      public JScrollPaneFixture requireToolTip(String expected) {
305        driver.requireToolTip(target, expected);
306        return this;
307      }
308    
309      /**
310       * Asserts that the toolTip in this fixture's <code>{@link JScrollPane}</code> matches the given regular expression
311       * pattern.
312       * @param pattern the regular expression pattern to match.
313       * @return this fixture.
314       * @throws NullPointerException if the given regular expression pattern is <code>null</code>.
315       * @throws AssertionError if the toolTip in this fixture's <code>JScrollPane</code> does not match the given regular
316       * expression.
317       * @since 1.2
318       */
319      public JScrollPaneFixture requireToolTip(Pattern pattern) {
320        driver.requireToolTip(target, pattern);
321        return this;
322      }
323    
324      /**
325       * Returns the client property stored in this fixture's <code>{@link JScrollPane}</code>, under the given key.
326       * @param key the key to use to retrieve the client property.
327       * @return the value of the client property stored under the given key, or <code>null</code> if the property was
328       * not found.
329       * @throws NullPointerException if the given key is <code>null</code>.
330       * @since 1.2
331       */
332      public Object clientProperty(Object key) {
333        return driver.clientProperty(target, key);
334      }
335    
336      /**
337       * Shows a pop-up menu using this fixture's <code>{@link JScrollPane}</code> as the invoker of the pop-up menu.
338       * @return a fixture that manages the displayed pop-up menu.
339       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is disabled.
340       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is not showing on the screen.
341       * @throws ComponentLookupException if a pop-up menu cannot be found.
342       */
343      public JPopupMenuFixture showPopupMenu() {
344        return new JPopupMenuFixture(robot, driver.invokePopupMenu(target));
345      }
346    
347      /**
348       * Shows a pop-up menu at the given point using this fixture's <code>{@link JScrollPane}</code> as the invoker of the
349       * pop-up menu.
350       * @param p the given point where to show the pop-up menu.
351       * @return a fixture that manages the displayed pop-up menu.
352       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is disabled.
353       * @throws IllegalStateException if this fixture's <code>JScrollPane</code> is not showing on the screen.
354       * @throws ComponentLookupException if a pop-up menu cannot be found.
355       */
356      public JPopupMenuFixture showPopupMenuAt(Point p) {
357        return new JPopupMenuFixture(robot, driver.invokePopupMenu(target, p));
358      }
359    }