stephen_wang
stephen_wang

Reputation: 31

insertNodeInto function only works in first insertion (works for leaf node)

Say I'm coding for an editable tree file system and adding an action listener for my "add child" button. That is, once I select a node in the tree and click the "Add child" button. There should be a new node "New" becoming its child, which was showed in Fig.1.

(Sorry I don't have 10 reputation to post images.. But probably you can run the complete code below.)

But the thing is my listener only works in first insertion, which means it only works for leaf node.

When I'm trying to add a new node into "Thing" node, the tree doesn't change. While the figure didn't change, the return value of .childCount() function return did change according to what the console display.

    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()));
        }
    });

For the ones who want to run the program, the complete code is here:

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;
}

Upvotes: 1

Views: 432

Answers (1)

JB Nizet
JB Nizet

Reputation: 692121

That's simply because the JTree doesn't use your model. It uses another model it creates from the root tree you passed as argument to the tree constructor. Replace

m_tree = new JTree(root);

by

m_tree = new JTree(m_model);

Upvotes: 1

Related Questions