【问题标题】:Change name of a TreeNode without changing the userObject更改 TreeNode 的名称而不更改 userObject
【发布时间】:2015-12-06 12:42:59
【问题描述】:

我有一个带有 DefaultTreeModel 和一些 DefaultMutableTreeNodes 的 JTree。
我正在寻找一种方法来更改节点的 displayName,但我不想更改 userObject,因为我需要它完全符合它的设置。
此外,我不能简单地覆盖我的 userObject 的 toString 方法,因为我在代码中的其他地方使用了 toString,而对此方法的相应更改将是不合适的。

那么问题是,是否有可能在上述条件下实现节点的重命名?

提前致谢
乌鸦

编辑: 一个小代码示例:

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultMutableTreeNode;

public class TreeNodeRenameExample extends JFrame {

    private JPanel  contentPane;
    private JTree tree;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TreeNodeRenameExample frame = new TreeNodeRenameExample();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public TreeNodeRenameExample() {
        initGUI();
    }
    private void initGUI() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        this.contentPane = new JPanel();
        this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        this.contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(this.contentPane);
        {
            this.tree = new JTree();
            this.tree.setModel(new DefaultTreeModel(
                new DefaultMutableTreeNode("JTree") {
                    {
                        add(new DefaultMutableTreeNode(new testObj("Peter")));
                        add(new DefaultMutableTreeNode(new testObj("Stephen")));
                    }
                }
            ));
            this.contentPane.add(this.tree, BorderLayout.CENTER);
        }
    }

    public class testObj {
        private String name;

        public testObj(String name) {
            this.name = name;
        }

        public String toString() {
            return "Name: " + this.name;
        }
    }

}

我想做的是将 TreeNodes 上的文本更改为不同的内容。例如“MyTreeNode1”和“MyTreeNode2”,但我想保留这两个节点的userObject,我的testObj和toString方法也不能改变......

【问题讨论】:

  • 也许你应该发布你的代码。 Take a look at this
  • 显示我所有条件的完整代码太长了,一小部分只会说我的描述,因为它或多或少是一个一般性问题,而不是真正依赖于我的代码使用
  • 但如果你愿意,我会给你一个小例子......

标签: java swing jtree treenode


【解决方案1】:

如果您想为树用户对象使用TestObj 类并且不想更改toString 方法,您可以使用自定义TreeNode 类(而不是DefaultMutableTreeNode 类)。使用这个自定义类,toString 方法可以被重写为不(总是)使用用户对象,而是使用替代名称。

例如,自定义 TreeNode 类可以称为 AliasTreeNode,并且可以在创建节点时或稍后在某些事件发生时接收别名(= 替代节点名称)。 AliasTreeNode.toString 方法检查是否设置了别名;如果有别名则返回 this,否则返回 DefaultMutableTreeNode.toString()

您的代码的此修改版本演示了该方法。节点在构造时获得别名,在按下按钮时获得不同的别名:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.*;

public class TreeNodeRenameExample extends JFrame {

    private JPanel  contentPane;
    private JTree tree;

    private AliasTreeNode peterNode = new AliasTreeNode(new TestObj("Peter"),
                                                        "Alias 1");
    private AliasTreeNode stephenNode = new AliasTreeNode(new TestObj("Stephen"),
                                                          "Alias 2");

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TreeNodeRenameExample frame = new TreeNodeRenameExample();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public TreeNodeRenameExample() {
        initGUI();
    }
    private void initGUI() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        this.contentPane = new JPanel();
        this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        this.contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(this.contentPane);
        {
            this.tree = new JTree();
            this.tree.setModel(new DefaultTreeModel(
                    new DefaultMutableTreeNode("JTree") {
                        {
                            add(peterNode);
                            add(stephenNode);
                        }
                    }
            ));
            this.contentPane.add(this.tree, BorderLayout.CENTER);

            JButton changeNamesButton = new JButton("Change node names");
            this.contentPane.add(changeNamesButton, BorderLayout.SOUTH);
            changeNamesButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    peterNode.setAlias("MyTreeNode1");
                    stephenNode.setAlias("MyTreeNode2");
                }
            });
        }
    }


    public class TestObj {
        private String name;

        public TestObj(String name) {
            this.name = name;
        }

        public String toString() {
            return "Name: " + this.name;
        }
    }


    public class AliasTreeNode extends DefaultMutableTreeNode {
        private String alias;

        public AliasTreeNode(Object userObject, String alias) {
            super(userObject);
            this.alias = alias;
        }

        public void setAlias(String alias) {
            this.alias = alias;

            // Notify the tree model of the changed node
            // (see http://stackoverflow.com/a/10375802/1694043).
            ((DefaultTreeModel) tree.getModel()).nodeChanged(this);
        }

        @Override
        public String toString() {
            return (alias != null) ? alias : super.toString();
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    • 2020-10-06
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多