Save JTree Tree Node State

1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5.00 out of 5)
Loading ... Loading ...

The JTree class does not have a means to save a tree node’s state (e.g. expanded of collapsed). I did come across a forum where a post mentioned about the use of a TreeExpansionListener to save a tree node’s state and provided a short sample snippet. I modified some minor bugs and the code below is the finished and modified code.

Say you want to add a new tree node, you do not want the JTree to refresh all its tree nodes’ expanded state to collapsed. Rather, the previous state will still be the same even when a new tree node is added to the JTree. You can call the method jTree1.restoreExpansionState() to restore it and jTree1.resetExpansionState() to reset all the state to collapsed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public class MyJTree extends JTree {
    private List expandedTreeObjects;
    public LinkedHashMap treepaths;
    private boolean supressExpansionEvent;
    private DefaultMutableTreeNode root;
 
    public My JTree(DefaultMutableTreeNode root) {
        // create root of tree
        this.root = root;
        setModel(new DefaultTreeModel(root));
 
        expandedTreeObjects = new LinkedList();
        treepaths = new LinkedHashMap();
 
        // add expansion listener to preserve expansion state of each node
        addTreeExpansionListener(new TreeExpansionListener() {
            @Override
            public void treeExpanded(TreeExpansionEvent event) {
                processTreeExpansion(event);
            }
 
            @Override
            public void treeCollapsed(TreeExpansionEvent event) {
                processTreeCollapse(event);
            }
        });
    }
 
    public void expandRoot() {
        //expand path to root
        expandPath(new TreePath(((DefaultMutableTreeNode) ((DefaultTreeModel) getModel()).getRoot()).getPath()));
    }
 
    private void restoreTreeNode(JTree tree, TreePath parent, DefaultMutableTreeNode treeNode) {
        // Traverse down through the children
        TreeNode node = (TreeNode) parent.getLastPathComponent(); // Get the last TreeNode component for this path
 
        if (node.getChildCount() >= 0) { // If the node has children?
            // Create a child numerator over the node
            Enumeration en = node.children();
            while (en.hasMoreElements()) { // While we have children
                DefaultMutableTreeNode dmTreeNode = (DefaultMutableTreeNode)en.nextElement(); // Derive the node
                TreePath path = parent.pathByAddingChild(dmTreeNode); // Derive the path
                restoreTreeNode(tree, path, dmTreeNode); // Recursive call with new path
 
            } // End While we have more children
        } // End If the node has children?
 
        // Nodes need to be expand from last branch node up
        if (treeNode != null) { // If true, this is the root node - ignore it
            String myString = new TreePath(treeNode.getPath()).toString();
 
            if (expandedTreeObjects.contains(myString)) { // Is this present on the previously expanded list?
                tree.expandPath(parent); // et viola
            }
        }
    }
 
    private void processTreeExpansion(TreeExpansionEvent e){
 
        if (supressExpansionEvent == false) {
            TreePath p = (TreePath) e.getPath();
            expandedTreeObjects.add(p.toString());
        }
 
    }
 
    private void processTreeCollapse(TreeExpansionEvent e){
        TreePath p = (TreePath) e.getPath();
        expandedTreeObjects.remove(p.toString());
    }
 
    public void restoreExpansionState() {
        supressExpansionEvent = true;
 
        ((DefaultTreeModel) getModel()).reload();
        restoreTreeNode(this, new TreePath(root), null);
 
        supressExpansionEvent = false; // Now we can go back to responding normally to expansion events
    }
 
    public void resetExpansionState() {
        expandedTreeObjects.clear();
    }
 
}
Bookmark and Share

Found this post useful? Buy me a cup of coffee or help support the sponsors on the right.

Related Posts with Thumbnails

tags: , , , ,

2 Responses to “Save JTree Tree Node State”

  1. 1
    Ambar Says:

    it’s great artikel, I will try..
    tx..

  2. 2
    Ygs Says:

    this was so necessary for me, thank you very much

Leave a Reply