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

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

Sort JTree Node To Always Stay First Or Last

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

Recently I wrote a post on how to sort JTree nodes alphabetically. But what if you want certain nodes that are equal to some words and you want them to always stay as the first and last node.

For example, I want to make the String “CARS” to always be the first node in the JTree and the String “HOUSE” to be the last while the rest of the tree nodes will be sorted alphabetically.

Using the value of the compare() method of the Comparator class, I did a dirty workaround to make this work with a little help from the Math class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public int compare(Object o1, Object o2) {
    int output = o1.toString().compareToIgnoreCase(o2.toString());
    if (o1.toString().equalsIgnoreCase("CARS")) {
        if (output > 0) {
            output = -Math.abs(output);
        }
    } else if (o2.toString().equalsIgnoreCase("CARS")) {
        if (output < 0) {
            output = Math.abs(output);
        }
    } else if (o1.toString().equalsIgnoreCase("HOUSE")) {
        if (output < 0) {
            output = Math.abs(output);
        }
    } else if (o2.toString().equalsIgnoreCase("HOUSE")) {
        if (output > 0) {
            output = -output;
        }
    }
}

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

Sort JTree

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

Sorting a JTree’s nodes is easy. Just make sure your nodes are of type DefaultMutableTreeNode. Have your class extend DefaultMutableTreeNode and add this code within the class. As you can see in the code, once a tree node is inserted into the tree, the nodes are sorted alphabetically using the Collections‘ sort method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Override
public void insert(MutableTreeNode newChild, int childIndex)    {
    super.insert(newChild, childIndex);
    Collections.sort(this.children, nodeComparator);
}
 
protected Comparator nodeComparator = new Comparator () {
    @Override
    public int compare(Object o1, Object o2) {
        return o1.toString().compareToIgnoreCase(o2.toString());
    }
 
    @Override
    @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
    public boolean equals(Object obj)    {
        return false;
    }
 
    @Override
    public int hashCode() {
        int hash = 7;
        return hash;
    }
};

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

Related Posts with Thumbnails