【发布时间】:2010-10-24 07:50:54
【问题描述】:
我有一个用TreeModel 表示的数据对象,我想在我的JTree 中只显示它的一部分——为了争论,说树叶和他们的父母。如何隐藏/过滤不必要的节点?
【问题讨论】:
-
这是一个过时且信息量较少的线程,而不是此副本:stackoverflow.com/questions/9234297/filtering-on-a-jtree
我有一个用TreeModel 表示的数据对象,我想在我的JTree 中只显示它的一部分——为了争论,说树叶和他们的父母。如何隐藏/过滤不必要的节点?
【问题讨论】:
我的最终实现:
TreeModels,一个是底层的,一个是过滤的。TreeModel 发生更改时,从头开始重建过滤的TreeModel。克隆每个应该可见的节点,并将其添加到过滤后的TreeModel 中的第一个可见祖先(如果不可见,则添加到根)。如果您好奇,请参阅下面的 codez。这有一个不幸的副作用,就是折叠用户打开的每条路径。为了解决这个问题,我在过滤后的TreeModel 中添加了一个TreeModelListener。当模型发生变化时,我将展开的路径保存在JTree(使用getExpandedDescendants())中,然后稍后重新展开(使用SwingUtilities.invokeLater())。
我必须在我正在使用的TreeNode 类中覆盖equals(),以便新的克隆节点与旧的克隆节点相同。
...
populateFilteredNode(unfilteredRoot, filteredRoot);
...
void populateFilteredNode(TreeNode unfilteredNode, TreeNode filteredNode)
{
for (int i = 0; i < unfilteredNode.getChildCount(); i++)
{
TreeNode unfilteredChildNode = unfilteredNode.getChildAt(i);
if (unfilteredChildNode.getType() == Type.INVISIBLE_FOLDER)
{
populateFilteredNode(unfilteredChildNode, filteredNode);
}
else
{
TreeNode filteredChildNode = unfilteredChildNode.clone();
filteredNode.add(filteredChildNode);
populateFilteredNode(unfilteredChildNode, filteredChildNode);
}
}
}
【讨论】:
您应该知道GlazedLists。这是一个很棒的库,可以轻松进行复杂的表转换。它们也扩展到树木。可能需要对现有代码进行一些重构才能使其进入 GlazedLists 的工作方式。但请查看演示和网络广播,了解它的强大功能。 (在我看来,它是必不可少的 Swing 库之一,而且它是开源的。)
【讨论】:
你试过JXTree 吗? (不幸的是,该网站现在已关闭,但您可以谷歌寻找镜像)
【讨论】:
看看这个实现:http://www.java2s.com/Code/Java/Swing-Components/InvisibleNodeTreeExample.htm
它创建 DefaultMutableNode 的子类,添加一个“isVisible”属性,而不是实际从 TreeModel 中删除/添加节点。
【讨论】:
如果您正在寻找商业解决方案,JideSoft 有一个可过滤的树模型。除此之外,SwingX 有一个过滤器 API,可用于 JXTable、JXTreeTable、JXTree 和 JXList。
【讨论】:
只要它仍然是您正在显示的树,那么过滤您现有的TreeModel 的TreeModel 应该足够简单。
【讨论】:
利用您用于构建 TreeNode 的代码并重建 TreeNode(仅包括您想要的元素)。用过滤后的根节点设置 TreeModel 上的根节点。
【讨论】: