Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
}
like image 917
Houtman Avatar asked Dec 30 '25 15:12

Houtman


2 Answers

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.

like image 175
Sam Barnum Avatar answered Jan 01 '26 04:01

Sam Barnum


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 :)

like image 40
Suraj Chandran Avatar answered Jan 01 '26 04:01

Suraj Chandran



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!