/*
* Created on 09.06.2006
*
*/
package org.jdesktop.swingx;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.border.Border;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import org.jdesktop.swingx.decorator.BorderHighlighter;
import org.jdesktop.swingx.renderer.DefaultTableRenderer;
import org.jdesktop.swingx.table.TableColumnExt;
import org.jdesktop.test.AncientSwingTeam;
/**
* Interactive "test" methods for <code>JXTableHeader</code>.
*
* @author Jeanette Winzenburg
*/
public class JXTableHeaderVisualCheck extends InteractiveTestCase {
@SuppressWarnings("unused")
private static final Logger LOG = Logger
.getLogger(JXTableHeaderVisualCheck.class.getName());
public static void main(String args[]) {
JXTableHeaderVisualCheck test = new JXTableHeaderVisualCheck();
try {
// test.runInteractiveTests();
// test.runInteractiveTests("interactive.*DoubleSort.*");
// test.runInteractive("ColumnToolTip");
test.runInteractive("PopupTrigger");
} catch (Exception e) {
System.err.println("exception when executing interactive tests:");
e.printStackTrace();
}
}
/**
* Issue #1563-swingx: find cell that was clicked for componentPopup
*
* Example of how to use:
* - in actionPerformed
* - in popupMenuWillBecomeVisible
*/
public void interactivePopupTriggerLocation() {
JXTable table = new JXTable(new AncientSwingTeam());
table.setColumnSelectionAllowed(true);
JXTableHeader header = (JXTableHeader) table.getTableHeader();
JPopupMenu popup = new JPopupMenu();
Action action = new AbstractAction("cell found in actionPerformed") {
@Override
public void actionPerformed(ActionEvent e) {
JXTableHeader table = SwingXUtilities.getAncestor(JXTableHeader.class, (Component) e.getSource());
Point trigger = table.getPopupTriggerLocation();
Point cell = null;
if (trigger != null) {
int column = table.columnAtPoint(trigger);
table.getColumnModel().getSelectionModel().setSelectionInterval(column, column);
cell = new Point(column, -1);
} else {
table.getColumnModel().getSelectionModel().clearSelection();
}
LOG.info("popupTrigger/cell " + trigger + "/" + cell);
}
};
popup.add(action);
final Action onShowing = new AbstractAction("dynamic: ") {
@Override
public void actionPerformed(ActionEvent e) {
LOG.info("" + getValue(NAME));
}
};
popup.add(onShowing);
PopupMenuListener l = new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
// doesn't work: popup itself cannot be used as
// starting component, bug?
// JXTable table = SwingXUtilities.getAncestor(JXTable.class,
// (Component) e.getSource());
JXTableHeader table = (JXTableHeader) ((JPopupMenu) e.getSource()).getInvoker();
Point trigger = table.getPopupTriggerLocation();
Point cell = null;
if (trigger != null) {
int column = table.columnAtPoint(trigger);
// here we set the cell focus, just to do a bit differently
// from the other action
// table.setColumnSelectionInterval(column, column);
// table.clearSelection();
cell = new Point(column, -1);
}
onShowing.putValue(Action.NAME, "popupTrigger/cell " + trigger + "/" + cell);
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
}
};
popup.addPopupMenuListener(l);
header.setComponentPopupMenu(popup);
showWithScrollingInFrame(table, "PopupTriggerLocation");
}
/**
* Issue 1560-swingx: column tooltip not working in stand-alone header
*
*/
public void interactiveColumnToolTip() {
JXTable table = new JXTable(new AncientSwingTeam());
for (TableColumn column : table.getColumns()) {
((TableColumnExt) column).setToolTipText("tip: "
+ column.getHeaderValue());
}
JXTableHeader header = new JXTableHeader(table.getColumnModel());
JXFrame frame = wrapWithScrollingInFrame(table, "columnToolTip");
frame.add(header, BorderLayout.NORTH);
show(frame);
}
/**
* Issue 1558-swingx: support custom column tooltip mechanism
*
* The use-case is a dynamic, tableModel-backed tooltip:
* needs subclassing of header which should not need duplication
* of column look-up
*/
public void interactiveColumnToolTipCustom() {
JXTable table = new JXTable(new ModelWithToolTip());
JXTableHeader header = new JXTableHeader(table.getColumnModel()) {
@Override
protected String getColumnToolTipText(TableColumnExt column) {
TableModel model = getTable().getModel();
if (model instanceof ModelWithToolTip) {
return ((ModelWithToolTip) model).getColumnToolTip(column.getModelIndex());
}
return model.getColumnName(column.getModelIndex());
}
};
DefaultTableCellRenderer r = new DefaultTableCellRenderer() {
Border padding = BorderFactory.createEmptyBorder(0, 10, 0, 10);
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
row, column);
setBorder(BorderFactory.createCompoundBorder(getBorder(), padding));
return this;
}
};
table.setDefaultRenderer(Object.class, r);
DefaultTableRenderer renderer = (DefaultTableRenderer) table.getDefaultRenderer(Number.class);
renderer.getComponentProvider().getRendererComponent(null).setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));
BorderHighlighter hl = new BorderHighlighter(BorderFactory.createEmptyBorder(0, 10, 0, 10));
hl.setInner(true);
table.addHighlighter(hl);
table.setTableHeader(header);
JXFrame frame = wrapWithScrollingInFrame(table, "custom columnToolTip");
show(frame);
}
/**
* Issue #1558-swing: model-based column tooltip
*/
public static class ModelWithToolTip extends AncientSwingTeam {
public String getColumnToolTip(int column) {
return "model-tip: " + getColumnName(column);
}
}
/**
* Issue #271-swingx: optionally support double sort on double click.
*
*/
public void interactiveDoubleSort() {
JXTable table = new JXTable(30, 5);
showWithScrollingInFrame(table, "support double sort on double click");
}
/**
* Issue #1225-swingx: JXTableHeader throws on rowSorters which are not
* of type SortController when resizing columns with mouse.
*/
public void interactiveHeaderCoreRowSorter() {
JXTable table = new JXTable(30, 5);
table.setAutoCreateRowSorter(false);
table.setRowSorter(new TableRowSorter<TableModel>(table.getModel()));
showWithScrollingInFrame(table, "core resize columns with mouse");
}
/**
* Issue #683-swingx: Autoscroll if column dragged outside.
*
*/
public void interactiveHeaderAutoScrollRToL() {
JXTable table = new JXTable(20, 30);
table.setColumnControlVisible(true);
table.setVisibleColumnCount(6);
assertTrue(table.getAutoscrolls());
table.getTableHeader().setAutoscrolls(true);
assertTrue(table.getTableHeader().getAutoscrolls());
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JXFrame frame = showWithScrollingInFrame(table, "autoScroll column drag - RToL");
frame.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
}
/**
* Issue #683-swingx: Autoscroll if column dragged outside.
*
*/
public void interactiveHeaderAutoScroll() {
JXTable table = new JXTable(20, 30);
table.setColumnControlVisible(true);
table.setVisibleColumnCount(6);
assertTrue(table.getAutoscrolls());
table.getTableHeader().setAutoscrolls(true);
assertTrue(table.getTableHeader().getAutoscrolls());
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JXFrame frame = showWithScrollingInFrame(table, "autoScroll column drag - LToR");
frame.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
}
/**
* Issue #683-swingx: Autoscroll if column dragged outside.
* Plain ol' JTable - core bug 6503981
*/
public void interactiveHeaderAutoScrollCoreIssue() {
JTable table = new JXTable(20, 30);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JXFrame frame = showWithScrollingInFrame(table, "core bug 1.6 before u4 - scroll to last column and drag");
frame.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
frame.setSize(400, 400);
}
/**
* 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") {
@Override
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") {
@Override
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);
}
/**
* do nothing test - keep the testrunner happy.
*/
public void testDummy() {
}
}