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 }