001 /*
002 * Created on Jul 12, 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 static org.fest.assertions.Assertions.assertThat;
018 import static org.fest.swing.driver.ComponentDriver.propertyName;
019 import static org.fest.util.Strings.concat;
020
021 import java.awt.Color;
022 import java.awt.Font;
023 import java.awt.Point;
024 import java.util.regex.Pattern;
025
026 import javax.swing.JTable;
027 import javax.swing.table.JTableHeader;
028
029 import org.fest.assertions.Description;
030 import org.fest.swing.cell.JTableCellReader;
031 import org.fest.swing.cell.JTableCellWriter;
032 import org.fest.swing.core.KeyPressInfo;
033 import org.fest.swing.core.MouseButton;
034 import org.fest.swing.core.MouseClickInfo;
035 import org.fest.swing.core.Robot;
036 import org.fest.swing.data.TableCell;
037 import org.fest.swing.data.TableCellFinder;
038 import org.fest.swing.driver.BasicJTableCellReader;
039 import org.fest.swing.driver.BasicJTableCellWriter;
040 import org.fest.swing.driver.JTableDriver;
041 import org.fest.swing.exception.ActionFailedException;
042 import org.fest.swing.exception.ComponentLookupException;
043 import org.fest.swing.exception.WaitTimedOutError;
044 import org.fest.swing.timing.Timeout;
045
046 /**
047 * Understands functional testing of <code>{@link JTable}</code>s:
048 * <ul>
049 * <li>user input simulation</li>
050 * <li>state verification</li>
051 * <li>property value query</li>
052 * </ul>
053 * <p>
054 * The conversion between the values given in tests and the values being displayed by a <code>{@link JTable}</code>
055 * renderer is performed by a <code>{@link JTableCellReader}</code>. This fixture uses a
056 * <code>{@link BasicJTableCellReader}</code> by default.
057 * </p>
058 *
059 * @author Alex Ruiz
060 * @author Yvonne Wang
061 * @author Fabien Barbero
062 * @author Andriy Tsykholyas
063 */
064 public class JTableFixture extends ComponentFixture<JTable> implements CommonComponentFixture,
065 JComponentFixture, JPopupMenuInvokerFixture {
066
067 private JTableDriver driver;
068
069 /**
070 * Creates a new <code>{@link JTableFixture}</code>.
071 * @param robot performs simulation of user events on the given <code>JTable</code>.
072 * @param target the <code>JTable</code> to be managed by this fixture.
073 * @throws NullPointerException if <code>robot</code> is <code>null</code>.
074 * @throws NullPointerException if <code>target</code> is <code>null</code>.
075 */
076 public JTableFixture(Robot robot, JTable target) {
077 super(robot, target);
078 createDriver();
079 }
080
081 /**
082 * Creates a new <code>{@link JTableFixture}</code>.
083 * @param robot performs simulation of user events on a <code>JTable</code>.
084 * @param tableName the name of the <code>JTable</code> to find using the given <code>Robot</code>.
085 * @throws NullPointerException if <code>robot</code> is <code>null</code>.
086 * @throws ComponentLookupException if a matching <code>JTable</code> could not be found.
087 * @throws ComponentLookupException if more than one matching <code>JTable</code> is found.
088 */
089 public JTableFixture(Robot robot, String tableName) {
090 super(robot, tableName, JTable.class);
091 createDriver();
092 }
093
094 private void createDriver() {
095 driver(new JTableDriver(robot));
096 }
097
098 /**
099 * Sets the <code>{@link JTableDriver}</code> to be used by this fixture.
100 * @param newDriver the new <code>JTableDriver</code>.
101 * @throws NullPointerException if the given driver is <code>null</code>.
102 */
103 protected final void driver(JTableDriver newDriver) {
104 validateNotNull(newDriver);
105 driver = newDriver;
106 }
107
108 /**
109 * Returns the <code>{@link JTableDriver}</code> used by this fixture.
110 * @return the <code>JTableDriver</code> used by this fixture.
111 */
112 protected final JTableDriver driver() {
113 return driver;
114 }
115
116 /**
117 * Returns a fixture that verifies the font of the given table cell.
118 * @param cell the given table cell.
119 * @return a fixture that verifies the font of the given table cell.
120 * @throws NullPointerException if the cell is <code>null</code>.
121 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
122 */
123 public FontFixture fontAt(TableCell cell) {
124 Font font = driver.font(target, cell);
125 return new FontFixture(font, cellProperty(cell, FONT_PROPERTY));
126 }
127
128 /**
129 * Returns a fixture that verifies the background color of the given table cell.
130 * @param cell the given table cell.
131 * @return a fixture that verifies the background color of the given table cell.
132 * @throws NullPointerException if the cell is <code>null</code>.
133 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
134 */
135 public ColorFixture backgroundAt(TableCell cell) {
136 Color background = driver.background(target, cell);
137 return new ColorFixture(background, cellProperty(cell, BACKGROUND_PROPERTY));
138 }
139
140 /**
141 * Returns a fixture that verifies the foreground color of the given table cell.
142 * @param cell the given table cell.
143 * @return a fixture that verifies the foreground color of the given table cell.
144 * @throws NullPointerException if the cell is <code>null</code>.
145 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
146 */
147 public ColorFixture foregroundAt(TableCell cell) {
148 Color foreground = driver.foreground(target, cell);
149 return new ColorFixture(foreground, cellProperty(cell, FOREGROUND_PROPERTY));
150 }
151
152 private Description cellProperty(TableCell cell, String propertyName) {
153 return propertyName(target, concat(propertyName, " ", cell));
154 }
155
156 /**
157 * Returns a fixture that manages the table cell whose value matches the given one.
158 * @param value the value of the cell to look for. It can be a regular expression.
159 * @return a fixture that manages the table cell whose value matches the given one.
160 * @throws ActionFailedException if a cell with a matching value cannot be found.
161 */
162 public TableCell cell(String value) {
163 return driver.cell(target, value);
164 }
165
166 /**
167 * Returns a fixture that manages the table cell whose value matches the given regular expression pattern.
168 * @param valuePattern the regular expression pattern to match.
169 * @return a fixture that manages the table cell whose value matches the given one.
170 * @throws NullPointerException if the given regular expression pattern is <code>null</code>.
171 * @throws ActionFailedException if a cell with a matching value cannot be found.
172 * @since 1.2
173 */
174 public TableCell cell(Pattern valuePattern) {
175 return driver.cell(target, valuePattern);
176 }
177
178 /**
179 * Returns a fixture that manages the table cell found by the given <code>{@link TableCellFinder}</code>.
180 * @param cellFinder knows how to find a cell.
181 * @return a fixture that manages the found table cell.
182 * @throws NullPointerException if the <code>TableCellFinder</code> is <code>null</code>.
183 * @throws ActionFailedException if a matching cell could not be found.
184 * @throws IndexOutOfBoundsException if the row or column indices in the found cell are out of bounds.
185 */
186 public JTableCellFixture cell(TableCellFinder cellFinder) {
187 return new JTableCellFixture(this, driver.cell(target, cellFinder));
188 }
189
190 /**
191 * Returns a fixture that manages the table cell specified by the given row and column.
192 * @param cell the cell of interest.
193 * @return a fixture that manages the table cell specified by the given row and column.
194 * @throws NullPointerException if the cell is <code>null</code>.
195 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
196 */
197 public JTableCellFixture cell(TableCell cell) {
198 driver.validate(target, cell);
199 return new JTableCellFixture(this, cell);
200 }
201
202 /**
203 * Returns a <code>{@link JTableHeaderFixture}</code> wrapping the <code>{@link JTableHeader}</code> in this fixture's
204 * <code>{@link JTable}</code>.
205 * @return a <code>JTableHeaderFixture</code> wrapping the <code>JTableHeader</code> in this fixture's
206 * <code>JTable</code>.
207 * @throws AssertionError if the <code>JTableHeader</code> in this fixture's <code>JTable</code> is <code>null</code>.
208 */
209 public JTableHeaderFixture tableHeader() {
210 JTableHeader tableHeader = driver.tableHeaderOf(target);
211 assertThat(tableHeader).isNotNull();
212 return new JTableHeaderFixture(robot, tableHeader);
213 }
214
215 /**
216 * Returns the <code>String</code> representation of the selected cell in this fixture's <code>{@link JTable}</code>,
217 * using this fixture's <code>{@link JTableCellReader}</code>. Returns <code>null</code> if one can not be obtained or
218 * if the <code>{@link JTable}</code> does not have any selected cell.
219 * @return the <code>String</code> representation of the selected cell.
220 * @see #cellReader(JTableCellReader)
221 */
222 public String selectionValue() {
223 return driver.selectionValue(target);
224 }
225
226 /**
227 * Converts the given cell into a coordinate pair.
228 * @param cell the given cell.
229 * @return the coordinates of the given cell.
230 * @throws NullPointerException if the cell is <code>null</code>.
231 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
232 */
233 public Point pointAt(TableCell cell) {
234 return driver.pointAt(target, cell);
235 }
236
237 /**
238 * Returns the <code>String</code> representation of the cells in the in this fixture's <code>{@link JTable}</code>,
239 * using this fixture's <code>{@link JTableCellReader}</code>.
240 * @return the <code>String</code> representation of the cells in thi fixture's <code>JTable</code>.
241 * @see #cellReader(JTableCellReader)
242 */
243 public String[][] contents() {
244 return driver.contents(target);
245 }
246
247 /**
248 * Returns the number of rows that can be shown in this fixture's <code>{@link JTable}</code>, given unlimited space.
249 * @return the number of rows shown in this fixture's <code>JTable</code>.
250 * @see JTable#getRowCount()
251 */
252 public int rowCount() {
253 return driver.rowCountOf(target);
254 }
255
256 /**
257 * Returns the <code>String</code> representation of the value of a cell in this fixture's
258 * <code>{@link JTable}</code>, using this fixture's <code>{@link JTableCellReader}</code>.
259 * @param cell the given cell.
260 * @return the <code>String</code> representation of the value of a cell in this fixture's <code>JTable</code>.
261 * @throws NullPointerException if the cell is <code>null</code>.
262 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
263 * @see #cellReader(JTableCellReader)
264 */
265 public String valueAt(TableCell cell) {
266 return driver.value(target, cell);
267 }
268
269 /**
270 * Simulates a user selecting the given cell (row and column) of this fixture's <code>{@link JTable}</code>.
271 * @param cell the cell to select.
272 * @return this fixture.
273 * @throws NullPointerException if the cell is <code>null</code>.
274 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
275 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
276 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
277 */
278 public JTableFixture selectCell(TableCell cell) {
279 driver.selectCell(target, cell);
280 return this;
281 }
282
283 /**
284 * Simulates a user selecting the given cells of this fixture's <code>{@link JTable}</code>.
285 * @param cells the cells to select.
286 * @return this fixture.
287 * @throws NullPointerException if <code>cells</code> is <code>null</code> or empty.
288 * @throws IllegalArgumentException if <code>cells</code> is <code>null</code> or empty.
289 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
290 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
291 * @throws NullPointerException if any element in <code>cells</code> is <code>null</code>.
292 * @throws IndexOutOfBoundsException if any of the indices of any of the <code>cells</code> are out of bounds.
293 */
294 public JTableFixture selectCells(TableCell... cells) {
295 driver.selectCells(target, cells);
296 return this;
297 }
298
299
300 /**
301 * Simulates a user selecting the given rows in this fixture's <code>{@link JTable}</code>.
302 * @param rows the indices of the row to select.
303 * @return this fixture.
304 * @throws NullPointerException if the given array of indices is <code>null</code>.
305 * @throws IllegalArgumentException if the given array of indices is empty.
306 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
307 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
308 * @throws IndexOutOfBoundsException if any of the given indices is out of bounds.
309 * @since 1.2
310 */
311 public JTableFixture selectRows(int... rows) {
312 driver.selectRows(target, rows);
313 return this;
314 }
315
316 /**
317 * Simulates a user dragging an item from this fixture's <code>{@link JTable}</code>.
318 * @param cell the cell to drag.
319 * @return this fixture.
320 * @throws NullPointerException if the cell is <code>null</code>.
321 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
322 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
323 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
324 */
325 public JTableFixture drag(TableCell cell) {
326 driver.drag(target, cell);
327 return this;
328 }
329
330 /**
331 * Simulates a user dropping an item to this fixture's <code>{@link JTable}</code>.
332 * @param cell the cell to drop the dragging item into.
333 * @return this fixture.
334 * @throws NullPointerException if the cell is <code>null</code>.
335 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
336 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
337 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
338 */
339 public JTableFixture drop(TableCell cell) {
340 driver.drop(target, cell);
341 return this;
342 }
343
344 /**
345 * Simulates a user clicking this fixture's <code>{@link JTable}</code>.
346 * @return this fixture.
347 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
348 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
349 */
350 public JTableFixture click() {
351 driver.click(target);
352 return this;
353 }
354
355 /**
356 * Simulates a user clicking this fixture's <code>{@link JTable}</code>.
357 * @param button the button to click.
358 * @return this fixture.
359 * @throws NullPointerException if the given <code>MouseButton</code> is <code>null</code>.
360 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
361 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
362 */
363 public JTableFixture click(MouseButton button) {
364 driver.click(target, button);
365 return this;
366 }
367
368 /**
369 * Simulates a user clicking this fixture's <code>{@link JTable}</code>.
370 * @param mouseClickInfo specifies the button to click and the times the button should be clicked.
371 * @return this fixture.
372 * @throws NullPointerException if the given <code>MouseClickInfo</code> is <code>null</code>.
373 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
374 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
375 */
376 public JTableFixture click(MouseClickInfo mouseClickInfo) {
377 driver.click(target, mouseClickInfo);
378 return this;
379 }
380
381 /**
382 * Simulates a user clicking a cell in this fixture's <code>{@link JTable}</code> once, using the specified mouse
383 * button.
384 * @param cell the cell to click.
385 * @param button the mouse button to use.
386 * @return this fixture.
387 * @throws NullPointerException if the cell is <code>null</code>.
388 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
389 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
390 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
391 */
392 public JTableFixture click(TableCell cell, MouseButton button) {
393 click(cell, button, 1);
394 return this;
395 }
396
397 /**
398 * Simulates a user clicking a cell in this fixture's <code>{@link JTable}</code>, using the specified mouse button
399 * the given number of times.
400 * @param cell the cell to click.
401 * @param mouseClickInfo specifies the mouse button to use and how many times to click.
402 * @return this fixture.
403 * @throws NullPointerException if the given <code>MouseClickInfo</code> is <code>null</code>.
404 * @throws NullPointerException if the cell is <code>null</code>.
405 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
406 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
407 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
408 */
409 public JTableFixture click(TableCell cell, MouseClickInfo mouseClickInfo) {
410 if (mouseClickInfo == null) throw new NullPointerException("The given MouseClickInfo should not be null");
411 click(cell, mouseClickInfo.button(), mouseClickInfo.times());
412 return this;
413 }
414
415 void click(TableCell cell, MouseButton button, int times) {
416 driver.click(target, cell, button, times);
417 }
418
419 /**
420 * Simulates a user double-clicking this fixture's <code>{@link JTable}</code>.
421 * <p>
422 * <b>Note:</b> This method will not be successful if the double-clicking occurs on an editable table cell. For this
423 * particular case, this method will start edition of the table cell located under the mouse pointer.
424 * </p>
425 * @return this fixture.
426 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
427 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
428 */
429 public JTableFixture doubleClick() {
430 driver.doubleClick(target);
431 return this;
432 }
433
434 /**
435 * Simulates a user right-clicking this fixture's <code>{@link JTable}</code>.
436 * @return this fixture.
437 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
438 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
439 */
440 public JTableFixture rightClick() {
441 driver.rightClick(target);
442 return this;
443 }
444
445 /**
446 * Simulates a user pressing given key with the given modifiers on this fixture's <code>{@link JTable}</code>.
447 * Modifiers is a mask from the available <code>{@link java.awt.event.InputEvent}</code> masks.
448 * @param keyPressInfo specifies the key and modifiers to press.
449 * @return this fixture.
450 * @throws NullPointerException if the given <code>KeyPressInfo</code> is <code>null</code>.
451 * @throws IllegalArgumentException if the given code is not a valid key code.
452 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
453 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
454 * @see KeyPressInfo
455 */
456 public JTableFixture pressAndReleaseKey(KeyPressInfo keyPressInfo) {
457 driver.pressAndReleaseKey(target, keyPressInfo);
458 return this;
459 }
460
461 /**
462 * Simulates a user pressing and releasing the given keys on this fixture's <code>{@link JTable}</code>. This method
463 * does not affect the current focus.
464 * @param keyCodes one or more codes of the keys to press.
465 * @return this fixture.
466 * @throws NullPointerException if the given array of codes is <code>null</code>.
467 * @throws IllegalArgumentException if any of the given code is not a valid key code.
468 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
469 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
470 * @see java.awt.event.KeyEvent
471 */
472 public JTableFixture pressAndReleaseKeys(int... keyCodes) {
473 driver.pressAndReleaseKeys(target, keyCodes);
474 return this;
475 }
476
477 /**
478 * Simulates a user pressing the given key on this fixture's <code>{@link JTable}</code>.
479 * @param keyCode the code of the key to press.
480 * @return this fixture.
481 * @throws IllegalArgumentException if any of the given code is not a valid key code.
482 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
483 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
484 * @see java.awt.event.KeyEvent
485 */
486 public JTableFixture pressKey(int keyCode) {
487 driver.pressKey(target, keyCode);
488 return this;
489 }
490
491 /**
492 * Simulates a user releasing the given key on this fixture's <code>{@link JTable}</code>.
493 * @param keyCode the code of the key to release.
494 * @return this fixture.
495 * @throws IllegalArgumentException if any of the given code is not a valid key code.
496 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
497 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
498 * @see java.awt.event.KeyEvent
499 */
500 public JTableFixture releaseKey(int keyCode) {
501 driver.releaseKey(target, keyCode);
502 return this;
503 }
504
505 /**
506 * Gives input focus to this fixture's <code>{@link JTable}</code>.
507 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
508 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
509 * @return this fixture.
510 */
511 public JTableFixture focus() {
512 driver.focus(target);
513 return this;
514 }
515
516 /**
517 * Enters the given value in the given cell of this fixture's <code>{@link JTable}</code>, using this fixture's
518 * <code>{@link JTableCellWriter}</code>. If you need more flexibility for editing cell, please see
519 * <code>{@link JTableCellFixture#editor()}</code>.
520 * @param cell the given cell.
521 * @param value the given value.
522 * @return this fixture.
523 * @throws NullPointerException if the cell is <code>null</code>.
524 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
525 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
526 * @throws IllegalStateException if this fixture's <code>JTable</code> is not editable.
527 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
528 * @throws ActionFailedException if this fixture's <code>JTableCellValueReader</code> is unable to enter the given
529 * value.
530 * @see #cellWriter(JTableCellWriter)
531 * @see JTableCellFixture#editor()
532 */
533 public JTableFixture enterValue(TableCell cell, String value) {
534 driver.enterValueInCell(target, cell, value);
535 return this;
536 }
537
538 /**
539 * Updates the implementation of <code>{@link JTableCellReader}</code> to use when comparing internal values of this
540 * fixture's <code>{@link JTable}</code> and the values expected in a test. The default implementation to use is
541 * <code>{@link BasicJTableCellReader}</code>.
542 * @param cellReader the new <code>JTableCellValueReader</code> to use.
543 * @throws NullPointerException if <code>cellReader</code> is <code>null</code>.
544 * @return this fixture.
545 */
546 public JTableFixture cellReader(JTableCellReader cellReader) {
547 driver.cellReader(cellReader);
548 return this;
549 }
550
551 /**
552 * Asserts that this fixture's <code>{@link JTable}</code> has the given number of rows.
553 * @param expected the expected number of rows.
554 * @return this fixture.
555 * @throws AssertionError if this fixture's <code>JTable</code> does not have the given number of rows.
556 */
557 public JTableFixture requireRowCount(int expected) {
558 driver.requireRowCount(target, expected);
559 return this;
560 }
561
562 /**
563 * Asserts that the set of selected rows in this fixture's <code>{@link JTable}</code> contains to the given row
564 * indices. The given row indices can be a subset of all the selected rows in a <code>JTable</code>.
565 * @param rows the indices of the rows expected to be selected.
566 * @return this fixture.
567 * @throws AssertionError if the set of selected rows in this fixture's <code>JTable</code> (if any) do not contain
568 * the given indices.
569 * @since 1.2
570 */
571 public JTableFixture requireSelectedRows(int... rows) {
572 driver.requireSelectedRows(target, rows);
573 return this;
574 }
575
576 /**
577 * Asserts that this fixture's <code>{@link JTable}</code> has the given number of columns.
578 * @param expected the expected number of columns.
579 * @return this fixture.
580 * @throws AssertionError if this fixture's <code>JTable</code> does not have the given number of columns.
581 */
582 public JTableFixture requireColumnCount(int expected) {
583 driver.requireColumnCount(target, expected);
584 return this;
585 }
586
587 /**
588 * Asserts that this fixture's <code>{@link JTable}</code> has input focus.
589 * @return this fixture.
590 * @throws AssertionError if this fixture's <code>JTable</code> does not have input focus.
591 */
592 public JTableFixture requireFocused() {
593 driver.requireFocused(target);
594 return this;
595 }
596
597 /**
598 * Asserts that this fixture's <code>{@link JTable}</code> is enabled.
599 * @return this fixture.
600 * @throws AssertionError is the managed <code>JTable</code> is disabled.
601 */
602 public JTableFixture requireEnabled() {
603 driver.requireEnabled(target);
604 return this;
605 }
606
607 /**
608 * Asserts that this fixture's <code>{@link JTable}</code> is enabled.
609 * @param timeout the time this fixture will wait for the component to be enabled.
610 * @return this fixture.
611 * @throws WaitTimedOutError if the managed <code>JTable</code> is never enabled.
612 */
613 public JTableFixture requireEnabled(Timeout timeout) {
614 driver.requireEnabled(target, timeout);
615 return this;
616 }
617
618 /**
619 * Asserts that this fixture's <code>{@link JTable}</code> is disabled.
620 * @return this fixture.
621 * @throws AssertionError is the managed <code>JTable</code> is enabled.
622 */
623 public JTableFixture requireDisabled() {
624 driver.requireDisabled(target);
625 return this;
626 }
627
628 /**
629 * Asserts that this fixture's <code>{@link JTable}</code> is visible.
630 * @return this fixture.
631 * @throws AssertionError if the managed <code>JTable</code> is not visible.
632 */
633 public JTableFixture requireVisible() {
634 driver.requireVisible(target);
635 return this;
636 }
637
638 /**
639 * Asserts that this fixture's <code>{@link JTable}</code> is not visible.
640 * @return this fixture.
641 * @throws AssertionError if the managed <code>JTable</code> is visible.
642 */
643 public JTableFixture requireNotVisible() {
644 driver.requireNotVisible(target);
645 return this;
646 }
647
648 /**
649 * Asserts that the toolTip in this fixture's <code>{@link JTable}</code> matches the given value.
650 * @param expected the given value. It can be a regular expression.
651 * @return this fixture.
652 * @throws AssertionError if the toolTip in this fixture's <code>JTable</code> does not match the given value.
653 * @since 1.2
654 */
655 public JTableFixture requireToolTip(String expected) {
656 driver.requireToolTip(target, expected);
657 return this;
658 }
659
660 /**
661 * Asserts that the toolTip in this fixture's <code>{@link JTable}</code> matches the given regular expression
662 * pattern.
663 * @param pattern the regular expression pattern to match.
664 * @return this fixture.
665 * @throws NullPointerException if the given regular expression pattern is <code>null</code>.
666 * @throws AssertionError if the toolTip in this fixture's <code>JTable</code> does not match the given regular
667 * expression pattern.
668 * @since 1.2
669 */
670 public JTableFixture requireToolTip(Pattern pattern) {
671 driver.requireToolTip(target, pattern);
672 return this;
673 }
674
675 /**
676 * Asserts that the given cell in this fixture's <code>{@link JTable}</code> is editable.
677 * @param cell the given cell.
678 * @return this fixture.
679 * @throws NullPointerException if the cell is <code>null</code>.
680 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
681 * @throws AssertionError if the given cell is not editable.
682 */
683 public JTableFixture requireEditable(TableCell cell) {
684 driver.requireEditable(target, cell);
685 return this;
686 }
687
688 /**
689 * Asserts that the given cell in this fixture's <code>{@link JTable}</code> is not editable.
690 * @param cell the given cell.
691 * @return this fixture.
692 * @throws NullPointerException if the cell is <code>null</code>.
693 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
694 * @throws AssertionError if the given cell is editable.
695 */
696 public JTableFixture requireNotEditable(TableCell cell) {
697 driver.requireNotEditable(target, cell);
698 return this;
699 }
700
701 /**
702 * Verifies that this fixture's <code>{@link JTable}</code> does not have any selection.
703 * @return this fixture.
704 * @throws AssertionError if this fixture's <code>JTable</code> has a selection.
705 */
706 public JTableFixture requireNoSelection() {
707 driver.requireNoSelection(target);
708 return this;
709 }
710
711 /**
712 * Asserts that the value of the given cell matches the given value.
713 * @param cell the given table cell.
714 * @param value the expected value. It can be a regular expression.
715 * @return this fixture.
716 * @throws NullPointerException if the cell is <code>null</code>.
717 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
718 * @throws AssertionError if the value of the given cell does not match the given value.
719 */
720 public JTableFixture requireCellValue(TableCell cell, String value) {
721 driver.requireCellValue(target, cell, value);
722 return this;
723 }
724
725 /**
726 * Asserts that the value of the given cell matches the given regular expression pattern.
727 * @param cell the given table cell.
728 * @param pattern the regular expression pattern to match.
729 * @return this fixture.
730 * @throws NullPointerException if the cell is <code>null</code>.
731 * @throws NullPointerException if the given regular expression pattern is <code>null</code>.
732 * @throws IndexOutOfBoundsException if any of the indices (row and column) is out of bounds.
733 * @throws AssertionError if the value of the given cell does not match the given regular expression pattern.
734 * @since 1.2
735 */
736 public JTableFixture requireCellValue(TableCell cell, Pattern pattern) {
737 driver.requireCellValue(target, cell, pattern);
738 return this;
739 }
740
741 /**
742 * Asserts that the <code>String</code> representation of the cell values in this fixture's
743 * <code>{@link JTable}</code> is equal to the given <code>String</code> array. This method uses this fixture's
744 * <code>{@link JTableCellReader}</code> to read the values of the table cells as <code>String</code>s.
745 * @param contents the expected <code>String</code> representation of the cell values in this fixture's
746 * <code>JTable</code>.
747 * @return this fixture.
748 * @see #cellReader(JTableCellReader)
749 */
750 public JTableFixture requireContents(String[][] contents) {
751 driver.requireContents(target, contents);
752 return this;
753 }
754
755 /**
756 * Updates the implementation of <code>{@link JTableCellWriter}</code> to use when comparing internal values of this
757 * fixture's <code>{@link JTable}</code> and the values expected in a test. The default implementation to use is
758 * <code>{@link BasicJTableCellWriter}</code>.
759 * @param cellWriter the new <code>JTableCellValueWriter</code> to use.
760 * @throws NullPointerException if <code>cellWriter</code> is <code>null</code>.
761 * @return this fixture.
762 */
763 public JTableFixture cellWriter(JTableCellWriter cellWriter) {
764 driver.cellWriter(cellWriter);
765 return this;
766 }
767
768 /**
769 * Returns the index of the column in this fixture's <code>{@link JTable}</code> whose name matches the given one.
770 * @param columnName the name of the column to look for.
771 * @return the index of the column whose name matches the given one.
772 * @throws ActionFailedException if a column with a matching name could not be found.
773 */
774 public int columnIndexFor(Object columnName) {
775 return driver.columnIndex(target, columnName);
776 }
777
778 /**
779 * Returns the client property stored in this fixture's <code>{@link JTable}</code>, under the given key.
780 * @param key the key to use to retrieve the client property.
781 * @return the value of the client property stored under the given key, or <code>null</code> if the property was
782 * not found.
783 * @throws NullPointerException if the given key is <code>null</code>.
784 * @since 1.2
785 */
786 public Object clientProperty(Object key) {
787 return driver.clientProperty(target, key);
788 }
789
790 /**
791 * Shows a pop-up menu using this fixture's <code>{@link JTable}</code> as the invoker of the pop-up menu.
792 * @return a fixture that manages the displayed pop-up menu.
793 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
794 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
795 * @throws ComponentLookupException if a pop-up menu cannot be found.
796 */
797 public JPopupMenuFixture showPopupMenu() {
798 return new JPopupMenuFixture(robot, driver.invokePopupMenu(target));
799 }
800
801 /**
802 * Shows a pop-up menu at the given point using this fixture's <code>{@link JTable}</code> as the invoker of the
803 * pop-up menu.
804 * @param p the given point where to show the pop-up menu.
805 * @return a fixture that manages the displayed pop-up menu.
806 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
807 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
808 * @throws ComponentLookupException if a pop-up menu cannot be found.
809 */
810 public JPopupMenuFixture showPopupMenuAt(Point p) {
811 return new JPopupMenuFixture(robot, driver.invokePopupMenu(target, p));
812 }
813
814 /**
815 * Shows a pop-up menu at the given cell.
816 * @param cell the table cell where to show the pop-up menu.
817 * @return a fixture that manages the displayed pop-up menu.
818 * @throws NullPointerException if the cell is <code>null</code>.
819 * @throws IllegalStateException if this fixture's <code>JTable</code> is disabled.
820 * @throws IllegalStateException if this fixture's <code>JTable</code> is not showing on the screen.
821 * @throws ComponentLookupException if a pop-up menu cannot be found.
822 */
823 public JPopupMenuFixture showPopupMenuAt(TableCell cell) {
824 return new JPopupMenuFixture(robot, driver.showPopupMenuAt(target, cell));
825 }
826 }