How to get JTree to load all its nodes after some nodes are removed in collaspe event?
Hi All,
I am having a problem to expand my JTree object after the component has been collapsed (some nodes have been removed). Basically, I have my on JTree derived class LazyLoadedTree. the class removes children nodes of selected node when it collapses; in an event of collapse, called nodesWereRemoved and set all children nodes to null. Problem is that the tree loses all its children nodes when it expands.
My question is why the tree does not reload all its node when it is expend?
Thank you,
XWL
public class LazyLoadedTree extends JTree { /* Creates new LazyLoadedTree based on a TreeModel */ public LazyLoadedTree(TreeModel model) { super(model); addTreeExpansionListener(new CollapseHandler()); } class CollapseHandler implements TreeExpansionListener { // Do nothing in treeExpand method public void treeExpanded(TreeExpansionEvent event) { } /** Remove children notes when a node is collapsed */ public void treeCollapsed(TreeExpansionEvent event) { TreeNode node = (TreeNode) event.getPath().getLastPathComponent(); int childIndices[] = new int[node.getChildCount()]; Object[] removedChildren = new Object[node.getChildCount()]; for(int x = 0; x < node.getChildCount(); x++) { childIndices[x] = x; removedChildren[x] = node.getChildAt(x); } // Remove the children notes and send them to gabage collection getModel().nodesWereRemoved(node, childIndices, removedChildren); // this method sets all children node to null SetChidrenToNull (node); } }// End of class CollapseHandler}// End of class LazyLoadedTree
why should it reload them? What is doing the reloading?
XWL
ASKER
Hi objects,
When I say "reloading" means expanding. After collapsing, the tree cannot expand any more. If I click "+" sign at root, it display a "-", no any other node displays. if the "-" sign is clicked again, An java.lang.ArrayIndexOutOfBoundsException will be thrown at DefaultMutableTreeNode.getChildAt(int index).
To your question, "What is doing the reloading?", well, If it means DefaultTreeModel.reload method, the method fires tree structure changed event to all interested listeners. This way, the tree is able to get all its node data from data source and expanded. Actually, if I call getModel().reload() in treeExpanded(TreeExpansionEvent event) method, which currently does nothing, the problem will gone.
I need to fully understand how the tree expands when the + sign is clicked. In my case, it seems my tree does not re-populate all its children notes automatically, which I suppose it should.
if all the nodes have been removed then how can it expand?
- That is my question too. If I removed all children in my own class, should I expect JTree/DefaultTreeModel know how to get them back in a tree expend event as if it was initially loaded?
Mick Barry
am getting more confused :) looking at the code it appears to be firing an event that all nodes have been removed but I don't see your code that actually removes them.
And then you seem to be expecting the nodes to again be there when you expand the node. I don't understand
XWL
ASKER
As I have a solution to this problem: just do this (currently, it does nothing):
public void treeExpanded(TreeExpansionEvent event) {
getModel().reload(node);
}
However, I am afraid it is an extra and is harmful to JTree/Model mechanism..
Actually, my question is this: if I removed children nodes in a tree collapse event in my own class *correctly*, shall I expect the JTree/DefaultTreeModel know how to get them back in a tree expend event as if it was initially loaded?
With the answer, I can judge whether or not I should try to find bug in code of removing the children nodes or call getModel().reload in treeExpanded event handler.
Thank you, I will fellow the direction that you pointed. It looks like there are two problematics parts in my code: 1) I should remove children nodes before fire the event, 2) setChirldrenToNull ( it does what its name says) is not real removal?
Also, can you explain a bit more about "leave the node in a state that it is identified as an unloaded node, and not a node with no children"? I am not sure fully understand this.
Thank you for your patience!
Mick Barry
If you are dymnamically loading I assume you have some way of telling which nodes have been loaded and which haven't.
In my code, method treeCollapsed of class CollapseHandler, I did this:
static enum LoadState {Loaded, Loading, NotLoaded};
... ...
((javax.swing.tree.DefaultMutableTreeNode)node).removeAllChildren();
getModel().nodesWereRemoved(node, childIndices, removedChildren);
node.setLoadState(LoadState .NotLoaded);
After the tree collapsed, if "+" sign of root node of the tree is clicked. the tree is not able to expand as there is no children node any more. Could anyone tell me why and what is missing?
Thank you,
XWL
Mick Barry
hard ti tell, check why the load isn't getting triggered.