Изменить имя TreeNode без изменения userObject

У меня есть JTree с DefaultTreeModel и несколькими прикрепленными к нему DefaultMutableTreeNodes.
Я ищу способ изменить displayName узла, но я не хочу менять userObject, потому что мне нужно, чтобы он был именно таким, каким он был. set to.
Кроме того, я не могу просто переопределить метод toString для моего userObject, потому что я использую toString в другом месте своего кода, где соответствующие изменения в этом методе были бы неуместными.

Итак, вопрос в том, можно ли добиться переименования узла с указанными выше условиями?

Заранее спасибо
Рэйвен

EDIT: небольшой пример кода:

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», но я хочу оставаться пользовательским объектом этих двух узлов, мой testObj и метод toString также не могут быть изменены...


person Raven    schedule 06.12.2015    source источник
comment
Может быть, вы должны опубликовать свой код. Посмотрите на это   -  person Yassin Hajaj    schedule 06.12.2015
comment
Мой полный код, который показывает все мои условия, был бы слишком длинным, а небольшая часть не говорила бы ничего, кроме моего описания, поскольку это более или менее общий вопрос, чем действительно зависит от кода, который я использую   -  person Raven    schedule 06.12.2015
comment
но если хотите, я приведу вам небольшой пример...   -  person Raven    schedule 06.12.2015


Ответы (1)


Если вы хотите использовать класс TestObj для пользовательских объектов дерева и не хотите изменять метод toString, вы можете использовать собственный класс TreeNode (вместо класса DefaultMutableTreeNode). Используя этот пользовательский класс, метод toString может быть переопределен, чтобы не использовать (всегда) пользовательский объект, а вместо этого использовать альтернативное имя.

Пользовательский класс TreeNode может, например, называться AliasTreeNode и может получать псевдоним (= альтернативное имя узла) при создании узла или позже, когда происходит какое-либо событие. Метод AliasTreeNode.toString проверяет, установлен ли псевдоним; если есть псевдоним, это возвращается, иначе возвращается 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();
        }
    }
}
person Freek de Bruijn    schedule 06.12.2015