Personalizar Tree.collapsedIcon para un solo JTree

Sé que puede cambiar Tree.collapsedIcon para todos los JTrees en una aplicación usando Swing usando UImanager . Por ejemplo:

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

Me gustaría la flexibilidad de cambiar Tree.collapsedIcon para Tree.collapsedIcon individuales en la misma aplicación, con el resultado final de que Tree.collpasedIcon podría aparecer de forma diferente para diferentes árboles en la misma aplicación.

Sé cómo personalizar íconos individuales usando un renderizador personalizado. Por ejemplo, uso setIcon para establecer el icono de una hoja, SetOpenIcon para establecer el icono para un nodo que tiene hijos cuando está expandido y SetCloseIcon para hacer lo mismo para los nodos que no lo son.

Pero no veo cómo hacer esto para Tree.collapsedIcon no sea el uso del UIManager que tiene las limitaciones descritas anteriormente.

Alguien sabe cómo hacer esto?

    Otro enfoque es condicionar el UIManager al construir cada árbol. En el siguiente ejemplo, las fábricas estáticas proporcionan el par de Icon requerido. El ejemplo toma prestados dos icons de MetalLookAndFeel para contraste. Los icons personalizados, vistos aquí , también son posibles.

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

    imagen

    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); } } 

    Si asume que TreeUI que está utilizando es una instance of BasicTreeUI , puede hacer lo siguiente:

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

    La única forma que puedo ver es crear su propia versión de JTree a partir del código fuente de Java que le permite definir los icons para cada JTree.

    Veo que JTree obtiene los icons de javax.accessibility.AccessibleContext y eventualmente alguna clase definida de la interfaz de AccessibleIcon .