【问题标题】:How to expand JTree nodes (in advance), but keep them invisible如何扩展 JTree 节点(提前),但保持它们不可见
【发布时间】:2009-10-20 09:51:03
【问题描述】:

在我看来,当我打电话时

JTree.expandPath(路径)

默认情况下,它的所有父级也会展开。 但我真正想做的是,预先设置特定的隐形孩子进行扩展。这样当一个节点展开时,它的完整子树就会弹出。

我发现在 JTree expandedState.put(path, Boolean.TRUE); 内部记录了展开的节点,但我无法访问它。 (附:我不想使用反射:)

为扩展事件安装监听器会导致大量运行时更新被触发。这就是为什么我更喜欢让 JTree 记录扩展状态。

希望有其他方法可以做到这一点。
任何帮助表示赞赏?

接受 Listener 解决方案。选项 2

选项 1 覆盖:

一个讨厌的drawBack..它取决于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);
  }
}

选项 2 监听器

/* 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;
}

【问题讨论】:

    标签: java swing jtree expand


    【解决方案1】:

    你会更容易打电话

    addTreeExpansionListener(TreeExpansionListener tel)
    

    当调用 TreeExpansionListener 中的 treeExpanded(TreeExpansionEvent event) 方法时,您可以检查是否应该为新扩展的 TreePath 递归扩展所有子级。

    【讨论】:

    • 这是真的,但问题特别提到了这种方法,并询问是否有替代方法可以让树记录状态,而不是在事情扩展时触发大量更新。
    • 仍然是一个有效的答案。可能是他一直在我的路上......山姆,你呢?
    • 触发这些 TreeExpansionEvents 的开销将非常小,它们只会在节点展开或折叠时触发。代码也可能更简洁。
    • 实际上效果很好.. 我的问题中也包含了 Listener 解决方案
    • 实际上耗时更少 :) 因为我只需要访问新扩展节点的直接子节点,而不是所有传入/创建的树节点。
    【解决方案2】:

    一种简单的方法是继承 JTree 并覆盖该方法

    setExpandedState(TreePath path, boolean state)
    

    在此方法中,不是展开所有父路径,而是仅展开您要展开的子路径。 这正是该方法受到保护的原因:)

    【讨论】:

    • 我同意这会很方便,因为它受到保护,但是。 'expandedState' 变量是私有的 :( 但是......我认为我可以通过覆盖 'isExpanded()' 来逃避它的向上递归扩展,因为它用于构建待办事项堆栈:)
    • 私有静态类 MyTree 扩展 JTree { int rows[]; public MyTree(int rows[]) { this.rows = rows; } protected void setExpandedState(TreePath path, boolean state) { TreePath []paths = new TreePath[rows.length]; for (int i = 0; i
    • 好的,给你 :) 虽然你的解决方案不是我所需要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-23
    • 2010-10-05
    • 1970-01-01
    • 2011-12-10
    • 2017-12-31
    • 2011-08-20
    • 2012-06-08
    相关资源
    最近更新 更多