001 /*
002 * Created on Mar 16, 2008
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with 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
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 *
014 * Copyright @2008-2010 the original author or authors.
015 */
016 package org.fest.swing.driver;
017
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.edt.GuiActionRunner.execute;
021 import static org.fest.swing.timing.Pause.pause;
022
023 import java.awt.Point;
024 import java.util.regex.Pattern;
025
026 import javax.swing.JPopupMenu;
027 import javax.swing.table.JTableHeader;
028
029 import org.fest.swing.annotation.RunsInEDT;
030 import org.fest.swing.core.MouseButton;
031 import org.fest.swing.core.Robot;
032 import org.fest.swing.edt.GuiQuery;
033 import org.fest.swing.exception.ComponentLookupException;
034 import org.fest.swing.exception.LocationUnavailableException;
035 import org.fest.swing.util.*;
036
037 /**
038 * Understands functional testing of <code>{@link JTableHeader}</code>s:
039 * <ul>
040 * <li>user input simulation</li>
041 * <li>state verification</li>
042 * <li>property value query</li>
043 * </ul>
044 * This class is intended for internal use only. Please use the classes in the package
045 * <code>{@link org.fest.swing.fixture}</code> in your tests.
046 *
047 * @author Yvonne Wang
048 * @author Alex Ruiz
049 */
050 public class JTableHeaderDriver extends JComponentDriver {
051
052 private final JTableHeaderLocation location = new JTableHeaderLocation();
053
054 /**
055 * Creates a new </code>{@link JTableHeaderDriver}</code>.
056 * @param robot the robot to use to simulate user input.
057 */
058 public JTableHeaderDriver(Robot robot) {
059 super(robot);
060 }
061
062 /**
063 * Clicks the column under the given index.
064 * @param tableHeader the target <code>JTableHeader</code>.
065 * @param columnIndex the given index.
066 * @throws IllegalStateException if the <code>JTableHeader</code> is disabled.
067 * @throws IllegalStateException if the <code>JTableHeader</code> is not showing on the screen.
068 * @throws IndexOutOfBoundsException if the index is out of bounds.
069 */
070 @RunsInEDT
071 public void clickColumn(JTableHeader tableHeader, int columnIndex) {
072 clickColumn(tableHeader, columnIndex, LEFT_BUTTON, 1);
073 }
074
075 /**
076 * Clicks the column under the given index using the given mouse button the given number of times.
077 * @param tableHeader the target <code>JTableHeader</code>.
078 * @param columnIndex the given index.
079 * @param button the mouse button to use.
080 * @param times the number of times to click.
081 * @throws IllegalStateException if the <code>JTableHeader</code> is disabled.
082 * @throws IllegalStateException if the <code>JTableHeader</code> is not showing on the screen.
083 * @throws IndexOutOfBoundsException if the index is out of bounds.
084 */
085 @RunsInEDT
086 public void clickColumn(JTableHeader tableHeader, int columnIndex, MouseButton button, int times) {
087 Point p = pointAtIndex(tableHeader, columnIndex, location);
088 robot.click(tableHeader, p, button, times);
089 pause(300); // needs more time when sorting a column (JDK 1.6)
090 }
091
092 /**
093 * Clicks the column which name matches the given value.
094 * @param tableHeader the target <code>JTableHeader</code>.
095 * @param columnName the column name to match. It can be a regular expression.
096 * @throws IllegalStateException if the <code>JTableHeader</code> is disabled.
097 * @throws IllegalStateException if the <code>JTableHeader</code> is not showing on the screen.
098 * @throws LocationUnavailableException if a column with a matching name cannot be found.
099 */
100 @RunsInEDT
101 public void clickColumn(JTableHeader tableHeader, String columnName) {
102 clickColumn(tableHeader, columnName, LEFT_BUTTON, 1);
103 }
104
105 /**
106 * Clicks the column which name matches the given regular expression pattern.
107 * @param tableHeader the target <code>JTableHeader</code>.
108 * @param columnNamePattern the the regular expression pattern to match.
109 * @throws IllegalStateException if the <code>JTableHeader</code> is disabled.
110 * @throws IllegalStateException if the <code>JTableHeader</code> is not showing on the screen.
111 * @throws NullPointerException if the given regular expression pattern is <code>null</code>.
112 * @throws LocationUnavailableException if a column with a matching name cannot be found.
113 * @since 1.2
114 */
115 @RunsInEDT
116 public void clickColumn(JTableHeader tableHeader, Pattern columnNamePattern) {
117 clickColumn(tableHeader, columnNamePattern, LEFT_BUTTON, 1);
118 }
119
120 /**
121 * Clicks the column which name matches the given one using the given mouse button the given number of times.
122 * @param tableHeader the target <code>JTableHeader</code>.
123 * @param columnName the column name to match. It can be a regular expression.
124 * @param button the mouse button to use.
125 * @param times the number of times to click.
126 * @throws IllegalStateException if the <code>JTableHeader</code> is disabled.
127 * @throws IllegalStateException if the <code>JTableHeader</code> is not showing on the screen.
128 * @throws LocationUnavailableException if a column with a matching name cannot be found.
129 */
130 @RunsInEDT
131 public void clickColumn(JTableHeader tableHeader, String columnName, MouseButton button, int times) {
132 clickColumn(tableHeader, new StringTextMatcher(columnName), button, times);
133 }
134
135 /**
136 * Clicks the column which name matches the given regular expression pattern using the given mouse button the given
137 * number of times.
138 * @param tableHeader the target <code>JTableHeader</code>.
139 * @param columnNamePattern the regular expression pattern to match.
140 * @param button the mouse button to use.
141 * @param times the number of times to click.
142 * @throws IllegalStateException if the <code>JTableHeader</code> is disabled.
143 * @throws IllegalStateException if the <code>JTableHeader</code> is not showing on the screen.
144 * @throws NullPointerException if the given regular expression pattern is <code>null</code>.
145 * @throws LocationUnavailableException if a column with a matching name cannot be found.
146 * @since 1.2
147 */
148 @RunsInEDT
149 public void clickColumn(JTableHeader tableHeader, Pattern columnNamePattern, MouseButton button, int times) {
150 clickColumn(tableHeader, new PatternTextMatcher(columnNamePattern), button, times);
151 }
152
153 @RunsInEDT
154 private void clickColumn(JTableHeader tableHeader, TextMatcher matcher, MouseButton button, int times) {
155 Point p = pointAtName(tableHeader, matcher, location);
156 robot.click(tableHeader, p, button, times);
157 }
158
159 /**
160 * Shows a pop-up menu at the given column.
161 * @param tableHeader the target <code>JTableHeader</code>.
162 * @param columnIndex the index of the column.
163 * @return the displayed pop-up menu.
164 * @throws IllegalStateException if the <code>JTableHeader</code> is disabled.
165 * @throws IllegalStateException if the <code>JTableHeader</code> is not showing on the screen.
166 * @throws IndexOutOfBoundsException if the index is out of bounds.
167 * @throws ComponentLookupException if a pop-up menu cannot be found.
168 */
169 @RunsInEDT
170 public JPopupMenu showPopupMenu(JTableHeader tableHeader, int columnIndex) {
171 return robot.showPopupMenu(tableHeader, pointAtIndex(tableHeader, columnIndex, location));
172 }
173
174 @RunsInEDT
175 private static Point pointAtIndex(final JTableHeader tableHeader, final int columnIndex,
176 final JTableHeaderLocation location) {
177 return execute(new GuiQuery<Point>() {
178 protected Point executeInEDT() {
179 Point p = location.pointAt(tableHeader, columnIndex);
180 validateIsEnabledAndShowing(tableHeader);
181 tableHeader.getTable().scrollRectToVisible(tableHeader.getHeaderRect(columnIndex));
182 return p;
183 }
184 });
185 }
186
187 /**
188 * Shows a pop-up menu at the given column.
189 * @param tableHeader the target <code>JTableHeader</code>.
190 * @param columnName the name of the column. It can be a regular expression.
191 * @return the displayed pop-up menu.
192 * @throws IllegalStateException if the <code>JTableHeader</code> is disabled.
193 * @throws IllegalStateException if the <code>JTableHeader</code> is not showing on the screen.
194 * @throws ComponentLookupException if a pop-up menu cannot be found.
195 */
196 @RunsInEDT
197 public JPopupMenu showPopupMenu(JTableHeader tableHeader, String columnName) {
198 return robot.showPopupMenu(tableHeader, pointAtName(tableHeader, new StringTextMatcher(columnName), location));
199 }
200
201 /**
202 * Shows a pop-up menu at the column whose name matches the given regular expression pattern.
203 * @param tableHeader the target <code>JTableHeader</code>.
204 * @param pattern the regular expression pattern to match.
205 * @return the displayed pop-up menu.
206 * @throws IllegalStateException if the <code>JTableHeader</code> is disabled.
207 * @throws IllegalStateException if the <code>JTableHeader</code> is not showing on the screen.
208 * @throws NullPointerException if the given regular expression pattern is <code>null</code>.
209 * @throws ComponentLookupException if a pop-up menu cannot be found.
210 * @since 1.2
211 */
212 @RunsInEDT
213 public JPopupMenu showPopupMenu(JTableHeader tableHeader, Pattern pattern) {
214 return robot.showPopupMenu(tableHeader, pointAtName(tableHeader, new PatternTextMatcher(pattern), location));
215 }
216
217 @RunsInEDT
218 private static Point pointAtName(final JTableHeader tableHeader, final TextMatcher matcher,
219 final JTableHeaderLocation location) {
220 return execute(new GuiQuery<Point>() {
221 protected Point executeInEDT() {
222 Pair<Integer, Point> indexAndLocation = location.pointAt(tableHeader, matcher);
223 validateIsEnabledAndShowing(tableHeader);
224 tableHeader.getTable().scrollRectToVisible(tableHeader.getHeaderRect(indexAndLocation.i));
225 return indexAndLocation.ii;
226 }
227 });
228 }
229 }