/* * Created on 14.10.2005 * */ package org.jdesktop.swingx.decorator; import java.awt.Color; import java.awt.Component; import java.net.MalformedURLException; import java.net.URL; import java.util.logging.Logger; import javax.swing.DefaultListModel; import javax.swing.JTable; import javax.swing.ListModel; import javax.swing.UIManager; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableModel; import org.jdesktop.swingx.JXEditorPaneTest; import org.jdesktop.swingx.JXList; import org.jdesktop.swingx.JXTable; import org.jdesktop.swingx.JXTree; import org.jdesktop.swingx.decorator.HighlighterFactory.UIColorHighlighter; import org.jdesktop.swingx.hyperlink.LinkModel; import org.jdesktop.swingx.renderer.DefaultTreeRenderer; import org.jdesktop.test.AncientSwingTeam; public class HighlighterIssues extends org.jdesktop.swingx.InteractiveTestCase { private static final Logger LOG = Logger.getLogger(HighlighterIssues.class .getName()); protected Color ledger = new Color(0xF5, 0xFF, 0xF5); protected Color background = Color.RED; protected Color foreground = Color.BLUE; protected ColorHighlighter emptyHighlighter; // flag used in setup to explicitly choose LF protected boolean defaultToSystemLF; //---------------- uidependent /** * test if background changes with LF. * * PENDING: this is not entirely correct, might fail because * both LFs fall back to GenericGray. */ public void testLookupUIColor() { UIColorHighlighter hl = new UIColorHighlighter(); Color color = hl.getBackground(); String lf = UIManager.getLookAndFeel().getName(); Color uiColor = UIManager.getColor("UIColorHighlighter.stripingBackground"); assertNotNull(uiColor); // switch LF setSystemLF(!defaultToSystemLF); if (lf.equals(UIManager.getLookAndFeel().getName())) { LOG.info("cannot run lookupUIColor - same LF" + lf); return; } Color uiColor2 = UIManager.getColor("UIColorHighlighter.stripingBackground"); assertNotNull(uiColor2); // hmm ... how to force the reloading in the addon? LOG.info("color must be different " + uiColor + "/" + uiColor2); assertFalse("color must be different " + uiColor + "/" + uiColor2 , uiColor2.equals(uiColor)); hl.updateUI(); assertFalse("highlighter background must be changed", color.equals(hl.getBackground())); } /** * test if background changes with LF. * * PENDING: this is not entirely correct, might fail because * both LFs fall back to GenericGray. */ public void testLookupUIColorInCompound() { UIColorHighlighter hl = new UIColorHighlighter(); Color color = hl.getBackground(); CompoundHighlighter compound = new CompoundHighlighter(hl); String lf = UIManager.getLookAndFeel().getName(); // switch LF setSystemLF(!defaultToSystemLF); if (lf.equals(UIManager.getLookAndFeel().getName())) { LOG.info("cannot run lookupUIColor - same LF" + lf); return; } compound.updateUI(); assertFalse("highlighter background must be changed", color.equals(hl.getBackground())); } /** * Issue #258-swingx: DefaultTableCellRenderer has memory. * How to formulate as test? * this is testing the hack (reset the memory in ResetDTCR to null), not * any highlighter! */ public void testTableUnSelectedDoNothingHighlighter() { JXTable table = new JXTable(10, 2); DefaultTableCellRenderer renderer = new DefaultTableCellRenderer(); renderer.setForeground(foreground); table.setHighlighters(new ColorHighlighter()); Component comp = table.prepareRenderer(renderer, 0, 0); assertEquals("do nothing highlighter must not change foreground", foreground, comp.getForeground()); fail("testing the hack around DefaultTableCellRenderer memory - not the memory itself"); } //--------------- public static void main(String args[]) { // setSystemLF(true); HighlighterIssues test = new HighlighterIssues(); try { // test.runInteractiveTests(); test.runInteractiveTests("interactive.*Predicate.*"); } catch (Exception e) { System.err.println("exception when executing interactive tests:"); e.printStackTrace(); } } /** * Issue #258-swingx: Background LegacyHighlighter must not change custom * foreground. * <p> * * Visualizing effect of hack: table-internally, a ResetDTCRColorHighlighter * tries to neutralize DefaultTableCellRenderer's color memory. * * <ul> * <li> a DTCR subclass with value-based custom foreground * <li> the renderer is shared between a table with background highlighter * (alternateRowHighlighter) and a table without highlighter * <li> the custom value-based foreground must show in both * (AlternateRowHighlighter overwrite both striped and unstriped back) * </ul> * * This behaves as expected after moving the hack to _before_ calling * super.prepareRenderer. */ public void interactiveTableCustomCoreRendererColorBasedOnValue() { TableModel model = new AncientSwingTeam(); JXTable table = new JXTable(model); DefaultTableCellRenderer renderer = new DefaultTableCellRenderer() { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // TODO Auto-generated method stub super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if (!isSelected) { if (getText().contains("y")) { setForeground(Color.RED); } else { setForeground(Color.GREEN); } } return this; } }; table.addHighlighter( HighlighterFactory.createSimpleStriping(HighlighterFactory.GENERIC_GRAY)); table.setDefaultRenderer(Object.class, renderer); JXTable nohighlight = new JXTable(model); nohighlight.setDefaultRenderer(Object.class, renderer); showWithScrollingInFrame(table, nohighlight, "core - value-based fg renderer with bg highlighter <--> shared without highl"); } /** * Issue #258-swingx: Background LegacyHighlighter must not change custom * foreground. * <p> * * Visualizing effect of hack: table-internally, a ResetDTCRColorHighlighter * tries to neutralize DefaultTableCellRenderer's color memory. * * <ul> * <li> a DTCR with custom foreground and custom background * <li> the renderer is shared between a table with background highlighter * (alternateRowHighlighter) and a table without highlighter * <li> the custom foreground must show in both * <li> the custom background must show in the table without highlighter * <li> the custom background must not show in the table with highlighter * (AlternateRowHighlighter overwrite both striped and unstriped back) * </ul> * */ public void interactiveTableCustomCoreRendererColor() { TableModel model = new AncientSwingTeam(); JXTable table = new JXTable(model); DefaultTableCellRenderer renderer = new DefaultTableCellRenderer(); renderer.setForeground(foreground); renderer.setBackground(background); table.addHighlighter( HighlighterFactory.createSimpleStriping(HighlighterFactory.GENERIC_GRAY)); table.setDefaultRenderer(Object.class, renderer); JXTable nohighlight = new JXTable(model); nohighlight.setDefaultRenderer(Object.class, renderer); showWithScrollingInFrame(table, nohighlight, "core: custom colored renderer with bg highlighter <--> shared without highl"); } /** * Issue #258-swingx: Background LegacyHighlighter must not change custom * foreground. * <p> * * Visualizing effect of hack: table-internally, a ResetDTCRColorHighlighter * tries to neutralize DefaultTableCellRenderer's color memory. * * Problem: if pre-hack-highlighting and selected on first rendering, * the renderer always uses the selection color. Bug in hacking highlighter? * Not much it can do about it: the hacking does not store the color if * the adapter isSelected - so in the next round the previously configured * color - which was for selected state - is stored as to color to restore to. * <p> * Arrggghhh... * */ public void interactiveTableCoreRendererFirstSelected() { TableModel model = new AncientSwingTeam(); DefaultTableCellRenderer renderer = new DefaultTableCellRenderer(); // JXTable table = new JXTable(model); // table.addHighlighter(AlternateRowHighlighter.genericGrey); // table.setDefaultRenderer(Object.class, renderer); JXTable nohighlight = new JXTable(model); nohighlight.setDefaultRenderer(Object.class, renderer); nohighlight.setRowSelectionInterval(0, 0); // showWithScrollingInFrame(table, nohighlight, showWithScrollingInFrame(nohighlight, "core: very first match is against selected"); } /** * UIHighlighter: check if highlighter is updated when toggling LF. */ public void interactiveUITableWithAlternateRow() { JXTable table = new JXTable(10, 2); table.setBackground(ledger); table.setHighlighters(HighlighterFactory.createSimpleStriping()); JXTable nohighlight = new JXTable(10, 2); nohighlight.setBackground(ledger); showWithScrollingInFrame(table, nohighlight, "colored table with ui highlighter <--> without highlighter"); } /** * Effect of background highlighters on list with custom background. * */ public void interactiveColoredListWithAlternateRow() { JXList list = new JXList(createListModel()); list.setBackground(ledger); list.addHighlighter( HighlighterFactory.createSimpleStriping(HighlighterFactory.GENERIC_GRAY)); JXList nohighlight = new JXList(createListModel()); nohighlight.setBackground(ledger); showWithScrollingInFrame(list, nohighlight, "colored list with striping <--> without "); } /** * * Effect of background highlighters on tree with custom background. Note: * background highlighters don't work at all with DefaultTreeCellRenderers. */ public void interactiveColoredTreeWithAlternateRow() { JXTree coreRendering = new JXTree(); coreRendering.setHighlighters(HighlighterFactory.createSimpleStriping(HighlighterFactory.GENERIC_GRAY)); coreRendering.setBackground(ledger); JXTree tree = new JXTree(); tree.setCellRenderer(new DefaultTreeRenderer()); tree.setHighlighters(HighlighterFactory.createSimpleStriping(HighlighterFactory.GENERIC_GRAY)); tree.setBackground(ledger); showWithScrollingInFrame(tree, coreRendering, "colored tree with striping: swingx <--> core"); } @SuppressWarnings("all") private TableModel createTableModelWithLinks() { String[] columnNames = { "text only", "Link editable", "Link not-editable", "Bool editable", "Bool not-editable" }; DefaultTableModel model = new DefaultTableModel(columnNames, 0) { public Class<?> getColumnClass(int column) { return getValueAt(0, column).getClass(); } @Override public boolean isCellEditable(int row, int column) { return !getColumnName(column).contains("not"); } }; for (int i = 0; i < 4; i++) { try { LinkModel link = new LinkModel("a link text " + i, null, new URL("http://some.dummy.url" + i)); if (i == 1) { URL url = JXEditorPaneTest.class.getResource("resources/test.html"); link = new LinkModel("a link text " + i, null, url); } model.addRow(new Object[] {"text only " + i, link, link, Boolean.TRUE, Boolean.TRUE }); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return model; } /** * Issue #178-swingx: Highlighters must not change the selection color if selection colors * not set. * * Compare table with empty highlighter to table without highlighter. */ public void interactiveTableWithDoNothingHighlighter() { JXTable table = new JXTable(new AncientSwingTeam()); table.addHighlighter(emptyHighlighter); showWithScrollingInFrame(table, new JXTable(table.getModel()), "selection: empty highlighter <--> no highlighter"); } //------------------ helpers private ListModel createListModel() { DefaultListModel model = new DefaultListModel(); for (int i = 0; i < 10; i++) { model.add(i, i); } return model; } }