001    /*
002     * Created on Jan 31, 2008
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 @2008-2010 the original author or authors.
014     */
015    package org.fest.swing.driver;
016    
017    import static javax.swing.JSplitPane.VERTICAL_SPLIT;
018    import static org.fest.swing.core.MouseButton.LEFT_BUTTON;
019    import static org.fest.swing.driver.ComponentStateValidator.validateIsEnabledAndShowing;
020    import static org.fest.swing.driver.JSplitPaneLocationCalculator.locationToMoveDividerTo;
021    import static org.fest.swing.driver.JSplitPaneSetDividerLocationTask.setDividerLocation;
022    import static org.fest.swing.edt.GuiActionRunner.execute;
023    
024    import java.awt.*;
025    
026    import javax.swing.JSplitPane;
027    
028    import org.fest.swing.annotation.RunsInCurrentThread;
029    import org.fest.swing.annotation.RunsInEDT;
030    import org.fest.swing.core.Robot;
031    import org.fest.swing.edt.GuiQuery;
032    import org.fest.swing.util.GenericRange;
033    
034    /**
035     * Understands functional testing of <code>{@link JSplitPane}</code>s:
036     * <ul>
037     * <li>user input simulation</li>
038     * <li>state verification</li>
039     * <li>property value query</li>
040     * </ul>
041     * This class is intended for internal use only. Please use the classes in the package
042     * <code>{@link org.fest.swing.fixture}</code> in your tests.
043     *
044     * @author Alex Ruiz
045     * @author Yvonne Wang
046     */
047    public class JSplitPaneDriver extends JComponentDriver {
048    
049      /**
050       * Creates a new </code>{@link JSplitPaneDriver}</code>.
051       * @param robot the robot to use to simulate user input.
052       */
053      public JSplitPaneDriver(Robot robot) {
054        super(robot);
055      }
056    
057      /**
058       * Sets the divider position to an absolute position.
059       * <p>
060       * Since 1.2, this method respects the minimum and maximum values of the left and right components inside the given
061       * <code>JSplitPane</code>.
062       * </p>
063       * @param splitPane the target <code>JSplitPane</code>.
064       * @param location the location to move the divider to.
065       * @throws IllegalStateException if the <code>JSplitPane</code> is disabled.
066       * @throws IllegalStateException if the <code>JSplitPane</code> is not showing on the screen.
067       */
068      @RunsInEDT
069      public void moveDividerTo(JSplitPane splitPane, int location) {
070        int newLocation = locationToMoveDividerTo(splitPane, location);
071        simulateMovingDivider(splitPane, newLocation);
072        setDividerLocation(splitPane, newLocation);
073        robot.waitForIdle();
074      }
075    
076      @RunsInEDT
077      private void simulateMovingDivider(JSplitPane split, int location) {
078        if (split.getOrientation() == VERTICAL_SPLIT) {
079          simulateMovingDividerVertically(split, location);
080          return;
081        }
082        simulateMovingDividerHorizontally(split, location);
083      }
084    
085      @RunsInEDT
086      private void simulateMovingDividerVertically(JSplitPane splitPane, int location) {
087        GenericRange<Point> whereToMove = validateAndFindWhereToMoveDividerVertically(splitPane, location);
088        simulateMovingDivider(splitPane, whereToMove);
089      }
090    
091      @RunsInEDT
092      private static GenericRange<Point> validateAndFindWhereToMoveDividerVertically(final JSplitPane splitPane,
093          final int location) {
094        return execute(new GuiQuery<GenericRange<Point>>() {
095          protected GenericRange<Point> executeInEDT() {
096            validateIsEnabledAndShowing(splitPane);
097            return whereToMoveDividerVertically(splitPane, location);
098          }
099        });
100      }
101    
102      @RunsInCurrentThread
103      private static GenericRange<Point> whereToMoveDividerVertically(JSplitPane splitPane, int location) {
104          int x = splitPane.getWidth() / 2;
105          int dividerLocation = splitPane.getDividerLocation();
106          return new GenericRange<Point>(new Point(x, dividerLocation), new Point(x, location));
107      }
108    
109      private void simulateMovingDividerHorizontally(JSplitPane splitPane, int location) {
110        GenericRange<Point> whereToMove = validateAndFindWhereToMoveDividerHorizontally(splitPane, location);
111        simulateMovingDivider(splitPane, whereToMove);
112      }
113    
114      @RunsInEDT
115      private static GenericRange<Point> validateAndFindWhereToMoveDividerHorizontally(final JSplitPane splitPane,
116          final int location) {
117        return execute(new GuiQuery<GenericRange<Point>>() {
118          protected GenericRange<Point> executeInEDT() {
119            validateIsEnabledAndShowing(splitPane);
120            return whereToMoveDividerHorizontally(splitPane, location);
121          }
122        });
123      }
124    
125      @RunsInCurrentThread
126      private static GenericRange<Point> whereToMoveDividerHorizontally(JSplitPane splitPane, int location) {
127          int y = splitPane.getHeight() / 2;
128          int dividerLocation = splitPane.getDividerLocation();
129          return new GenericRange<Point>(new Point(dividerLocation, y), new Point(location, y));
130      }
131    
132      @RunsInEDT
133      private void simulateMovingDivider(JSplitPane splitPane, GenericRange<Point> range) {
134        try {
135          robot.moveMouse(splitPane, range.from);
136          robot.pressMouse(LEFT_BUTTON);
137          robot.moveMouse(splitPane, range.to);
138          robot.releaseMouse(LEFT_BUTTON);
139        } catch (RuntimeException ignored) {}
140      }
141    }