Avatar of XWL
XWL
 asked on

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

Open in new window

Java

Avatar of undefined
Last Comment
Mick Barry

8/22/2022 - Mon
Mick Barry

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.
 
Thank you for your quick response!

XWL

Mick Barry

i meant what is repopulating the tree?

Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
XWL

ASKER
I meant expanding the tree. The tree cannot expand any more after collapsing in that process all children nodes were removed.
Mick Barry

maybe I'm misiunderstanding, but if all the nodes have been removed then how can it expand?

XWL

ASKER
Is something wrong with the call to nodesWereRemoved in treeCollapsed? or setChildrenToNull? I don't know.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
XWL

ASKER
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..
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
Mick Barry

without seeing all of your tree code its a bit hard to help you.

XWL

ASKER
setChildrnToNull removes all children nodes. It is a pseudo-code here as it involved other data structure which is too much for this question.
Mick Barry

ok, that clears up some of my confusion.
well you should be clearing the children *before* firing the event.

⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
XWL

ASKER

I undstood it is hard.

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.
ASKER CERTIFIED SOLUTION
Mick Barry

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
XWL

ASKER
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.

All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
XWL

ASKER

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.