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