【问题标题】:DefaultTreeCellRenderer not working as expectedDefaultTreeCellRenderer 未按预期工作
【发布时间】:2013-07-15 09:45:41
【问题描述】:

我疯了,因为我不明白我做错了什么。我需要我的树的每个节点都有一个不同的图标,就好像它是正确的、不正确的或需要更新一样。我看到了 Oracle 文档和很多网页(包括 Stackoverflow),但我的代码只显示了具有相同图标的所有节点。如果我做错了什么,我很抱歉,这是我的第一篇文章:>

显示: 我不能显示,因为我没有声望>.

想象一棵树,并想象它总是显示带有 gifNew 图标的 leafIcon。似乎只有状态会监听最后一个节点。

这是代码(所有变量都正确创建,像 gifNew 之类的图标也是如此):

图标:

static Icon closedIcon = new ImageIcon("folder.png");
    static Icon openIcon = new ImageIcon("folder.png");
    static Icon leafIcon = new ImageIcon("file.png");
    static Icon gifWarn = new ImageIcon("warn.gif");
    static Icon gifOk = new ImageIcon("ok.gif");
    static Icon gifNew = new ImageIcon("plus.gif");
    static Icon gifError = new ImageIcon("error.gif");

致电:

tree.setCellRenderer(new TreeRenderer());

渲染器:

private static class TreeRenderer extends DefaultTreeCellRenderer {


        public Component getTreeCellRendererComponent(JTree tree, Object value,
            boolean sel, boolean exp, boolean leaf, int row, boolean hasFocus) {

            super.getTreeCellRendererComponent(tree, value, sel, exp, leaf, row, hasFocus);
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
            String s = node.getUserObject().toString();
            String error;
            if (actualTree.equals("DOORS")){
                error = checkTypeError(s, valuesClass.listOfValuesDOORS);
                //System.out.println("DOORS - S: "+s);
            }else{
                error = checkTypeError(s, valuesClass.listOfValuesTC);
                //System.out.println("TC - S: "+s);
            }

            switch (error) {
                case "CORRECT":
                    setOpenIcon(openIcon);
                    setClosedIcon(closedIcon);
                    setLeafIcon(leafIcon);
                    break;
                case "CREATE":
                    setOpenIcon(gifNew);
                    setClosedIcon(gifNew);
                    setLeafIcon(gifNew);
                    break;
                case "DELETE":
                    setOpenIcon(gifError);
                    setClosedIcon(gifError);
                    setLeafIcon(gifError);
                    break;
                case "UPDATE":
                    setOpenIcon(gifWarn);
                    setClosedIcon(gifWarn);
                    setLeafIcon(gifWarn);
                    break;
                default:
                    setOpenIcon(openIcon);
                    setClosedIcon(closedIcon);
                    setLeafIcon(leafIcon);
                    //System.err.println("ERROR IN RENDERER. VALUE: "+error);
                    break;
            }

            return this;
        }

        /*****************************************
        * Function that return which error have the actual node to push the icon when the tree is created.
        *****************************************/
        protected static String checkTypeError(String txt, List<valuesClass> list){

            for (int i = 0; i < list.size(); i++) {
                if (list.get(i).text.equals(txt))
                    if (list.get(i).create == true){
                        return "CREATE";
                    }else if (list.get(i).delete == true){
                        return "DELETE";
                    }else if (list.get(i).update == true){
                        return "UPDATE";
                    }else{

                        return "CORRECT";
                    }
            }
            return "DEFAULT";
        }
    }

【问题讨论】:

    标签: java swing nodes jtree treecellrenderer


    【解决方案1】:

    您所描述的行为是由于您没有正确设置switch 语句中的节点图标造成的。 setOpenIcon()setClosedIcon() 等设置渲染器将用于整个树的图标。所以在最后一个节点中采取的行动将决定最后将呈现哪些图标。

    DefaultTreeCellRenderer 扩展了 JLabel。该组件将用于每个节点来呈现其内容。需要设置的是该组件的图标,即您的代码应如下所示:

    switch (error) {
      case "CORRECT":
           setIcon(leafIcon); // sets the icon of the renderer which is a JLabel
           break;
      case "CREATE":
           setIcon(gifNew);
           break;
      case "DELETE":
           setIcon(gifError);
           break;
      ...
    }
    

    请确保在所有情况下都设置图标,并确保您了解渲染器如何用于渲染树节点(所有节点都重复使用相同的实例)

    【讨论】:

    • 噢!惊人的!有用!现在我的树对每个案例都有不同的图标!现在我可以继续这个项目了! :> 我不能因为我的低声望给你声望,但你是大师 :P
    • 也许你可以接受这个答案,因为它对你有用:)
    【解决方案2】:

    Java 7 中的 switch 语句中允许使用字符串,虽然我还没有使用它们,但您的语法看起来是正确的。我怀疑错误字符串的值不是你所期望的。

    由于case值都是大写,所以换行

    switch (error) {
    

    switch (error.toUpperCase()) {
    

    看看能不能解决。如果不是,则打印出错误的值,或者使用调试器检查它的值。

    编辑:根据我们下面的讨论,我怀疑您的树节点是 DefaultMutableTreeNode 对象(对吗?)并且您将数据存储在用户对象中。

    在这种情况下,将值转换为 DefaultMutableTreeNode,然后提取数据:

    DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
    MyData myData = (MyData) node.getUserObject();
    

    然后您可以测试 myData 以确定要设置的图标。

    【讨论】:

    • 我正在使用 1.7 的库。 Switch 可以与字符串一起正常工作。
    • 可能我的错误在: String s = node.getUserObject().toString();我试图捕捉节点的文本,这个函数不正确。谁能告诉我如何提取实际节点的文本?
    • 是的,您需要从 value 参数中获取节点的内容。将其转换为您在树中存储的节点类型,然后获取它的值。
    • 我头晕目眩,无法清晰思考。你能帮我写代码吗?我找不到提取价值的方法。 >.
    • 树中存储了哪些数据,即如何创建节点?
    猜你喜欢
    • 2021-06-04
    • 2022-01-24
    • 2015-05-11
    • 2020-05-15
    • 2014-10-31
    • 2018-02-12
    • 2014-01-20
    • 2015-01-13
    • 2013-08-01
    相关资源
    最近更新 更多