I'm making a JTree and I have a button that removes a node from the tree. Everytime I removde the node with the button, the Tree automatically collapse. I've read that it's becasue I'm using .reload()
. I've also read some SO answers that suggested using .nodeChanged(node)
, which I've tried but when I use that, I believe the model is getting updated, but the tree doesn't reload accordingly in the GUI. How can I get the tree not to collapse?
Here's a simple SSCCE with the default JTree and a button to remove a node
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
public class StopTreeCollapse extends JApplet {
JTree tree = new JTree();
JButton jbtRemove = new JButton("Remove Node");
public StopTreeCollapse(){
add(new JScrollPane(tree), BorderLayout.CENTER);
add(jbtRemove, BorderLayout.SOUTH);
jbtRemove.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
TreePath[] paths = tree.getSelectionPaths();
if (paths == null) {
JOptionPane.showMessageDialog(null,
"No node in the tree is selected");
return;
}
DefaultMutableTreeNode node = null;
for (TreePath path : paths) {
node = (DefaultMutableTreeNode) (path.getLastPathComponent());
if (node.isRoot()) {
JOptionPane.showMessageDialog(null, "Cannot remove the root");
} else {
node.removeFromParent();
}
}
((DefaultTreeModel) tree.getModel()).reload();
}
});
}
}
reload()
essentially says "the whole tree may have changed, forget anything you previously knew about it and start again".Instead of using
node.removeFromParent()
and then reloading the whole tree, tryThis will fire a more specific modification event telling listeners that that particular node has been removed but the rest of the tree is unchanged, so you no longer require the
reload()
call.