/* * Created on 09.06.2006 * */ package org.jdesktop.swingx; import java.awt.Component; import java.awt.Dimension; import java.awt.GraphicsEnvironment; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JTable; import javax.swing.KeyStroke; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import org.jdesktop.swingx.table.TableColumnExt; import org.jdesktop.test.PropertyChangeReport; import org.jdesktop.test.TestUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class JXTableHeaderTest extends InteractiveTestCase { private static final Logger LOG = Logger.getLogger(JXTableHeaderTest.class .getName()); /** * the table used to instantiate a TableColumnModel used in the header. */ private JXTable table; /** * A header instantiated with the same TableColumnModel as the table. * NOTE: this is a standalone header, except for the model unrelated * to the table. */ private JXTableHeader header; @Test public void testSortsOnDoubleClick() { assertFalse(header.getResortsOnDoubleClick()); header.setResortsOnDoubleClick(true); assertEquals(header.getXTable() != null, header.getResortsOnDoubleClick()); header.setTable(table); assertEquals(header.getXTable() != null, header.getResortsOnDoubleClick()); } /** * Issue #1563-swingx: find cell that was clicked for componentPopup * * Test api and event firing. */ @Test public void testPopupTriggerLocationAvailable() { JXTableHeader table = (JXTableHeader) new JXTable(10, 3).getTableHeader(); MouseEvent event = new MouseEvent(table, 0, 0, 0, 40, 5, 0, false); PropertyChangeReport report = new PropertyChangeReport(table); table.getPopupLocation(event); assertEquals(event.getPoint(), table.getPopupTriggerLocation()); TestUtils.assertPropertyChangeEvent(report, "popupTriggerLocation", null, event.getPoint()); } /** * Issue #1563-swingx: find cell that was clicked for componentPopup * * Test safe return value. */ @Test public void testPopupTriggerCopy() { JXTableHeader table = (JXTableHeader) new JXTable(10, 3).getTableHeader(); MouseEvent event = new MouseEvent(table, 0, 0, 0, 40, 5, 0, false); table.getPopupLocation(event); assertNotSame("trigger point must not be same", table.getPopupTriggerLocation(), table.getPopupTriggerLocation()); } /** * Issue #1563-swingx: find cell that was clicked for componentPopup * * Test safe handle null. */ @Test public void testPopupTriggerKeyboard() { JXTableHeader table = (JXTableHeader) new JXTable(10, 3).getTableHeader(); MouseEvent event = new MouseEvent(table, 0, 0, 0, 40, 5, 0, false); table.getPopupLocation(event); PropertyChangeReport report = new PropertyChangeReport(table); table.getPopupLocation(null); assertNull("trigger must null", table.getPopupTriggerLocation()); TestUtils.assertPropertyChangeEvent(report, "popupTriggerLocation", event.getPoint(), null); } /** * Issue #1341-swingx: resizing/dragged/column/distance bound properties. */ @Test public void testNotifyResizingColumn() { assertNull(header.getResizingColumn()); PropertyChangeReport report = new PropertyChangeReport(header); TableColumn tableColumn = header.getColumnModel().getColumn(0); header.setResizingColumn(tableColumn); TestUtils.assertPropertyChangeEvent(report, "resizingColumn", null, tableColumn); } /** * Issue #1341-swingx: resizing/dragged/column/distance bound properties. */ @Test public void testNotifyDraggedDistance() { PropertyChangeReport report = new PropertyChangeReport(header); header.setDraggedDistance(10); TestUtils.assertPropertyChangeEvent(report, "draggedDistance", 0, 10); } /** * Issue #1341-swingx: resizing/dragged/column/distance bound properties. */ @Test public void testNotifyDraggedColumn() { assertNull(header.getDraggedColumn()); PropertyChangeReport report = new PropertyChangeReport(header); TableColumn tableColumn = header.getColumnModel().getColumn(0); header.setDraggedColumn(tableColumn); TestUtils.assertPropertyChangeEvent(report, "draggedColumn", null, tableColumn); } /** * Issue #1154-swingx: Regression after switching to Mustang. * was: Issue #31 (swingx): clicking header must not sort if table !enabled. * * Actually, an older debate - to disable or not to disable the header * if table disabled. Decided to synch header disabled (via listener in * JXTableHeader. This is consistent with ColumnControlButton. * */ @Test public void testEnabledSynched() { // test synch on propertyChange JXTable table = new JXTable(); table.setEnabled(false); assertEquals(table.isEnabled(), table.getTableHeader().isEnabled()); // test synch on setTable JXTableHeader header = new JXTableHeader(); header.setTable(table); assertEquals(table.isEnabled(), header.isEnabled()); // test true if table null header.setTable(null); assertEquals(true, header.isEnabled()); } /** * Issue #485-swingx: table header disappears if all header values are * empty. * * fixed for SwingX. * */ @Test public void testHeaderSizeEmptyStringHeaderValue() { final String[] alternate = { "", "", }; JXTable xTable = new JXTable(10, 2); xTable.getColumn(0).setHeaderValue(alternate[0]); xTable.getColumn(1).setHeaderValue(alternate[1]); assertTrue("header height must be > 0", xTable.getTableHeader().getPreferredSize().height > 0); } /** * Issue #485-swingx: table header disappears if all header values are * empty. * * fixed for Swingx. * */ @Test public void testHeaderSizeNullHeaderValue() { final String[] alternate = { null, null, }; JXTable xTable = new JXTable(10, 2); xTable.getColumn(0).setHeaderValue(alternate[0]); xTable.getColumn(1).setHeaderValue(alternate[1]); assertTrue("header height must be > 0", xTable.getTableHeader().getPreferredSize().height > 0); } /** * Issue #390-swingx: JXTableHeader: throws AIOOB on removing dragged column. * Test that getDraggedColumn is null if removed. * * Problem was reported on mac: * http://forums.java.net/jive/thread.jspa?threadID=18368&tstart=0 * when hiding column while drag(?) is in process. * * */ @Test public void testDraggedColumnRemoved() { JXTable table = new JXTable(10, 2); TableColumnExt columnExt = table.getColumnExt(0); table.getTableHeader().setDraggedColumn(columnExt); // sanity assert assertEquals(columnExt, table.getTableHeader().getDraggedColumn()); table.getColumnModel().removeColumn(columnExt); assertNull("draggedColumn must be null if removed", table.getTableHeader().getDraggedColumn()); } /** * Issue #390-swingx: JXTableHeader: throws AIOOB on removing dragged column. * Test that getDraggedColumn is visible or null. * * Problem was reported on mac: * http://forums.java.net/jive/thread.jspa?threadID=18368&tstart=0 * when hiding column while drag(?) is in process. */ @Test public void testDraggedColumnVisible() { JXTable table = new JXTable(10, 2); TableColumnExt columnExt = table.getColumnExt(0); table.getTableHeader().setDraggedColumn(columnExt); // sanity assert assertEquals(columnExt, table.getTableHeader().getDraggedColumn()); columnExt.setVisible(false); assertNull("dragged column must visible or null", table.getTableHeader().getDraggedColumn()); } /** * Issue 334-swingx: BasicTableHeaderUI.getPrefSize doesn't respect * all renderere's size requirements. * */ @Test public void testPreferredHeight() { JXTable table = new JXTable(10, 2); TableColumnExt columnExt = table.getColumnExt(1); columnExt.setTitle("<html><center>Line 1<br>Line 2</center></html>"); JXTableHeader tableHeader = (JXTableHeader) table.getTableHeader(); TableCellRenderer renderer = tableHeader.getCellRenderer(1); Component comp = renderer.getTableCellRendererComponent(table, columnExt.getHeaderValue(), false, false, -1, 1); Dimension prefRendererSize = comp.getPreferredSize(); assertEquals("Header pref height must respect renderer", prefRendererSize.height, tableHeader.getPreferredSize().height); } /** * test doc'ed xheader.getToolTipText(MouseEvent) behaviour. * */ @Test public void testColumnToolTip() { JXTable table = new JXTable(10, 2); TableColumnExt columnExt = table.getColumnExt(0); JXTableHeader tableHeader = (JXTableHeader) table.getTableHeader(); MouseEvent event = new MouseEvent(tableHeader, 0, 0, 0, 40, 5, 0, false); DefaultTableCellRenderer renderer = new DefaultTableCellRenderer(); String rendererToolTip = "rendererToolTip"; renderer.setToolTipText(rendererToolTip); columnExt.setHeaderRenderer(renderer); assertEquals(rendererToolTip, tableHeader.getToolTipText(event)); String columnToolTip = "columnToolTip"; columnExt.setToolTipText(columnToolTip); assertEquals(columnToolTip, tableHeader.getToolTipText(event)); } /** * Issue #1560-swingx: column tooltip not working for stand-alone header. */ @Test public void testColumnToolTipStandAlone() { JXTable table = new JXTable(10, 2); TableColumnExt columnExt = table.getColumnExt(0); JXTableHeader tableHeader = new JXTableHeader(table.getColumnModel()); MouseEvent event = new MouseEvent(tableHeader, 0, 0, 0, 40, 5, 0, false); String columnToolTip = "columnToolTip"; columnExt.setToolTipText(columnToolTip); assertEquals(columnToolTip, tableHeader.getToolTipText(event)); } /** * #212-swingx: second last column cannot be set to invisible programatically. * * One reason for the "trick" of reselecting the last is that * the header and with it the columnControl vanishes if there is * no visible column. * * * */ @Test public void testHeaderVisibleWithoutColumns() { // This test will not work in a headless configuration. if (GraphicsEnvironment.isHeadless()) { LOG.fine("cannot run headerVisible - headless environment"); return; } JXTable table = new JXTable(); table.setColumnControlVisible(true); wrapWithScrollingInFrame(table, ""); assertTrue("headerHeight must be > 0", table.getTableHeader().getHeight() > 0); assertEquals("headerWidth must be table width", table.getWidth(), table.getTableHeader().getWidth()); } /** * #212-swingx: second last column cannot be set to invisible programatically. * * One reason for the "trick" of reselecting the last is that * the header and with it the columnControl vanishes if there is * no visible column. * * * */ @Test public void testHeaderVisibleWithColumns() { // This test will not work in a headless configuration. if (GraphicsEnvironment.isHeadless()) { LOG.fine("cannot run headerVisible - headless environment"); return; } JXTable table = new JXTable(10, 2); table.setColumnControlVisible(true); wrapWithScrollingInFrame(table, ""); assertTrue("headerHeight must be > 0", table.getTableHeader().getHeight() > 0); table.setModel(new DefaultTableModel()); assertTrue("headerHeight must be > 0", table.getTableHeader().getHeight() > 0); } //--------------------------------- visual checks /** * Issue #485-swingx: table header disappears if all header values are * empty. Compare core <--> JXTable * fixed for SwingX. * */ public void interactiveHeaderSizeRequirements() { final String[] alternate = { null, null, }; final JTable table = new JTable(10, 2); table.getColumnModel().getColumn(0).setHeaderValue(alternate[0]); table.getColumnModel().getColumn(1).setHeaderValue(alternate[1]); JXTable xTable = new JXTable(10, 2); xTable.getColumn(0).setHeaderValue(alternate[0]); xTable.getColumn(1).setHeaderValue(alternate[1]); JXFrame frame = wrapWithScrollingInFrame(table, xTable, "header height empty (core - xtable)"); frame.setVisible(true); } /** * Issue #390-swingx: JXTableHeader: throws AIOOB on removing dragged column. * */ public void interactiveDraggedColumnRemoved() { final JXTable table = new JXTable(10, 5); Action deleteColumn = new AbstractAction("deleteCurrentColumn") { public void actionPerformed(ActionEvent e) { TableColumn column = table.getTableHeader().getDraggedColumn(); if (column == null) return; table.getColumnModel().removeColumn(column); } }; KeyStroke keyStroke = KeyStroke.getKeyStroke("F1"); table.getInputMap(JTable.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, "f1"); table.getActionMap().put("f1", deleteColumn); JXFrame frame = wrapWithScrollingInFrame(table, "Remove dragged column with F1"); frame.setVisible(true); } /** * Visual demo that header is always visible. */ public void interactiveHeaderVisible() { final JXTable table = new JXTable(); table.setColumnControlVisible(true); JXFrame frame = wrapWithScrollingInFrame(table, "header always visible"); Action action = new AbstractAction("toggle model") { public void actionPerformed(ActionEvent e) { int columnCount = table.getColumnCount(true); table.setModel(columnCount > 0 ? new DefaultTableModel() : new DefaultTableModel(10, 2)); } }; addAction(frame, action); frame.setVisible(true); } public static void main(String args[]) { JXTableHeaderTest test = new JXTableHeaderTest(); try { test.runInteractiveTests(); // test.runInteractiveTests("interactive.*Siz.*"); } catch (Exception e) { System.err.println("exception when executing interactive tests:"); e.printStackTrace(); } } @Override @Before public void setUp() { table = new JXTable(10, 5); header = new JXTableHeader(table.getColumnModel()); } @After public void tearDownJ4() throws Exception { tearDown(); } }