com.objogate.wl.swing.driver.JTableDriver Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of windowlicker-swing Show documentation
Show all versions of windowlicker-swing Show documentation
This is the Windowlicker Swing library.
The newest version!
package com.objogate.wl.swing.driver;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTable;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.util.Iterator;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import com.objogate.exception.Defect;
import com.objogate.wl.Gesture;
import com.objogate.wl.Prober;
import com.objogate.wl.Query;
import com.objogate.wl.gesture.Gestures;
import static com.objogate.wl.gesture.Gestures.*;
import com.objogate.wl.gesture.Tracker;
import com.objogate.wl.swing.ComponentManipulation;
import com.objogate.wl.swing.ComponentSelector;
import com.objogate.wl.swing.driver.table.*;
import static com.objogate.wl.swing.driver.table.JTableCellManipulation.render;
import com.objogate.wl.swing.gesture.GesturePerformer;
public class JTableDriver extends JComponentDriver {
public JTableDriver(ComponentDriver extends Container> containerDriver, Matcher super JTable>... matchers) {
super(containerDriver, JTable.class, matchers);
}
public JTableDriver(GesturePerformer gesturePerformer, ComponentSelector componentSelector, Prober prober) {
super(gesturePerformer, componentSelector, prober);
}
public JTableDriver(ComponentDriver extends Component> parentOrOwner, ComponentSelector componentSelector) {
super(parentOrOwner, componentSelector);
}
public JTableDriver(ComponentDriver extends Component> parentOrOwner, Class componentType, Matcher super JTable>... matchers) {
super(parentOrOwner, componentType, matchers);
}
@Override
protected int appropriateInputMapId() {
return JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
}
public static boolean arrayContains(int[] stuff, int item) {
for (int selectedRow : stuff) {
if (item == selectedRow)
return true;
}
return false;
}
public void selectCells(Cell... cells) {
scrollCellToVisible(cells[0]);
Gesture[] gestures = new Gesture[cells.length];
for (int i = 0; i < cells.length; i++) {
gestures[i] = sequence(
moveMouseTo(pointIn(cells[i])),
leftClickMouse()
);
}
performGesture(sequence(gestures));
}
public void selectCell(final int row, final int col) {
selectCells(cell(row, col));
}
public void selectCell(final Matcher extends JComponent> matcher) {
final Cell cell = hasCell(matcher);
if (cell == null) {
throw new Defect("Cannot find cell");
}
selectCells(cell);
}
public void dragMouseOver(Cell start, Cell end) {
scrollCellToVisible(start);
performGesture(
moveMouseTo(pointIn(start)),
whileHoldingMouseButton(BUTTON1,
moveMouseTo(pointIn(end)))
);
}
private Tracker pointIn(Cell start) {
return offset(relativeMidpointOfColumn(start.col), rowOffset(start.row));
}
public Cell hasCell(final Matcher extends JComponent> matcher) {
RenderedCellMatcher cellMatcher = new RenderedCellMatcher(matcher);
is(new CellInTableMatcher(cellMatcher));
return cellMatcher.foundCell.cell;
}
public void hasRow(Matcher> rowMatcher) {
is(new RowInTableMatcher(rowMatcher));
}
public Component editCell(int row, int col) {
mouseOverCell(row, col);
performGesture(Gestures.doubleClickMouse());
JTableCellManipulation manipulation = new JTableCellManipulation(row, col);
perform("finding cell editor", manipulation);
return manipulation.getEditorComponent();
}
public void mouseOverCell(Cell cell) {
mouseOverCell(cell.row, cell.col);
}
public void mouseOverCell(int row, int col) {
scrollCellToVisible(row, col);
int y = rowOffset(row);
int x = relativeMidpointOfColumn(col);
moveMouseToOffset(x, y);
}
private int rowOffset(int row) {
int rowHeight = rowHeight();
return (rowHeight * row) + (rowHeight / 2);
}
private int relativeMidpointOfColumn(final int col) {
ColumnManipulation manipulation = new ColumnManipulation(col);
perform("column mid point", manipulation);
return manipulation.getMidPoint();
}
private int rowHeight() {
JTableRowHeightManipulation tableManipulation = new JTableRowHeightManipulation();
perform("row height", tableManipulation);
return tableManipulation.getRowHeight();
}
public void hasSelectedCells(final Cell... cells) {
is(new SelectedCellsMatcher(cells));
}
public void scrollCellToVisible(Cell cell) {
scrollCellToVisible(cell.row, cell.col);
}
//todo (nick): this should be a gesture
public void scrollCellToVisible(final int row, final int col) {
perform("table scrolling", new ComponentManipulation() {
public void manipulate(JTable table) {
table.scrollRectToVisible(table.getCellRect(row, col, true));
}
});
}
public void cellHasColour(int row, Object columnIdentifier, Matcher foregroundColor, Matcher backgroundColor) {
cellHasBackgroundColor(row, columnIdentifier, backgroundColor);
cellHasForegroundColor(row, columnIdentifier, foregroundColor);
}
public void cellHasColour(int row, int col, Matcher foregroundColor, Matcher backgroundColor) {
cellHasBackgroundColor(row, col, backgroundColor);
cellHasForegroundColor(row, col, foregroundColor);
}
public void cellHasBackgroundColor(final int row, final Object columnIdentifier, Matcher backgroundColor) {
cellHasBackgroundColor(cell(row, columnIdentifier), backgroundColor);
}
public void cellHasBackgroundColor(final int row, final int col, Matcher backgroundColor) {
cellHasBackgroundColor(cell(row, col), backgroundColor);
}
public void cellHasForegroundColor(final int row, final Object columnIdentifier, Matcher foregroundColor) {
cellHasForegroundColor(cell(row, columnIdentifier), foregroundColor);
}
public void cellHasForegroundColor(final int row, final int col, Matcher foregroundColor) {
cellHasForegroundColor(cell(row, col), foregroundColor);
}
public void cellRenderedWithText(final int row, final Object columnIdentifier, Matcher expectedText) {
cellRenderedWithText(cell(row, columnIdentifier), expectedText);
}
public void cellRenderedWithText(final int row, final int col, Matcher expectedText) {
cellRenderedWithText(cell(row, col), expectedText);
}
public void cellHasForegroundColor(final Location cell, Matcher foregroundColor) {
has(cellWith(cell, foregroundColor()), foregroundColor);
}
public void cellHasBackgroundColor(final Location cell, Matcher backgroundColor) {
has(cellWith(cell, backgroundColor()), backgroundColor);
}
public void cellRenderedWithText(final Location cell, Matcher expectedText) {
has(cellWith(cell, labelText()), expectedText);
}
public static Query cellWith(Location cell, Query detail) {
return new RenderedCellQuery(cell, detail);
}
public static Query foregroundColor() {
return new Query() {
public Color query(Component component) { return component.getForeground(); }
public void describeTo(Description description) { description.appendText("foreground colour"); }
};
}
public static Query backgroundColor() {
return new Query() {
public Color query(Component component) { return component.getBackground(); }
public void describeTo(Description description) { description.appendText("background colour"); }
};
}
public static IdentifierCell cell(final int row, final Object columnIdentifier) {
return new IdentifierCell(row, columnIdentifier);
}
public static Cell cell(int row, int col) {
return new Cell(row, col);
}
public static Query labelText() {
return new Query() {
public String query(Component cell) {
return ((JLabel) cell).getText();
}
public void describeTo(Description description) {
description.appendText("text");
}
};
}
private class SelectedCellsMatcher extends TypeSafeMatcher {
public Cell unselectedCell;
private final Cell[] cells;
public SelectedCellsMatcher(Cell... cells) {
this.cells = cells;
}
@Override
public boolean matchesSafely(JTable table) {
for (Cell cell : cells) {
if (!table.isCellSelected(cell.row, cell.col)) {
this.unselectedCell = cell;
return false;
}
}
return true;
}
public void describeTo(Description description) {
description.appendText("cell " + unselectedCell + " is not selected");
}
}
private static final class RenderedCellMatcher extends TypeSafeMatcher {
private final Matcher extends JComponent> matcher;
RenderedCell foundCell;
RenderedCellMatcher(Matcher extends JComponent> matcher) {
this.matcher = matcher;
}
@Override public boolean matchesSafely(RenderedCell renderedCell) {
if (matcher.matches(renderedCell.rendered)) {
foundCell = renderedCell;
return true;
}
return false;
}
public void describeTo(Description description) {
description.appendDescriptionOf(matcher);
}
}
private static final class CellInTableMatcher extends TypeSafeMatcher {
private final Matcher matcher;
CellInTableMatcher(Matcher matcher) { this.matcher = matcher; }
@Override public boolean matchesSafely(JTable table) {
for (int row = 0; row < table.getRowCount(); row++) {
for (int col = 0; col < table.getColumnCount(); col++) {
Cell cell = cell(row, col);
if (matcher.matches(new RenderedCell(cell, JTableCellManipulation.render(table, cell)))) {
return true;
}
}
}
return false;
}
public void describeTo(Description description) {
description.appendText("with cell ")
.appendDescriptionOf(matcher);
}
}
private static final class RowInTableMatcher extends TypeSafeMatcher {
private final Matcher> matcher;
RowInTableMatcher(Matcher> matcher) { this.matcher = matcher; }
@Override public boolean matchesSafely(JTable table) {
for (int row = 0; row < table.getRowCount(); row++) {
if (matcher.matches(CellRowIterator.asIterable(table, row))) {
return true;
}
}
return false;
}
public void describeTo(Description description) {
description.appendText("with row ")
.appendDescriptionOf(matcher);
}
}
private static class CellRowIterator implements Iterator {
private final JTable table;
private final int row;
private final int width;
private int col = 0;
public CellRowIterator(JTable table, int row) {
this.table = table;
this.row = row;
this.width = table.getColumnCount();
}
public boolean hasNext() { return col < width; }
public Component next() { return render(table, cell(row, col++)); }
public void remove() { throw new Defect("Not implemented"); }
public static Iterable asIterable(final JTable table, final int row) {
return new Iterable() {
public Iterator iterator() { return new CellRowIterator(table, row); }
};
}
}
private static class JTableRowHeightManipulation implements ComponentManipulation {
private int rowHeight;
public void manipulate(JTable component) {
rowHeight = component.getRowHeight();
}
public int getRowHeight() {
return rowHeight;
}
}
private static class ColumnManipulation implements ComponentManipulation {
private int midpoint;
private final int col;
public ColumnManipulation(int col) {
this.col = col;
}
public void manipulate(JTable component) {
midpoint = JTableHeaderDriver.ColumnManipulation.midpointOfColumn(col, component.getColumnModel());
}
public int getMidPoint() {
return midpoint;
}
}
private static class RenderedCellQuery implements Query {
private final Location location;
private final Query detail;
public RenderedCellQuery(Location location, Query detail) {
this.location = location;
this.detail = detail;
}
public T query(JTable table) {
return detail.query(JTableCellManipulation.render(table, location));
}
public void describeTo(Description description) {
description.appendDescriptionOf(detail)
.appendText(" in cell at " + location);
}
}
}