Swing JTree 图标渲染
我想在我的 swing 应用程序中有一个没有叶节点图标的 JTree,因此我编写了以下代码:
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer)
jtree.getCellRenderer();
renderer.setLeafIcon(null);
jtree.setCellRenderer(renderer);
这正确地删除了叶节点的图标,但它也会导致以下渲染错误:
您可以看到附加到分支节点的标签被截断,并且它们聚集得太近。如果我展开然后折叠所有分支节点,问题会自行解决:
如果我注释掉该行:
renderer.setLeafIcon(null);
问题消失了(但是出现了我不想要的叶子图标。)
有什么想法可以解决这个问题吗?
编辑:我将添加所有相关代码。
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();
}
所有设置都在构造函数中完成。调用 populateFilterRules,它会添加分支节点。然后调用 populateRewriteList,将叶节点添加到正确的位置。进行这些更改后调用 repaint。包含的 JScrollPane 类被包装到 JSplitPane 中,并渲染到框架中。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这对我来说效果很好。仔细检查是否有其他情况发生。
如果您在树显示后更改此设置,请确保重新绘制树。
一个丑陋的解决方法可能是使用 100% 透明图标而不是 null。
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.
另一种方法是使用没有像素的实现,如建议的此处。
An alternative is to use an implementation having no pixels, as suggested here.