How to expand JTree nodes (in advance), but keep them invisible

It seems to me that when I call

JTree.expandPath (path)

By default, all his parents are also extended. But what I really want to do is to establish certain invisible children that will be expanded in advance. Thus, when a node expands, its full subtree pops up.

I found that internally expandedState.put(path, Boolean.TRUE);extended nodes are written to JTree , but I cannot access it. (ps I do not want to use reflection :)

Setting a listener for an extension event will trigger a large number of run-time updates. Therefore, I prefer JTree to record advanced states.

Hope there are other ways to do this.
Any help is appreciated?

A decision has been made by the receiver. Option 2

Option 1 Override:

One nasty drawBack .. it depends 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;
}
+3
source share
2 answers

It will be easier for you to call

addTreeExpansionListener(TreeExpansionListener tel)

When a method is called treeExpanded(TreeExpansionEvent event)in your TreeExpansionListener, you can check if all child elements need to be recursively expanded for the newly extended TreePath.

+1
source

One easy way to do this is to 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 is why the method is protected :)

+1
source

Source: https://habr.com/ru/post/1720550/


All Articles