package org.robotframework.swing.table;
import java.awt.Component;
import javax.swing.AbstractButton;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
import org.jretrofit.AllMethodsNotImplementedException;
import org.jretrofit.Retrofit;
import org.netbeans.jemmy.operators.JTableOperator;
import org.robotframework.swing.chooser.WithText;
import org.robotframework.swing.common.SmoothInvoker;
public class CellValueExtractor {
public enum TextSource {AUTO, MODEL}
private JTableOperator jTableOperator;
public CellValueExtractor(JTableOperator jTableOperator) {
this.jTableOperator = jTableOperator;
}
public String textOf(int row, int col, TextSource source) {
if (source == TextSource.MODEL)
return getTextFromTableModel(row, col);
else
return getTextWithDefaultStrategy(row, col);
}
public String textOf(int row, int col) {
return textOf(row, col, TextSource.AUTO);
}
public String getTextWithDefaultStrategy(int row, int col) {
try {
return getTextFromCellComponent(row, col);
} catch (AllMethodsNotImplementedException e) {
return getTextFromTableModel(row, col);
}
}
private String getTextFromTableModel(int row, int col) {
return wrapElementToWithText(row, col).getText();
}
private String getTextFromCellComponent(int row, int col) {
Component cellRendererComponent = getCellRendererComponent(row, col);
if (isButtonBasedRenderer(cellRendererComponent))
return new Boolean(((AbstractButton) cellRendererComponent).isSelected()).toString();
return coerceToWithText(cellRendererComponent).getText();
}
public Component getCellRendererComponent(int row, int column) {
TableCellRenderer renderer = jTableOperator.getCellRenderer(row, column);
JTable table = (JTable) jTableOperator.getSource();
Object value = jTableOperator.getValueAt(row, column);
boolean isSelected = jTableOperator.isCellSelected(row, column);
boolean hasFocus = jTableOperator.hasFocus();
return getTableCellRendererComponentSmoothly(row, column, renderer, table, value, isSelected, hasFocus);
}
private boolean isButtonBasedRenderer(Component cellRendererComponent) {
TableCellRenderer defaultCheckboxRenderer = ((JTable) jTableOperator.getSource()).getDefaultRenderer(Boolean.class);
return (defaultCheckboxRenderer.getClass().isInstance(cellRendererComponent) &&
cellRendererComponent instanceof AbstractButton);
}
private WithText coerceToWithText(Object element) {
return (WithText) Retrofit.complete(element, WithText.class);
}
private WithText wrapElementToWithText(final int rowIndex, final int columnIndex) {
return new WithText() {
public String getText() {
return jTableOperator.getModel()
.getValueAt(rowIndex, columnIndex)
.toString();
}
};
}
private Component getTableCellRendererComponentSmoothly(final int row, final int column, final TableCellRenderer renderer,
final JTable table, final Object value, final boolean isSelected, final boolean hasFocus) {
return new SmoothInvoker<Component>() {
public Object work() {
return renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}.invoke();
}
}