How to expand JTree nodes (in advance), but keep them invisible
문제
I seems to me that when i call
JTree.expandPath( path )
That by default all its parents are expanded as well. But what i actually want to do is, set up specific invisible children to be expanded in advance. So that when a node is expanded that its complete sub-tree pops-out.
I've found that internally in JTree expandedState.put(path, Boolean.TRUE);
records the expanded nodes, but i can't get access to it. (p.s. i don't want to use reflection :)
Installing listener for the expansion event, would result in a lot of run-time updates beeing fired. That's why i prefer to let JTree record the expanded states.
Hope that there are other ways of doing it.
Any help is appreciated?
Accepted the Listener solution. Option 2
Option 1 Overriding :
One nasty drawBack..it is depending on the implementation of setExpandedState()
private boolean cIsExpandingHidden = false;
private TreePath cExpandingPath;
public void expandBranchHidden(DefaultMutableTreeNode node) {
TreeNode[] mPathSections = mNode.getPath();
TreePath mPath = new TreePath(mPathSections);
//
if (!cTree.isVisible(mPath)){
cIsExpandingHidden = true;
}
cExpandingPath = mPath;
try{
expandPath(mPath);
}finally{
cExpandingPath = null;
cIsExpandingHidden = false;
}
}
@Override
public boolean isExpanded(TreePath path) {
// override the questions whether the node parents of
// 'the currently expanded node' to return TRUE
if (cIsExpandingHidden){
if (path.isDescendant(cExpandingPath)){
return true; // just claim it doesn't need expanding
}
}
return super.isExpanded(path);
}
@Override
public void fireTreeExpanded(TreePath path) {
// the treeUI must not to know.. bad luck for any other listeners
if (!cIsExpandingHidden){
super.fireTreeExpanded(path);
}
}
Option 2 Listener
/* code where new nodes are received */
{
// only if direct parent is expanded.. else expansionListener will pick it up
if (cTree.isExpanded(mCreator.getParentTreeNode())){
for (TreeNode mNode : mAddNodes) {
if (mNode.isDefaultExpanded()) {
cTree.expandBranch(mNode);
mNode.setDefaultExpanded(false);
}
}
}
}
/* expansion listener */
{
if (cRecursiveExpand){
return;
}
// walk through children, expand and clear its preference
cRecursiveExpand = true;
IExtendedTreeNode[] mNodes = cTree.getChildrenOfCurrentNode();
for (IExtendedTreeNode mNode : mNodes) {
TreeNode mTreeNode = (TreeNode)mNode;
if (mTreeNode.isDefaultExpanded()){
cTree.expandBranch(mTreeNode);
mTreeNode.setDefaultExpanded(false);
}
}
cRecursiveExpand = false;
}
해결책
You'll have an easier time calling
addTreeExpansionListener(TreeExpansionListener tel)
When the treeExpanded(TreeExpansionEvent event)
method in your TreeExpansionListener gets called, you can check to see if you should recursively expand all children for the newly expanded TreePath.
다른 팁
One easy way of doing it is subclass JTree and override the method
setExpandedState(TreePath path, boolean state)
In this method instead of expanding all parents, expand only the subpaths that you want to expand. That's exactly why the method is protected :)