001 /*
002 * Created on Jan 27, 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 org.fest.swing.driver.ComponentStateValidator.validateIsEnabledAndShowing;
018 import static org.fest.swing.driver.JSliderSetValueTask.setValue;
019 import static org.fest.swing.edt.GuiActionRunner.execute;
020 import static org.fest.util.Strings.concat;
021
022 import java.awt.Point;
023
024 import javax.swing.JSlider;
025
026 import org.fest.swing.annotation.RunsInCurrentThread;
027 import org.fest.swing.annotation.RunsInEDT;
028 import org.fest.swing.core.Robot;
029 import org.fest.swing.edt.GuiQuery;
030 import org.fest.swing.util.GenericRange;
031 import org.fest.swing.util.Pair;
032
033 /**
034 * Understands functional testing of <code>{@link JSlider}</code>s:
035 * <ul>
036 * <li>user input simulation</li>
037 * <li>state verification</li>
038 * <li>property value query</li>
039 * </ul>
040 * This class is intended for internal use only. Please use the classes in the package
041 * <code>{@link org.fest.swing.fixture}</code> in your tests.
042 *
043 * @author Alex Ruiz
044 * @author Yvonne Wang
045 */
046 public class JSliderDriver extends JComponentDriver {
047
048 private final JSliderLocation location;
049
050 /**
051 * Creates a new </code>{@link JSliderDriver}</code>.
052 * @param robot the robot to use to simulate user input.
053 */
054 public JSliderDriver(Robot robot) {
055 super(robot);
056 location = new JSliderLocation();
057 }
058
059 /**
060 * Slides the knob to its maximum.
061 * @param slider the target <code>JSlider</code>.
062 * @throws IllegalStateException if the <code>JSlider</code> is disabled.
063 * @throws IllegalStateException if the <code>JSlider</code> is not showing on the screen.
064 */
065 @RunsInEDT
066 public void slideToMaximum(JSlider slider) {
067 slide(slider, validateAndFindSlideToMaximumInfo(slider, location));
068 }
069
070 @RunsInEDT
071 private static Pair<Integer, GenericRange<Point>> validateAndFindSlideToMaximumInfo(final JSlider slider,
072 final JSliderLocation location) {
073 return execute(new GuiQuery<Pair<Integer, GenericRange<Point>>>() {
074 protected Pair<Integer, GenericRange<Point>> executeInEDT() {
075 validateIsEnabledAndShowing(slider);
076 int value = slider.getMaximum();
077 GenericRange<Point> fromAndTo = slideInfo(slider, location, value);
078 return new Pair<Integer, GenericRange<Point>>(value, fromAndTo);
079 }
080 });
081 }
082
083 /**
084 * Slides the knob to its minimum.
085 * @param slider the target <code>JSlider</code>.
086 * @throws IllegalStateException if the <code>JSlider</code> is disabled.
087 * @throws IllegalStateException if the <code>JSlider</code> is not showing on the screen.
088 */
089 @RunsInEDT
090 public void slideToMinimum(JSlider slider) {
091 slide(slider, validateAndFindSlideToMinimumInfo(slider, location));
092 }
093
094 @RunsInEDT
095 private static Pair<Integer, GenericRange<Point>> validateAndFindSlideToMinimumInfo(final JSlider slider,
096 final JSliderLocation location) {
097 return execute(new GuiQuery<Pair<Integer, GenericRange<Point>>>() {
098 protected Pair<Integer, GenericRange<Point>> executeInEDT() {
099 validateIsEnabledAndShowing(slider);
100 int value = slider.getMinimum();
101 GenericRange<Point> fromAndTo = slideInfo(slider, location, value);
102 return new Pair<Integer, GenericRange<Point>>(value, fromAndTo);
103 }
104 });
105 }
106
107 @RunsInEDT
108 private void slide(JSlider slider, Pair<Integer, GenericRange<Point>> slideInfo) {
109 slide(slider, slideInfo.i, slideInfo.ii);
110 }
111
112 /**
113 * Slides the knob to the requested value.
114 * @param slider the target <code>JSlider</code>.
115 * @param value the requested value.
116 * @throws IllegalStateException if the <code>JSlider</code> is disabled.
117 * @throws IllegalStateException if the <code>JSlider</code> is not showing on the screen.
118 * @throws IllegalArgumentException if the given position is not within the <code>JSlider</code> bounds.
119 */
120 @RunsInEDT
121 public void slide(JSlider slider, int value) {
122 GenericRange<Point> slideInfo = validateAndFindSlideInfo(slider, location, value);
123 slide(slider, value, slideInfo);
124 }
125
126 @RunsInEDT
127 private void slide(JSlider slider, int value, GenericRange<Point> fromAndTo) {
128 moveMouseIgnoringAnyError(slider, fromAndTo.from);
129 moveMouseIgnoringAnyError(slider, fromAndTo.to);
130 setValue(slider, value);
131 robot.waitForIdle();
132 }
133
134 @RunsInEDT
135 private static GenericRange<Point> validateAndFindSlideInfo(final JSlider slider, final JSliderLocation location,
136 final int value) {
137 return execute(new GuiQuery<GenericRange<Point>>() {
138 protected GenericRange<Point> executeInEDT() {
139 validateValue(slider, value);
140 validateIsEnabledAndShowing(slider);
141 return slideInfo(slider, location, value);
142 }
143 });
144 }
145
146 @RunsInCurrentThread
147 private static void validateValue(JSlider slider, int value) {
148 int min = slider.getMinimum();
149 int max = slider.getMaximum();
150 if (value >= min && value <= max) return;
151 throw new IllegalArgumentException(
152 concat("Value <", value, "> is not within the JSlider bounds of <", min, "> and <", max, ">"));
153 }
154
155 @RunsInCurrentThread
156 private static GenericRange<Point> slideInfo(JSlider slider, JSliderLocation location, int value) {
157 Point from = location.pointAt(slider, slider.getValue());
158 Point to = location.pointAt(slider, value);
159 return new GenericRange<Point>(from, to);
160 }
161 }