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