Reputation: 11597
I want to have a JTree in my swing application that does not have an icon for leaf nodes, so I wrote the following code:
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer)
jtree.getCellRenderer();
renderer.setLeafIcon(null);
jtree.setCellRenderer(renderer);
This correctly removes the icons for leaves, but it also results in the following rendering error:
You can see that the labels attached to the branch nodes are truncated, and they are bunched too close together. If I expand and then collapse all the branch nodes, the problem fixes itself:
If I comment out the line:
renderer.setLeafIcon(null);
The problem goes away (but the leaf icon, which I don't want, is present.)
Any ideas how to fix this?
Edit: I'll add all the relevant code.
public class StepChooserPanel extends JScrollPane {
private JTree rules;
public StepChooserPanel(TabPanel parent){
super();
this.setBackground(Color.white);
DefaultMutableTreeNode top = new DefaultMutableTreeNode("top");
rules = new JTree();
rules.getSelectionModel()
.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
rules.setRootVisible(false);
rules.setScrollsOnExpand(false);
rules.setToggleClickCount(1);
rules.addTreeSelectionListener(parent);
rules.putClientProperty("JTree.lineStyle", "None");
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer)
rules.getCellRenderer();
renderer.setLeafIcon(null);
rules.setCellRenderer(renderer);
this.setViewportView(rules);
}
public void populateFilterRules(InferenceSystem system){
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
TreeModel treeModel = new DefaultTreeModel(root);
rules.setModel(treeModel);
List<Rule> systemRules = system.getSortedRules();
for(int i = 0; i < systemRules.size(); i++){
if(!(systemRules.get(i) instanceof InferenceRule)){
continue;
}
DefaultMutableTreeNode rule = new DefaultMutableTreeNode
(systemRules.get(i).getName());
root.add(rule);
}
rules.expandPath(new TreePath(root.getPath()));
this.repaint();
}
public void populateRewriteList(Collection<Rewrite> choices){
DefaultMutableTreeNode root = (DefaultMutableTreeNode) rules.getModel()
.getRoot();
for(Rewrite rr : choices){
for (int i = 0; i < root.getChildCount(); i++){
String ruleName = (String) ((DefaultMutableTreeNode)root.getChildAt(i))
.getUserObject();
if(rr.getRule().getName().equals(ruleName)){
((DefaultMutableTreeNode)root.getChildAt(i))
.add(new DefaultMutableTreeNode(rr));
}
}
}
this.repaint();
}
All the setup is done in the constructor. populateFilterRules is called, which adds in the branch nodes. Then populateRewriteList is called, which adds in the leaf nodes to the right places. repaint is called after these changes are made. The containing JScrollPane class is wrapped into a JSplitPane, which is rendered into the frame.
Upvotes: 2
Views: 2089
Reputation: 205785
An alternative is to use an implementation having no pixels, as suggested here.
Upvotes: 1
Reputation: 23629
This works fine for me. Double check that there is not something else going on.
If you are changing this after the tree has been displayed, make sure you are repainting the tree.
An ugly work around might be a 100% transparent icon instead of null.
Upvotes: 1