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