Swing JTree 图标渲染

发布于 2024-11-04 01:52:42 字数 2864 浏览 8 评论 0原文

我想在我的 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:

Badly rendered tree

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:

enter image description here

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟酉 2024-11-11 01:52:42

这对我来说效果很好。仔细检查是否有其他情况发生。

如果您在树显示后更改此设置,请确保重新绘制树。

一个丑陋的解决方法可能是使用 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.

ゞ记忆︶ㄣ 2024-11-11 01:52:42

另一种方法是使用没有像素的实现,如建议的此处

An alternative is to use an implementation having no pixels, as suggested here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文