/*
* Created on 02.06.2006
*
*/
package org.jdesktop.swingx.table;
import java.awt.Component;
import javax.swing.BorderFactory;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import org.jdesktop.swingx.InteractiveTestCase;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.decorator.BorderHighlighter;
import org.jdesktop.swingx.decorator.Highlighter;
import org.jdesktop.test.AncientSwingTeam;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* Contains unit tests for <code>ColumnFactory</code>.
*
* @author Jeanette Winzenburg
*/
@RunWith(JUnit4.class)
public class ColumnFactoryTest extends InteractiveTestCase {
/**
* Issue #1215-swingx: ColumnFactory must pack with prepareRenderer.
* Otherwise, doesn't catch sizing effective highlighters, like f.i. font.
*/
@Test
public void testPackWithPrepareRenderer() {
JXTable table = new JXTable(1, 1);
table.setValueAt("just a long string something utterly meaningless", 0, 0);
table.packColumn(0, 0);
assertEquals("sanity: no highlighter", table.prepareRenderer(
table.getCellRenderer(0, 0), 0, 0).getPreferredSize().width,
table.getColumn(0).getPreferredWidth());
Highlighter hl = new BorderHighlighter(BorderFactory.createEmptyBorder(0, 50, 0, 50));
table.addHighlighter(hl);
table.packColumn(0, 0);
assertEquals("highlighter which adds 100 px width", table.prepareRenderer(
table.getCellRenderer(0, 0), 0, 0).getPreferredSize().width,
table.getColumn(0).getPreferredWidth());
}
/**
* Issue #564-swingx: allow custom factories to return null column.
* Here: test that table can cope with null columns on create.
*/
@Test
public void testTableCopeWithCreateNullColumn() {
// factory returns null on create
ColumnFactory factory = new ColumnFactory() {
@Override
public TableColumnExt createTableColumn(int modelIndex) {
return modelIndex > 0 ? super.createTableColumn(modelIndex) : null;
}
};
JXTable table = new JXTable();
table.setColumnFactory(factory);
TableModel model = new DefaultTableModel(0, 10);
table.setModel(model);
assertEquals("factory must have created one less than model columns",
model.getColumnCount() - 1, table.getColumnCount());
}
/**
* Issue #564-swingx: allow custom factories to return null column.
* Here: test that ColumnFactory can handle null creation.
*/
@Test
public void testCreateNullColumn() {
// factory returns null on create
ColumnFactory factory = new ColumnFactory() {
@Override
public TableColumnExt createTableColumn(int modelIndex) {
return null;
}
};
TableModel model = new DefaultTableModel(0, 10);
factory.createAndConfigureTableColumn(model, 0);
}
/**
* Issue #564-swingx: allow custom factories to return null column.
* Here: check how to implement model-based decision.
*
* PENDING: need additional api? Left to subclasses for now.
*/
@Test
public void testCreateNullColumnFromModelProperty() {
// factory returns null on create
ColumnFactory factory = new ColumnFactory() {
@Override
public TableColumnExt createAndConfigureTableColumn(
TableModel model, int modelIndex) {
if ("A".equals(model.getColumnName(modelIndex))) return null;
return super.createAndConfigureTableColumn(model, modelIndex);
}
};
TableModel model = new DefaultTableModel(0, 10);
TableColumnExt column = factory.createAndConfigureTableColumn(model, 0);
assertNull("", column);
}
/**
* Issue ??: NPE in pack for null table header.
*
*/
@Test
public void testPackColumnNullHeader() {
JXTable table = new JXTable(new AncientSwingTeam());
table.setTableHeader(null);
table.packAll();
}
/**
* test if max parameter is respected.
*
*/
@Test
public void testPackColumnWithMax() {
JXTable table = new JXTable(new AncientSwingTeam());
TableColumnExt columnExt = table.getColumnExt(0);
table.getColumnFactory().packColumn(table, columnExt, -1, -1);
int prefWidth = columnExt.getPreferredWidth();
assertTrue("sanity: ", prefWidth > 10);
int max = prefWidth - 5;
table.getColumnFactory().packColumn(table, columnExt, -1, max);
assertEquals("pref width must be bounded by max",
max, columnExt.getPreferredWidth());
}
/**
* packColumn can't handle hidden columns.
*
*/
@Test
public void testPackHiddenColumn() {
JXTable table = new JXTable(10, 4);
TableColumnExt columnExt = table.getColumnExt(0);
columnExt.setVisible(false);
try {
table.getColumnFactory().packColumn(table, columnExt, -1, -1);
fail("packColumn is doc'ed to not handle hidden columns");
} catch (IllegalStateException e) {
// expected
}
}
/**
* test that configure throws exceptions as doc'ed.
* Here: model index == negative
*
*/
@Test
public void testConfigureTableColumnDoc() {
TableModel model = new DefaultTableModel(0, 4);
TableColumnExt columnExt = new TableColumnExt(-1);
try {
ColumnFactory.getInstance().configureTableColumn(model, columnExt);
fail("factory must throw on illegal column model index " + columnExt.getModelIndex());
} catch (IllegalStateException e) {
// nothing to do - that's the doc'ed behaviour
}
}
/**
* test that configure throws exceptions as doc'ed.
* Here: model index == getColumnCount
*
*/
@Test
public void testConfigureTableColumnExcessModelIndex() {
TableModel model = new DefaultTableModel(0, 4);
TableColumnExt columnExt = new TableColumnExt(model.getColumnCount());
try {
ColumnFactory.getInstance().configureTableColumn(model, columnExt);
fail("factory must throw on illegal column model index " + columnExt.getModelIndex());
} catch (IllegalStateException e) {
// nothing to do - that's the doc'ed behaviour
}
}
/**
* For completeness: formally test that app-wide factory
* is used by JXTable.
*
*/
@Test
public void testSetColumnFactory() {
ColumnFactory myFactory = new ColumnFactory();
ColumnFactory.setInstance(myFactory);
JXTable table = new JXTable();
assertSame(myFactory, table.getColumnFactory());
}
/**
* Issue #470-swingx: added getRowCount(table)
*
*/
@Test
public void testEncapsulateRowCount() {
final int cutOffRowCount = 10;
ColumnFactory factory = new ColumnFactory() {
@Override
protected int getRowCount(JXTable table) {
return cutOffRowCount;
}
};
DefaultTableModel model = new DefaultTableModel(cutOffRowCount * 2, 2) {
@Override
public Object getValueAt(int row, int column) {
if (row >= cutOffRowCount) {
throw new IllegalArgumentException("Illegal access to cutoff rows");
}
return super.getValueAt(row, column);
}
};
JXTable table = new JXTable();
table.setColumnFactory(factory);
table.setModel(model);
factory.packColumn(table, table.getColumnExt(0), -1, -1);
}
/**
* Issue #315-swingx: pack doesn't pass column index to headerRenderer.
* This bug shows only if the renderer relies on the column index (default doesn't).
*/
@Test
public void testPackColumnIndexToHeaderRenderer() {
final int special = 1;
TableCellRenderer renderer = new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (column == special) {
value = "exxxxttteeeed" + value;
}
super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
row, column);
return this;
}
};
JXTable table = new JXTable(1, 2);
table.getTableHeader().setDefaultRenderer(renderer);
TableColumnExt columnExt = table.getColumnExt(special);
table.packAll();
int realPrefWidth = 2 * 4 // magic value - JXTable's default margin,
// needs to be made configurable, see Issue ??
+ renderer.getTableCellRendererComponent(table,
columnExt.getHeaderValue(), false, false, -1, special).getPreferredSize().width;
assertEquals(realPrefWidth, columnExt.getPreferredWidth());
}
/**
* Issue #266-swingx: support customization of pack margin.
*
* added property to ColumnFactory.
*
*/
@Test
public void testPackMargin() {
final int special = 1;
JXTable table = new JXTable(1, 2);
ColumnFactory factory = new ColumnFactory();
table.setColumnFactory(factory);
table.setValueAt("something that's wider than 75", 0, special);
TableColumnExt columnExt = table.getColumnExt(special);
table.packAll();
TableCellRenderer renderer = table.getCellRenderer(0, special);
Component comp = table.prepareRenderer(renderer, 0, special);
int realPrefWidth = 2 * factory.getDefaultPackMargin() // magic value - JXTable's default margin,
// needs to be made configurable, see Issue 266
+ comp.getPreferredSize().width;
// sanity - default margin kicks in
assertEquals(realPrefWidth, columnExt.getPreferredWidth());
int margin = 10;
factory.setDefaultPackMargin(margin);
table.packAll();
table.prepareRenderer(renderer, 0, special);
int otherPrefWidth = 2 * margin + comp.getPreferredSize().width;
assertEquals(otherPrefWidth, columnExt.getPreferredWidth());
}
}