/* * $Id$ * * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, * Santa Clara, California 95054, U.S.A. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ package org.jdesktop.swingx.renderer; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.Font; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.geom.Point2D; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; import java.util.regex.Pattern; import javax.swing.AbstractAction; import javax.swing.AbstractListModel; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.ListModel; import javax.swing.ToolTipManager; import javax.swing.UIManager; import javax.swing.border.MatteBorder; import javax.swing.table.TableModel; import org.jdesktop.swingx.InteractiveTestCase; import org.jdesktop.swingx.JXFrame; import org.jdesktop.swingx.JXList; import org.jdesktop.swingx.JXSearchPanel; import org.jdesktop.swingx.JXTable; import org.jdesktop.swingx.JXTree; import org.jdesktop.swingx.JXTreeTable; import org.jdesktop.swingx.decorator.AbstractHighlighter; import org.jdesktop.swingx.decorator.BorderHighlighter; import org.jdesktop.swingx.decorator.ColorHighlighter; import org.jdesktop.swingx.decorator.ComponentAdapter; import org.jdesktop.swingx.decorator.CompoundHighlighter; import org.jdesktop.swingx.decorator.HighlightPredicate; import org.jdesktop.swingx.decorator.Highlighter; import org.jdesktop.swingx.decorator.HighlighterFactory; import org.jdesktop.swingx.decorator.PatternPredicate; import org.jdesktop.swingx.decorator.ShadingColorHighlighter; import org.jdesktop.swingx.decorator.HighlightPredicate.ColumnHighlightPredicate; import org.jdesktop.swingx.painter.MattePainter; import org.jdesktop.swingx.painter.AbstractLayoutPainter.HorizontalAlignment; import org.jdesktop.swingx.renderer.RelativePainterHighlighter.NumberRelativizer; import org.jdesktop.swingx.rollover.RolloverProducer; import org.jdesktop.swingx.search.PatternMatcher; import org.jdesktop.swingx.treetable.FileSystemModel; import org.jdesktop.swingx.util.PaintUtils; import org.jdesktop.test.AncientSwingTeam; /** * visual checks of highlighter clients. Mostly by example of JXTable. * * @author Jeanette Winzenburg */ public class HighlighterClientVisualCheck extends InteractiveTestCase { @SuppressWarnings("unused") private static final Logger LOG = Logger .getLogger(HighlighterClientVisualCheck.class.getName()); protected TableModel tableModel; protected Color background = Color.RED; protected Color foreground = Color.BLUE; public static void main(String args[]) { // UIManager.put("Nimbus.keepAlternateRowColor", Boolean.TRUE); // setSystemLF(true); HighlighterClientVisualCheck test = new HighlighterClientVisualCheck(); try { // setLookAndFeel("Nimbus"); test.runInteractiveTests(); // test.runInteractive("JP"); // test.runInteractiveTests(".*Striping.*"); // test.runInteractiveTests(".*ToolTip.*"); // test.runInteractiveTests("interactive.*Search.*"); // test.runInteractiveTests("interactive.*BorderHighlighter.*"); } catch (Exception e) { System.err.println("exception when executing interactive tests:"); e.printStackTrace(); } } /** * Issue #1295-swingx: JXTable rolloverController repaint incomplete. * Column not repainted. */ public void interactiveBorderHighlighterOnRollover() { JXTable table = new JXTable(tableModel) { int count; @Override protected void paintComponent(Graphics g) { // crude check if the logic of column/row painting // in TableRolloverController is working (looks so) // LOG.info("paint clip: " + count++ + g.getClip()); super.paintComponent(g); } }; final AbstractHighlighter hlRow = new BorderHighlighter(HighlightPredicate.ROLLOVER_ROW, // BorderFactory.createCompoundBorder( new MatteBorder(1, 0, 1, 0, Color.lightGray) // , BorderFactory.createEmptyBorder(0, 1, 0, 1)) , true, false ); final AbstractHighlighter hlColumn = new ColorHighlighter(HighlightPredicate.ROLLOVER_COLUMN, Color.LIGHT_GRAY, null); table.setHighlighters(hlRow, hlColumn); JXFrame frame = wrapWithScrollingInFrame(table, "borderHighlgihter on rollover"); Action toggleCell = new AbstractAction("toggle cell-rollover") { @Override public void actionPerformed(ActionEvent e) { if (hlRow.getHighlightPredicate() == HighlightPredicate.ROLLOVER_ROW) { hlRow.setHighlightPredicate(HighlightPredicate.NEVER); hlColumn.setHighlightPredicate(HighlightPredicate.ROLLOVER_CELL); } else { hlRow.setHighlightPredicate(HighlightPredicate.ROLLOVER_ROW); hlColumn.setHighlightPredicate(HighlightPredicate.ROLLOVER_COLUMN); } } }; addAction(frame, toggleCell); show(frame); } /** * Show variants of border Highlighters. * */ public void interactiveTableBorderHighlighter() { JXTable table = new JXTable(tableModel); table.setVisibleRowCount(table.getRowCount()); table.setVisibleColumnCount(7); table.packAll(); table.setColumnControlVisible(true); BorderHighlighter outer = new BorderHighlighter(new HighlightPredicate.ColumnHighlightPredicate(1), BorderFactory.createLineBorder(Color.RED, 3)); BorderHighlighter inner = new BorderHighlighter(new HighlightPredicate.ColumnHighlightPredicate(2), BorderFactory.createLineBorder(Color.RED, 3), true, true); BorderHighlighter replace = new BorderHighlighter(new HighlightPredicate.ColumnHighlightPredicate(0), BorderFactory.createLineBorder(Color.RED, 3), false, true); table.setHighlighters(outer, inner, replace); showWithScrollingInFrame(table, "Border Highlighters"); } /** * Show variants of border Highlighters. * */ public void interactiveTreeBorderHighlighter() { JXTree tree = new JXTree(); tree.expandAll(); tree.setVisibleRowCount(tree.getRowCount()); // need SwingX highlighter tree.setCellRenderer(new DefaultTreeRenderer()); tree.setHighlighters(new BorderHighlighter(BorderFactory.createLineBorder(Color.GREEN, 1))); showWithScrollingInFrame(tree, "Border Highlighters"); } /** * Multiple Highlighters (shown as example in Javapolis 2007). * */ public void interactiveTablePatternHighlighterJP() { JXTable table = new JXTable(tableModel); table.setVisibleRowCount(table.getRowCount()); table.setVisibleColumnCount(7); table.packAll(); table.setColumnControlVisible(true); Font font = table.getFont().deriveFont(Font.BOLD | Font.ITALIC); Highlighter simpleStriping = HighlighterFactory.createSimpleStriping(); PatternPredicate patternPredicate = new PatternPredicate("^M", 1); ColorHighlighter magenta = new ColorHighlighter(patternPredicate, null, Color.MAGENTA, null, Color.MAGENTA); FontHighlighter derivedFont = new FontHighlighter(patternPredicate, font); AbstractHighlighter gradient = createRelativeGradientHighlighter(HorizontalAlignment.LEFT, AncientSwingTeam.INTEGER_COLUMN); gradient.setHighlightPredicate(new HighlightPredicate.ColumnHighlightPredicate(AncientSwingTeam.INTEGER_COLUMN)); LOG.info("" + (table.getValueAt(0, 3) instanceof Number)); Highlighter shading = new ShadingColorHighlighter( new HighlightPredicate.ColumnHighlightPredicate(1)); table.setHighlighters(simpleStriping, magenta, derivedFont, shading //); , gradient); showWithScrollingInFrame(table, "Multiple Highlighters"); } /** * Simulates table by one-list per column. * * NOTE: the only purpose is to demonstrate the similarity * of highlighter usage across collection components! * (shown as example in Javapolis 2007) * * @see #interactiveTablePatternHighlighterJP() */ public void interactiveListPatternHighlighterJP() { JXTable source = new JXTable(tableModel); source.toggleSortOrder(3); Font font = source.getFont().deriveFont(Font.BOLD | Font.ITALIC); Highlighter simpleStriping = HighlighterFactory.createSimpleStriping(); String pattern = "^M"; PatternPredicate patternPredicate = new PatternPredicate(pattern, 0); ColorHighlighter magenta = new ColorHighlighter(patternPredicate, null, Color.MAGENTA, null, Color.MAGENTA); FontHighlighter derivedFont = new FontHighlighter(patternPredicate, font); Highlighter gradient = createRelativeGradientHighlighter( HorizontalAlignment.LEFT, 0); Highlighter shading = new ShadingColorHighlighter( new HighlightPredicate.ColumnHighlightPredicate(0)); // create and configure one JXList per column. List<JXList> lists = new ArrayList<JXList>(); // first name JXList list0 = new JXList(createListModel(source, 0)); list0.setHighlighters(simpleStriping); lists.add(list0); // last name JXList list1 = new JXList(createListModel(source, 1)); list1.setHighlighters(simpleStriping, magenta, derivedFont, shading); lists.add(list1); // color JXList listc = new JXList(createListModel(source, 2)); listc.setHighlighters(simpleStriping); lists.add(listc); // number JXList listn = new JXList(createListModel(source, AncientSwingTeam.INTEGER_COLUMN)); listn.setCellRenderer(new DefaultListRenderer( StringValues.NUMBER_TO_STRING, JLabel.RIGHT)); listn.setHighlighters(simpleStriping, gradient); lists.add(listn); // boolean JXList listb = new JXList(createListModel(source, 4)); listb.setCellRenderer(new DefaultListRenderer(new CheckBoxProvider())); listb.setFixedCellHeight(list0.getPreferredSize().height / source.getRowCount()); listb.setHighlighters(simpleStriping, magenta, derivedFont, gradient); lists.add(listb); JComponent panel = Box.createHorizontalBox(); for (JXList l : lists) { listb.setVisibleRowCount(source.getRowCount()); l.setFont(source.getFont()); panel.add(new JScrollPane(l)); } showInFrame(panel, "Multiple Highlighters"); } /** * @param right * @return */ private RelativePainterHighlighter createRelativeGradientHighlighter( HorizontalAlignment right, int column) { Color startColor = PaintUtils.setAlpha(Color.RED, 130); Color endColor = PaintUtils.setAlpha(Color.RED.brighter(), 0); boolean isRightAligned = HorizontalAlignment.RIGHT == right; GradientPaint paint = new GradientPaint(new Point2D.Double(0, 0), isRightAligned ? endColor : startColor, new Point2D.Double(100, 0), isRightAligned ? startColor : endColor); MattePainter painter = new MattePainter(paint); painter.setPaintStretched(true); RelativePainterHighlighter p = new RelativePainterHighlighter(painter); p.setHorizontalAlignment(right); p.setRelativizer(new NumberRelativizer(column, 100, 100)); return p; } /** * @param tableModel2 * @param i * @return */ private ListModel createListModel(final JXTable tableModel, final int i) { ListModel listModel = new AbstractListModel(){ @Override public Object getElementAt(int index) { return tableModel.getValueAt(index, i); } @Override public int getSize() { return tableModel.getRowCount(); }}; return listModel ; } public static class FontHighlighter extends AbstractHighlighter { private Font font; public FontHighlighter(HighlightPredicate predicate, Font font) { super(predicate); this.font = font; } @Override protected Component doHighlight(Component component, ComponentAdapter adapter) { component.setFont(font); return component; } } /** * Example from forum requirement: highlight all rows of a given group * if mouse if over one of them. * * PENDING: need to track row view-model coordinates mapping after * filtering/sorting. * */ public void interactiveRolloverRowGroup() { TableModel model = new AncientSwingTeam(); final List<Integer> rowSet = new ArrayList<Integer>(); for (int i = 0; i < model.getRowCount(); i++) { if ((Integer)model.getValueAt(i, 3) > 10) { rowSet.add(i); } } final HighlightPredicate predicate = new HighlightPredicate() { @Override public boolean isHighlighted(Component renderer, ComponentAdapter adapter) { return rowSet.contains(adapter.row); } }; final ColorHighlighter highlighter = new ColorHighlighter(HighlightPredicate.NEVER, Color.YELLOW, null); JXTable table = new JXTable(model); table.addHighlighter(highlighter); PropertyChangeListener l = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { Point location = (Point) evt.getNewValue(); int row = -1; if (location != null) { row = location.y; } if (rowSet.contains(row)) { highlighter.setHighlightPredicate(predicate); } else { highlighter.setHighlightPredicate(HighlightPredicate.NEVER); } } }; table.addPropertyChangeListener(RolloverProducer.ROLLOVER_KEY, l); showWithScrollingInFrame(table, "rollover highlight of row groups"); } /** * Example to highlight against a value/color map. * Here the control is in predicate. <p> * */ public void interactiveColorValueMappedHighlighterPredicate() { JXTable table = new JXTable(new AncientSwingTeam()); // build a quick color lookup to simulate multi-value value-based // coloring final int numberColumn = 3; table.toggleSortOrder(numberColumn); Color[] colors = new Color[] { Color.YELLOW, Color.CYAN, Color.MAGENTA, Color.GREEN }; int rowsPerColor = (table.getRowCount() - 5) / colors.length; Map<Color, HighlightPredicate> map = new HashMap<Color, HighlightPredicate>(); for (int i = 0; i < colors.length; i++) { List<Integer> values = new ArrayList<Integer>(); for (int j = 0; j < rowsPerColor; j++) { values.add((Integer) table.getValueAt(i * rowsPerColor + j, numberColumn)); } map.put(colors[i], new ValueMappedHighlightPredicate(values, numberColumn)); } // create one ColorHighlighter for each color/predicate pair and // add to a compoundHighlighter CompoundHighlighter chl = new CompoundHighlighter(); for (Color color : colors) { chl.addHighlighter(new ColorHighlighter(map.get(color), color, null)); } table.resetSortOrder(); table.addHighlighter(chl); showWithScrollingInFrame(table, "compound highlighter with value-based color mapping predicate"); } /** * Custom predicate which returns true if the filtered cell value * of a given testColumn is contained in a list of values. * PENDING: logic similar to search/pattern, enough to abstract? */ public static class ValueMappedHighlightPredicate implements HighlightPredicate { private List<?> values; private int testColumn; public ValueMappedHighlightPredicate(List<?> values, int testColumn) { this.values = values; this.testColumn = testColumn; } @Override public boolean isHighlighted(Component renderer, ComponentAdapter adapter) { return values.contains(adapter.getValue(testColumn)); } } /** * Example to highlight against a value/color map. <p> * Here the Highlighter takes full control. Which is a bit * on the border line of * the intended distribution of responsibility between * Highlighter and HighlighterPredicate. */ public void interactiveColorValueMappedHighlighter() { JXTable table = new JXTable(new AncientSwingTeam()); // build a quick color lookup to simulate multi-value value-based // coloring final int numberColumn = 3; table.toggleSortOrder(numberColumn); final Map<Integer, Color> lookup = new HashMap<Integer, Color>(); Color[] colors = new Color[] { Color.YELLOW, Color.CYAN, Color.MAGENTA, Color.GREEN }; int rowsPerColor = (table.getRowCount() - 5) / colors.length; for (int i = 0; i < colors.length; i++) { for (int j = 0; j < rowsPerColor; j++) { lookup.put((Integer) table.getValueAt(i * rowsPerColor + j, numberColumn), colors[i]); } } table.resetSortOrder(); // PENDING JW: add and use HighlightPredicate.SELECTED/UN_SELECTED Highlighter hl = new ColorHighlighter() { @Override protected void applyBackground(Component renderer, ComponentAdapter adapter) { if (adapter.isSelected()) return; Color background = lookup.get(adapter.getValue(numberColumn)); if (background != null) { renderer.setBackground(background); } } }; table.addHighlighter(hl); showWithScrollingInFrame(table, "conditional highlighter with value-based color mapping"); } /** * test to see searchPanel functionality in new Highlighter api * */ public void interactiveSearchPanel() { JXTable table = new JXTable(tableModel); final ColorHighlighter cl = new ColorHighlighter(new PatternPredicate((Pattern) null, 0), null, Color.RED); table.addHighlighter(cl); JXSearchPanel searchPanel = new JXSearchPanel(); PatternMatcher patternMatcher = new PatternMatcher() { @Override public Pattern getPattern() { return getPatternPredicate().getPattern(); } @Override public void setPattern(Pattern pattern) { PatternPredicate old = getPatternPredicate(); cl.setHighlightPredicate(new PatternPredicate(pattern, old .getTestColumn(), old.getHighlightColumn())); } private PatternPredicate getPatternPredicate() { return (PatternPredicate) cl.getHighlightPredicate(); } }; searchPanel.addPatternMatcher(patternMatcher); JXFrame frame = wrapWithScrollingInFrame(table, "Pattern highlighting col 0"); addStatusComponent(frame, searchPanel); show(frame); } //----------------- custom PatternMatcher /** * columm shading (was: hierarchicalColumnHighlighter) * */ public void interactiveColumnShading() { JXTreeTable treeTable = new JXTreeTable(new FileSystemModel()); // simulate hierarchicalColumnHighlighter int hierarchicalColumn = 0; for (int i = 0; i < treeTable.getColumnCount(); i++) { if (treeTable.isHierarchical(i)) { hierarchicalColumn = i; break; } } treeTable.addHighlighter(new ShadingColorHighlighter(new ColumnHighlightPredicate(hierarchicalColumn))); showWithScrollingInFrame(treeTable, "hierarchical column"); } /** * Classic lineprinter striping and hyperlink (LF only, no action). * */ public void interactiveTableAlternateAndHyperlink() { JXTable table = new JXTable(tableModel); table.setRowHeight(22); table.getColumn(1).setCellRenderer( new DefaultTableRenderer(new HyperlinkProvider())); table.addHighlighter(HighlighterFactory .createSimpleStriping(HighlighterFactory.CLASSIC_LINE_PRINTER)); JFrame frame = wrapWithScrollingInFrame(table, "classic lineprinter and hyperlink on column 1"); frame.setVisible(true); } /** * LinePrinter striping and rollover. * */ public void interactiveTableAlternateAndRollover() { JXTable table = new JXTable(tableModel); table.setRowHeight(22); table.setHighlighters( HighlighterFactory.createSimpleStriping(HighlighterFactory.LINE_PRINTER), new ColorHighlighter(HighlightPredicate.ROLLOVER_ROW, Color.YELLOW, null)); showWithScrollingInFrame(table, "LinePrinter plus yellow rollover"); } /** * Foreground highlight on column 1 and 3. * */ public void interactiveColumnForeground() { JXTable table = new JXTable(tableModel); HighlightPredicate predicate = new ColumnHighlightPredicate(1, 3); table.addHighlighter(new ColorHighlighter(predicate, null, Color.BLUE)); showWithScrollingInFrame(table, "Foreground highlight col 1 and 3"); } /** * ColorHighlighter with pattern predicate * */ public void interactiveTablePatternHighlighter() { JXTable table = new JXTable(tableModel); table.setColumnControlVisible(true); table.addHighlighter(new ColorHighlighter(new PatternPredicate("^M", 1), null, Color.red)); showWithScrollingInFrame(table, "Pattern: highlight row if ^M col 1"); } /** * Issue #258-swingx: Background LegacyHighlighter must not change custom * foreground. * <p> * * Use SwingX extended default renderer. */ public void interactiveTableCustomRendererColor() { TableModel model = new AncientSwingTeam(); JXTable table = new JXTable(model); DefaultTableRenderer renderer = new DefaultTableRenderer(); renderer.setForeground(foreground); renderer.setBackground(background); table.addHighlighter(HighlighterFactory.createAlternateStriping(Color.WHITE, HighlighterFactory.GENERIC_GRAY)); table.setDefaultRenderer(Object.class, renderer); JXTable nohighlight = new JXTable(model); nohighlight.setDefaultRenderer(Object.class, renderer); showWithScrollingInFrame(table, nohighlight, "ext: custom colored renderer with bg highlighter <--> shared without highl"); } /** * Requirement from forum: value based color and tooltip. * * Here the tooltip is regarded as visual decoration and * set in a specialized Highlighter. * */ public void interactiveValueBasedToolTipAndColorOnHighlighter() { ToolTipManager t = ToolTipManager.sharedInstance(); LOG.info("initial/reshow/dismiss" + t.getInitialDelay() + " / " + t.getReshowDelay() + " / " + t.getDismissDelay() + " / " + UIManager.getString("ToolTipManager.enableToolTipMode")); final JXTable table = new JXTable(new AncientSwingTeam()) { // @Override // public Point getToolTipLocation(MouseEvent event) { // int column = columnAtPoint(event.getPoint()); // int row = rowAtPoint(event.getPoint()); // Rectangle cellRect = getCellRect(row, column, false); // if (!getComponentOrientation().isLeftToRight()) { // cellRect.translate(cellRect.width, 0); // } // // PENDING JW: otherwise we get a small (borders only) tooltip for null // // core issue? Yeh, the logic in tooltipManager is crooked. // // but this here is ehem ... rather arbitrary. //// return getValueAt(row, column) == null ? null : cellRect.getLocation(); // return getToolTipText(event) == null ? null : cellRect.getLocation(); //// return null; // } // }; t.unregisterComponent(table); table.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke('q'), "dummy"); t.registerComponent(table); table.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke("F5"), "hideTip"); LOG.info("hideTip? " + table.getActionMap().get("hideTip")); PropertyChangeListener l = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { LOG.info("evt.getP" + evt.getPropertyName()); ToolTipManager.sharedInstance().mousePressed(null); } }; table.addPropertyChangeListener(RolloverProducer.ROLLOVER_KEY, l); // table.addMouseMotionListener(new MouseMotionAdapter() { // int prevRow = -1; // int prevCol = -1; // // public void mouseMoved(MouseEvent e) { // int row = table.rowAtPoint(e.getPoint()); // int col = table.columnAtPoint(e.getPoint()); // if (row == prevRow && col == prevCol) // return; // ToolTipManager.sharedInstance().mousePressed(e); //// ToolTipManager.sharedInstance().mouseEntered(e); // prevRow = row; // prevCol = col; // } // }); HighlightPredicate predicate = new HighlightPredicate() { @Override public boolean isHighlighted(Component renderer, ComponentAdapter adapter) { if (!(adapter.getValue() instanceof Number)) return false; return ((Number) adapter.getValue()).intValue() < 10; } }; ColorHighlighter hl = new ColorHighlighter( predicate, null, Color.RED, null, Color.RED); // THINK this is possible, but maybe not the correct place // ... more on the what-side of "what vs. how" ? Highlighter tl = new AbstractHighlighter(predicate) { @Override protected Component doHighlight(Component component, ComponentAdapter adapter) { String text = "low on luck: " + ((JLabel) component).getText(); ((JComponent) component).setToolTipText(text); return component; } @Override protected boolean canHighlight(Component component, ComponentAdapter adapter) { return component instanceof JLabel; } }; table.setHighlighters(HighlighterFactory.createSimpleStriping(HighlighterFactory.GENERIC_GRAY), hl, tl); showWithScrollingInFrame(table, "Value-based Tooltip ... on Highlighter"); } /** * Requirement from forum: value based color and tooltip.<p> * * Here the tooltip is regarded as belonging more to the "what" * of rendering and set in a custom provider. The implication * is that the logic (whether to show the tooltip or not) is * duplicated (in the predicate and the provider. * * */ public void interactiveValueBasedToolTipAndColorOnProvider() { JXTable table = new JXTable(new AncientSwingTeam()); HighlightPredicate predicate = new HighlightPredicate() { @Override public boolean isHighlighted(Component renderer, ComponentAdapter adapter) { if (!(adapter.getValue() instanceof Number)) return false; return ((Number) adapter.getValue()).intValue() < 10; } }; ColorHighlighter hl = new ColorHighlighter( predicate, null, Color.RED, null, Color.RED); table.setHighlighters(HighlighterFactory.createSimpleStriping(HighlighterFactory.GENERIC_GRAY), hl); //, tl); // here: set's value based .. this duplicates logic of // predicate LabelProvider provider = new LabelProvider() { @Override protected void configureState(CellContext context) { super.configureState(context); rendererComponent.setToolTipText(getToolTipText(context)); } private String getToolTipText(CellContext context) { if ((context.getValue() instanceof Number)) { int luck = ((Number) context.getValue()).intValue(); if (luck < 10) { return "low on luck: " + luck; } } return null; } }; provider.setHorizontalAlignment(JLabel.RIGHT); table.setDefaultRenderer(Number.class, new DefaultTableRenderer(provider)); showWithScrollingInFrame(table, "Value-based Tooltip ... on provider"); } /** * Example of custom predicate based on the component's value, * (as opposed to on the value of the adapter). * * */ public void interactiveTableColorBasedOnComponentValue() { TableModel model = new AncientSwingTeam(); JXTable table = new JXTable(model); table.setForeground(Color.GREEN); HighlightPredicate predicate = new HighlightPredicate() { @Override public boolean isHighlighted(Component renderer, ComponentAdapter adapter) { if (!(renderer instanceof JLabel)) return false; String text = ((JLabel) renderer).getText(); return text.contains("y"); } }; ColorHighlighter hl = new ColorHighlighter(predicate, null, Color.RED); table.addHighlighter(HighlighterFactory.createSimpleStriping(HighlighterFactory.GENERIC_GRAY)); table.addHighlighter(hl); showWithScrollingInFrame(table, "component value-based rendering (label text contains y) "); } //------------------ rollover /** * Issue #503-swingx: custom cursor respected when rollover? * Seems okay for table, */ public void interactiveRolloverHighlightCustomCursor() { JXTable table = new JXTable(tableModel); table.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); table.addHighlighter(new ColorHighlighter(HighlightPredicate.ROLLOVER_ROW, Color.YELLOW, null)); showWithScrollingInFrame(table, "rollover highlight, custom cursor"); } /** * Plain RolloverHighlighter. * Issue #513-swingx: no rollover effect for disabled table. * */ public void interactiveRolloverHighlight() { final JXTable table = new JXTable(tableModel); ColorHighlighter colorHighlighter = new ColorHighlighter(HighlightPredicate.ROLLOVER_ROW, Color.YELLOW, null); table.addHighlighter(colorHighlighter); Action action = new AbstractAction("toggle table enabled") { @Override public void actionPerformed(ActionEvent e) { table.setEnabled(!table.isEnabled()); } }; JXFrame frame = showWithScrollingInFrame(table, "rollover highlight, enabled/disabled table"); addAction(frame, action); frame.pack(); } //--------------------- factory /** * Simple ui-striping. * */ public void interactiveTreeTableSimpleStripingUI() { JXTreeTable table = new JXTreeTable(new FileSystemModel()); table.setVisibleRowCount(table.getRowCount() + 3); table.addHighlighter(HighlighterFactory.createSimpleStriping()); showWithScrollingInFrame(table, "Simple ui striping"); } /** * shows the effect of a simple striping highlighter on a * colored table. * */ public void interactiveTreeTableSimpleStriping() { JXTreeTable table = new JXTreeTable(new FileSystemModel()); table.setVisibleRowCount(table.getRowCount() + 3); table.setBackground(new Color(0xC0FFC0)); table.addHighlighter(HighlighterFactory.createSimpleStriping()); showWithScrollingInFrame(table, "Simple gray striping"); } /** * Simple ui-striping. * */ public void interactiveSimpleStripingUI() { JXTable table = new JXTable(tableModel); table.setVisibleRowCount(table.getRowCount() + 3); table.addHighlighter(HighlighterFactory.createSimpleStriping()); showWithScrollingInFrame(table, "Simple ui striping"); } /** * shows the effect of a simple striping highlighter on a * colored table. * */ public void interactiveSimpleStriping() { JXTable table = new JXTable(tableModel); table.setVisibleRowCount(table.getRowCount() + 3); table.setBackground(new Color(0xC0FFC0)); table.addHighlighter(HighlighterFactory.createSimpleStriping()); Highlighter disabled = new AbstractHighlighter(HighlightPredicate.READ_ONLY) { @Override protected Component doHighlight(Component component, ComponentAdapter adapter) { component.setEnabled(false); return component; } }; table.getColumnExt(0).setEditable(false); table.getColumnExt(2).setEditable(false); table.getColumnExt(0).setCellRenderer(new DefaultTableRenderer(new TextFieldProvider())); table.addHighlighter(disabled); showWithScrollingInFrame(table, "Simple gray striping"); } public static class TextFieldProvider extends ComponentProvider<JTextField> { @Override protected void configureState(CellContext context) { // TODO Auto-generated method stub } @Override protected JTextField createRendererComponent() { JTextField field = new JTextField(20); return field; } @Override protected void format(CellContext context) { rendererComponent.setText(getValueAsString(context)); } } /** * shows the effect of a simple striping highlighter on a * colored table. * */ public void interactiveSimpleStripingGroup() { JXTable table = new JXTable(tableModel); table.setVisibleRowCount(table.getRowCount() + 3); table.setBackground(Color.YELLOW); table.addHighlighter(HighlighterFactory.createSimpleStriping(Color.LIGHT_GRAY, 3)); showWithScrollingInFrame(table, "Simple gray striping, grouped by 3"); } /** * shows the effect of a simple striping highlighter on a * colored table. * */ public void interactiveAlternateStriping() { JXTable table = new JXTable(tableModel); table.setVisibleRowCount(table.getRowCount() + 3); table.setBackground(Color.YELLOW); table.addHighlighter(HighlighterFactory.createAlternateStriping(Color.WHITE, Color.LIGHT_GRAY)); showWithScrollingInFrame(table, "Alternate white/gray striping"); } /** * shows the effect of a simple striping highlighter on a * colored table. * */ public void interactiveAlternateStripingGroup() { JXTable table = new JXTable(tableModel); table.setVisibleRowCount(table.getRowCount() + 3); table.setBackground(Color.YELLOW); table.addHighlighter(HighlighterFactory.createAlternateStriping(Color.WHITE, Color.LIGHT_GRAY, 3)); showWithScrollingInFrame(table, "Alternate white/gray striping"); } @Override protected void setUp() throws Exception { super.setUp(); tableModel = new AncientSwingTeam(); } /** * Do nothing, make the test runner happy * (would output a warning without a test fixture). * */ public void testDummy() { } }