Функция insertNodeInto работает только при первой вставке (работает для конечного узла)

Скажем, я кодирую редактируемую древовидную файловую систему и добавляю прослушиватель действий для моей кнопки «добавить ребенка». То есть, как только я выбираю узел в дереве и нажимаю кнопку «Добавить ребенка». Должен появиться новый узел «New», который станет его дочерним элементом, как показано на рис.1.

(Извините, у меня нет 10 репутации для публикации изображений. Но, вероятно, вы можете запустить полный код, представленный ниже.)

Но дело в том, что мой слушатель работает только при первой вставке, а это значит, что он работает только для листового узла.

Когда я пытаюсь добавить новый узел в узел «Вещь», дерево не меняется. Хотя цифра не изменилась, возвращаемое значение функции .childCount () return действительно изменилось в соответствии с тем, что отображается на консоли.

    addChildButton.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent action)
        {
            DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) m_tree.
                getLastSelectedPathComponent();
            if (selectedNode == null)
            {
                System.out.println("selected null");
                return ;
            }
            DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New");
            System.out.println(selectedNode.getChildCount());
            m_model.insertNodeInto(newNode, selectedNode, 
                selectedNode.getChildCount());
            // display the new node
            m_tree.scrollPathToVisible(new TreePath(newNode.getPath()));
        }
    });

Для тех, кто хочет запустить программу, полный код находится здесь:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.tree.*;
public class TreeEditTest
{
    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                JFrame frame = new TreeEditFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

class TreeEditFrame extends JFrame
{
    public TreeEditFrame()
    {
        setTitle("TreeEditTest");
        setSize(M_DEFAULT_WIDTH, M_DEFAULT_HEIGHT);

        // construct tree
        TreeNode root = makeSampleTree();
        m_model = new DefaultTreeModel(root);
        m_tree = new JTree(root);
        m_tree.setEditable(true);
        // add scroll pane with tree
        JScrollPane scrollPane = new JScrollPane(m_tree);
        add(scrollPane, BorderLayout.CENTER);

        // make buttons
        makeButtons();  
    }

    private TreeNode makeSampleTree()
    {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Thing");
        DefaultMutableTreeNode pizza = new DefaultMutableTreeNode("Pizza");
        DefaultMutableTreeNode pizzaBase = new DefaultMutableTreeNode("PizzaBase");
        DefaultMutableTreeNode pizzaTopping = new DefaultMutableTreeNode("PizzaTopping");
        root.add(pizza);
        root.add(pizzaBase);
        root.add(pizzaTopping);
        DefaultMutableTreeNode deepPanBase = new DefaultMutableTreeNode("DeepPanBase");
        DefaultMutableTreeNode thinAndCrispyBase = new DefaultMutableTreeNode("ThinAndCrispyBase");
        pizzaBase.add(deepPanBase);
        pizzaBase.add(thinAndCrispyBase);

        return root;        
    }

    private void makeButtons()
    {
        JPanel panel = new JPanel();
        JButton addChildButton = new JButton("Add Child");      
        JButton addSiblingButton = new JButton("Add Sibling");
        JButton deleteButton = new JButton("Delete");
        addChildButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent action)
            {
                DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) m_tree.
                    getLastSelectedPathComponent();
                if (selectedNode == null)
                {
                    System.out.println("selected null");
                    return ;
                }
                DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New");
                System.out.println(selectedNode.getChildCount());
                m_model.insertNodeInto(newNode, selectedNode, 
                    selectedNode.getChildCount());

//              display the new node
                m_tree.scrollPathToVisible(new TreePath(newNode.getPath()));
            }
        });
        addSiblingButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent action)
            {
                DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) m_tree.
                    getLastSelectedPathComponent();
                if (selectedNode == null)
                {
                    System.out.println("selected null");
                    return ;
                }
                DefaultMutableTreeNode parent = (DefaultMutableTreeNode) selectedNode.
                    getParent();
                if (parent == null)
                {
                    System.out.println("parent null");                  
                    return ;
                }
                DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New");
                int selectedIndex = parent.getIndex(selectedNode);
//              System.out.println(parent.getChildCount());             
//              m_model.insertNodeInto(newNode, parent, parent.getChildCount());
                System.out.println(selectedIndex+1);
                m_model.insertNodeInto(newNode, parent, selectedIndex+1);

                // now display the new node
                TreeNode[] nodes = m_model.getPathToRoot(newNode);
                TreePath path = new TreePath(nodes);
                m_tree.scrollPathToVisible(path);
            }
        });
        deleteButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent action)
            {
                DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) m_tree.
                    getLastSelectedPathComponent();
                if (selectedNode == null)
                {
                    System.out.println("selected null");
                    return ;
                }
                DefaultMutableTreeNode parent = (DefaultMutableTreeNode) selectedNode.
                    getParent();
                if (parent == null)
                {
                    System.out.println("Cannot delete the \"Thing\" node");
                    return ;
                }
                m_model.removeNodeFromParent(selectedNode);
            }
        });
        panel.add(addChildButton);
        panel.add(addSiblingButton);
        panel.add(deleteButton);

        add(panel, BorderLayout.NORTH);
    }

    private DefaultTreeModel m_model;
    private JTree m_tree;
    private static final int M_DEFAULT_WIDTH = 400;
    private static final int M_DEFAULT_HEIGHT = 200;
}

person stephen_wang    schedule 26.10.2014    source источник


Ответы (1)


Это просто потому, что JTree не использует вашу модель. Он использует другую модель, которую он создает из корневого дерева, которое вы передали в качестве аргумента конструктору дерева. Заменять

m_tree = new JTree(root);

by

m_tree = new JTree(m_model);
person JB Nizet    schedule 26.10.2014
comment
Большое спасибо! Мне все еще интересно, почему этот добавленный дочерний слушатель работает для листового узла; ) - person stephen_wang; 26.10.2014