javaswingrendererswingxjxtreetable

JXTreeTable in combination with TreeCellRender and selectedBackground with ColorHighlighter


I' m trying to set a custom selectionBackground to rows in a JXTreeTable. This works if I'm not setting a custom TreeCellRenderer. If I set it additionally like in my example the selectionBackground of the text of the node is the default one. Any ideas how to get the background of the nodetext to the custom one?

import java.awt.Color;

import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.UIManager;

import org.jdesktop.swingx.JXTreeTable;
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.jdesktop.swingx.decorator.HighlightPredicate;
import org.jdesktop.swingx.renderer.DefaultTreeRenderer;
import org.jdesktop.swingx.renderer.IconValue;
import org.jdesktop.swingx.treetable.DefaultMutableTreeTableNode;
import org.jdesktop.swingx.treetable.DefaultTreeTableModel;

public class TestHighlighter {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JScrollPane scrollPane = new JScrollPane();
        frame.setContentPane(scrollPane);

        JXTreeTable treeTable = new JXTreeTable(new DefaultTreeTableModel(new DefaultMutableTreeTableNode("Test")));
        treeTable.setRootVisible(true);
        scrollPane.setViewportView(treeTable);

        DefaultTreeRenderer treeCellRenderer = new DefaultTreeRenderer(new IconValue() {
            @Override
            public Icon getIcon(Object value) {
                return UIManager.getIcon("FileView.directoryIcon");
            }
        });
        //Comment out next line and background is like set in Highlighter
        treeTable.setTreeCellRenderer(treeCellRenderer);

        treeTable.addHighlighter(new ColorHighlighter(HighlightPredicate.ALWAYS, null, null, Color.RED, null));

        frame.pack();
        frame.setVisible(true);
    }
}

I also tried to use an IconHighlighter (to avoid using custom TreeCellRenderer) to change the Icon of the node, but the icon does not changed.

treeTable.addHighlighter(new IconHighlighter(HighlightPredicate.ALWAYS, UIManager.getIcon("FileView.directoryIcon")));

Solution

  • [...]the problem is, that I want to have different selectionBackgrounds dependent of the node. [...] I thought there is maybe a more elegant way by using the swingx-renderer.

    You can certainly use a SwingX renderer (aka: DefaultTreeRenderer) and override getCellRendererComponent(...) in order to set the background color depending on the node as you wish. For example:

    IconValue iconValue = new IconValue() {
        @Override
        public Icon getIcon(Object value) {
            return UIManager.getIcon("FileView.directoryIcon");
        }
    };
    
    DefaultTreeRenderer treeCellRenderer = new DefaultTreeRenderer(iconValue) {
        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            Component c = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
            if (selected && leaf) {
                c.setBackground(Color.RED);
            } else {
                setBackground(tree.getBackground());
            }
            return c;
        }
    };
    

    In this snippet if a leaf (not root nor parent) node is selected then the label's background color will be red. Otherwise the label's background color will be the default.