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?
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()));
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);
}
}
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.
来源:https://stackoverflow.com/questions/14260185/customizing-tree-collapsedicon-for-a-single-jtree