TreeModelListener not responding to changes in TreeModel which it subscribes to

I'm having some bother understanding why I cannot get a TreeModelChanged listener to respond to changes in the model which it subscribes to.

I have managed to reproduce the problem in a small example.

The SysOut message does not print to the console whenever a new node is added to the tree.

I intend to replace the SysOut message with some commands to redraw the tree. At the moment I am using a SysOut message just to prove that the listener is not being fired.

Am I missing something fundamental?

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;


public class TreeTest {

    private JTree t;
    private DefaultTreeModel m ;

    public static void main(String[] args) {
         new TreeTest();

    }

    public TreeTest() {

        //Draw Frame & Panel  - set dimensions
        JFrame f = new JFrame();
        f.setSize(new Dimension(800,600));
        JPanel p = new JPanel();
        p.setSize(new Dimension(800,600));



        //Create a Tree Model. Give it a String at the root.
        m = new DefaultTreeModel(new DefaultMutableTreeNode("Root"));

        //Create a tree and add the Model to it
        t = new JTree();
        t.setModel(m);


        //Try a Tree Model Listener
        m.addTreeModelListener(new TreeModelListener() {

            private void doSomething() {
                //Should fire whenever a node is added to the model
                System.out.println("Responding to TreeModelListener");
            }
            @Override
            public void treeStructureChanged(TreeModelEvent e) {
                doSomething();

            }

            @Override
            public void treeNodesRemoved(TreeModelEvent e) {
                doSomething();

            }

            @Override
            public void treeNodesInserted(TreeModelEvent e) {
                doSomething();

            }

            @Override
            public void treeNodesChanged(TreeModelEvent e) {
                doSomething();

            }
        });     

        //Add listener to a button which adds nodes to the tree when clicked
        JButton addNode = new JButton("Add node");
        addNode.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("New Node");
                DefaultMutableTreeNode root = (DefaultMutableTreeNode) m.getRoot();
                root.add(newNode);
            }
        });

        JScrollPane s = new JScrollPane(t);


        p.add(s);
        p.add(addNode);

        p.setVisible(true);
        f.add(p);
        f.setVisible(true);
    }

}

Answers


that's because the model doesn't know about the addition, it happens under its feet. Use the methods on DefaultTreeModel to do the insertion:

model.insertNodeInto(newNode, root, root.getChildCount())

Edit

a TreeNode is just a (more or less) dumb data structure. As you can see in the api, it's not an Observable, so there is no way for the model which uses that data structure to detect if anything changed on the node. To make it aware of the change, you have to do one of two things

  • use the node manipulation methods of the model
  • update the node and notify the model manually (calling nodesWereInserted)

The first is the preferable way (keeps control where it belongs), the second might be needed in more complex contexts (though I would strongly recommend to never do it, that's why SwingX DefaultTreeTableModel doesn't have them exposed :)


Need Your Help

Algorithm to calculate the number of divisors of a given number

performance algorithm pseudocode

What would be the most optimal algorithm (performance-wise) to calculate the number of divisors of a given number?

Dropdown jQuery not performing

php jquery codeigniter

This script is ran when the user clicks on a dropdown and makes a different selection and then changes the session key called defaultCharacterID and I'm tyring to figure out when it brings up the p...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.