Search code examples
javaswingjtreetreemodel

Why isn't my JTree updating when the TreeModel adds new nodes?


I am using a DefaultTreeModel populated with an override of DefaultMutableTreeNode which supports optionally changing the display string of a node in a tree. As shown in the code below, in my form I populate the tree with new nodes by creating them in a separate class and then passing them in via a wrapper class for my main data type. The procedure there is to create a new overridden DefaultMutableTreeNode, add children to it (each AccessPoint is represented by a node with several child nodes), then store it for later use in the UI.

The first time I add a node this way, it works beautifully. Any subsequent node added with the following code is in fact stored in the DefaultTreeModel, but the JTree is not being updated with the new nodes.

Why is it that the JTree doesn't get populated after the first child is added?

private void populateAccessPointTreeModel(AccessPointDataWrapper wrapper) {
    //the pre-created DefaultMutableTreeNode subclass instance is
    // stored in the wrapper
    DefaultMutableTreeNode accessPointNode =
            wrapper.getAccessPointTreeNode();
    //this line updates the accessPointTree with the new node (I've looked at the
    // value in debug mode, and it does in fact add the node
    ((DefaultMutableTreeNode) accessPointTree.getRoot()).add(accessPointNode);
    //unrelated logic happens down here...
}

I can include the code where I create the node if necessary, but I don't think it is the issue.


Solution

  • The problem is that DefaultMutableTreeNode does not inform the DefaultTreeModel that its children were updated. To do this you'll either want to call the appropriate method in the table model (nodesChanged or similar) or (preferably) use the DefaultTreeModel.insertNodesInto method.

    DefaultTreeModel model = (DefaultTreeModel)accessPointTree.getModel();
    DefaultMutableTreeNode root = model.getRoot();
    model.insertNodeInto(accessPointNode, root, root.getChildCount());