5

我正在编写一个 Java 树,其中树节点的子节点可能需要很长时间来计算(在这种情况下,它是一个文件系统,其中可能存在网络超时,从而阻止从连接的驱动器获取文件列表)。

我发现的问题是:

  1. getChildCount()在用户特别请求打开树的特定分支之前调用。我相信这样做是为了JTree知道是否在节点旁边显示 + 图标。

  2. 准确计数来自的孩子getChildCount()需要执行潜在的昂贵操作

  3. 如果我伪造 的值getChildCount(),那么在请求枚举子节点之前,树只会为那么多子节点分配空间。(如果我返回“1”,我只会看到列出的 1 个孩子,尽管还有更多)

孩子的枚举可能既昂贵又耗时,我可以接受。但我不getChildCount()同意需要知道孩子的确切数量。

有什么办法可以解决这个问题吗?

补充:另一个问题是,如果其中一个节点代表一个软盘驱动器(多么古老!),驱动器将在用户请求其文件之前被轮询;如果驱动器中没有磁盘,则会导致系统错误。

更新:不幸的是,实现TreeWillExpand监听器不是解决方案。这可以让您否决扩展,但显示的节点数仍受TreeNode.getChildCount().

4

4 回答 4

3

http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html#data

向下滚动一点,这里有关于如何为 jtree 创建延迟加载节点的确切教程,并附有示例和文档

于 2008-09-30T21:50:46.863 回答
0

我不确定它是否完全适用,但我最近通过预先计算通常需要遍历子列表的方法的答案来解决树慢的问题。我只在添加、删除或更新孩子时重新计算它们。在我的例子中,一些方法必须递归地沿着树向下走,以找出每个节点的“存储了多少字节”之类的东西。

于 2008-09-30T20:16:42.470 回答
0

如果您需要大量访问计算成本高昂的数据结构的特定功能,那么预先计算它可能是有意义的。

在 TreeNode 的情况下,这意味着您的 TreeNode 必须存储它们的 Child 计数。更详细地解释一下:当你创建一个节点时,n0这个节点的 childcount ( cc) 为 0。当你添加一个节点n1作为这个节点的子节点时,你n1.cc + cc++.

棘手的一点是删除操作。您必须保持与父级的反向链接并向上层级减去cc当前节点的。

如果您只想hasChildren为您的节点或覆盖提供 a 功能getChildCount,则布尔值可能就足够了,并且不会强迫您在被删除的情况下上升整个层次结构。或者您可以删除反向链接,只是说您在删除操作上失去了精度。该TreeNode界面实际上并不强制您提供删除操作,但您可能还是想要一个。

好吧,就是这样。为了得出预先计算的精确值,您必须保留某种反向链接。如果你不这样做,你最好调用你的方法hasHadChildren或更有趣的方法isVirgin

于 2008-09-30T20:57:01.127 回答
0

解决方案有几个部分:

  • 就像 Lorenzo Boccaccia 所说,使用TreeWillExpandListener

  • 另外,需要在树上调用nodesWereInserted,这样会显示正确数量的节点。 看到这个代码

  • 我已经确定,如果你不知道孩子的数量,TreeNode.getChildCount() 至少需要返回 1(它不能返回 0)

于 2008-10-01T19:42:11.187 回答