Question

I know that you can change the Tree.collapsedIcon for a all JTrees in an application using Swing using the UImanager. For example:

UIManager.put("Tree.collapsedIcon",closedcabinet);

I would like the flexibility of changing the Tree.collapsedIcon for individual JTrees in the same application with the end result being that the Tree.collpasedIcon could appear differently for different trees in the same application.

I know how to customize individual icons using a custom renderer. For example, I use setIcon to set the icon of a leaf, SetOpenIcon to set the icon for a node that has children when its expanded and SetCloseIcon to do the same for nodes that are not.

But I don't see how to do this for the Tree.collapsedIcon other than use the UIManager which has the limitations as described above.

Anyone know how to do this?

Was it helpful?

Solution 2

Another approach is to condition the UIManager when constructing each tree. In the example below, static factories provide the required Icon pair. The example borrows two icons from the MetalLookAndFeel for contrast. Custom icons, seen here, are also possible.

frame.add(new JTreePanel(Icons.getDefault()));
frame.add(new JTreePanel(Icons.getMetal()));

image

SSCCE:

import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.metal.MetalLookAndFeel;

/** @see https://stackoverflow.com/a/14262706/230513 */
public class JTreePanel extends JPanel {

    public static final class Icons {

        private static final String COLLAPSED_ICON = "Tree.collapsedIcon";
        private static final String EXPANDED_ICON = "Tree.expandedIcon";
        private Icon collapsed;
        private Icon expanded;

        public static Icons getDefault() {
            Icons icons = new Icons();
            icons.collapsed = (Icon) UIManager.get(COLLAPSED_ICON);
            icons.expanded = (Icon) UIManager.get(EXPANDED_ICON);
            return new Icons();
        }

        public static Icons getMetal() {
            Icons icons = new Icons();
            try {
                LookAndFeel save = UIManager.getLookAndFeel();
                LookAndFeel laf = new MetalLookAndFeel();
                UIManager.setLookAndFeel(laf);
                icons.collapsed = (Icon) UIManager.get(COLLAPSED_ICON);
                icons.expanded = (Icon) UIManager.get(EXPANDED_ICON);
                UIManager.setLookAndFeel(save);
            } catch (UnsupportedLookAndFeelException ex) {
                ex.printStackTrace(System.err);
            }
            return icons;
        }
    }

    public JTreePanel(Icons pair) {
        UIManager.put("Tree.collapsedIcon", pair.collapsed);
        UIManager.put("Tree.expandedIcon", pair.expanded);
        JTree tree = new JTree();
        this.add(tree);
        for (int i = 0; i < tree.getRowCount(); i++) {
            tree.expandRow(i);
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                createGUI();
            }
        });
    }

    private static void createGUI() {
        final JFrame frame = new JFrame();
        frame.setLayout(new GridLayout(1, 0));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new JTreePanel(Icons.getDefault()));
        frame.add(new JTreePanel(Icons.getMetal()));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

OTHER TIPS

If you make the assumption that TreeUI that you are using is an instance of BasicTreeUI, you can do the following:

TreeUI tui = treeInstance.getUI();
if (tui instanceof BasicTreeUI) {
  ((BasicTreeUI)tui).setCollapsedIcon(myIcon);
}

Only way I can see is to create your own version of JTree from the Java source code that allows you to define the icons for each JTree.

I see that JTree gets the icons from javax.accessibility.AccessibleContext and eventually some defined class of the AccessibleIcon interface.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top