1

假设我正在编写一个可编辑的树文件系统并为我的“添加子”按钮添加一个动作监听器。也就是说,一旦我在树中选择了一个节点并单击“添加子节点”按钮。应该有一个新节点“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;
}
4

1 回答 1

1

这仅仅是因为 JTree 不使用您的模型。它使用从作为参数传递给树构造函数的根树创建的另一个模型。代替

m_tree = new JTree(root);

经过

m_tree = new JTree(m_model);
于 2014-10-26T09:39:45.323 回答