Java TreeNode:如何防止getChildCount执行昂贵的操作?

时间:2021-04-20 12:33:26

I'm writing a Java Tree in which tree nodes could have children that take a long time to compute (in this case, it's a file system, where there may be network timeouts that prevent getting a list of files from an attached drive).

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

The problem I'm finding is this:

我发现的问题是:

  1. getChildCount() is called before the user specifically requests opening a particular branch of the tree. I believe this is done so the JTree knows whether to show a + icon next to the node.

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

  2. An accurate count of children from getChildCount() would need to perform the potentially expensive operation

    来自getChildCount()的子项的准确计数将需要执行可能昂贵的操作

  3. If I fake the value of getChildCount(), the tree only allocates space for that many child nodes before asking for an enumeration of the children. (If I return '1', I'll only see 1 child listed, despite that there are more)

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

The enumeration of the children can be expensive and time-consuming, I'm okay with that. But I'm not okay with getChildCount() needing to know the exact number of children.

孩子们的列举可能既昂贵又耗时,我对此感到满意。但我不满意getChildCount()需要知道孩子的确切数量。

Any way I can work around this?

我可以用任何方式解决这个问题吗?

Added: The other problem is that if one of the nodes represents a floppy drive (how archaic!), the drive will be polled before the user asks for its files; if there's no disk in the drive, this results in a system error.

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

Update: Unfortunately, implementing the TreeWillExpand listener isn't the solution. That can allow you to veto an expansion, but the number of nodes shown is still restricted by the value returned by TreeNode.getChildCount().

更新:不幸的是,实现TreeWillExpand侦听器不是解决方案。这可以允许您否决扩展,但显示的节点数仍然受TreeNode.getChildCount()返回的值的限制。

4 个解决方案

#1


3  

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

scroll a little down, there is the exact tutorial on how to create lazy loading nodes for the jtree, complete with examples and documentation

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

#2


0  

I'm not sure if it's entirely applicable, but I recently worked around problems with a slow tree by pre-computing the answers to methods that would normally require going through the list of children. I only recompute them when children are added or removed or updated. In my case, some of the methods would have had to go recursively down the tree to figure out things like 'how many bytes are stored' for each node.

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

#3


0  

If you need a lot of access to a particular feature of your data structure that is expensive to compute, it may make sense to pre-compute it.

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

In the case of TreeNodes, this means that your TreeNodes would have to store their Child count. To explain it a bit more in detail: when you create a node n0 this node has a childcount (cc) of 0. When you add a node n1 as a child of this one, you n1.cc + cc++.

对于TreeNodes,这意味着您的TreeNodes必须存储其子计数。更详细地解释一下:当你创建一个节点n0时,这个节点的子计数(cc)为0.当你添加一个节点n1作为这个节点的子节点时,你就是n1.cc + cc ++。

The tricky bit is the remove operation. You have to keep backlinks to parents and go up the hierarchy to subtract the cc of your current node.

棘手的一点是删除操作。您必须保持对父项的反向链接,并向上移动层次结构以减去当前节点的cc。

In case you just want to have the a hasChildren feature for your nodes or override getChildCount, a boolean might be enough and would not force you to go up the whole hierarchy in case of removal. Or you could remove the backlinks and just say that you lose precision on remove operations. The TreeNode interface actually doesn't force you to provide a remove operation, but you probably want one anyway.

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

Well, that's the deal. In order to come up with precomputed precise values, you will have to keep backlinks of some sorts. If you don't you'd better call your method hasHadChildren or the more amusing isVirgin.

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

#4


0  

There are a few parts to the solution:

该解决方案有几个部分:

  • Like Lorenzo Boccaccia said, use the TreeWillExpandListener

    就像Lorenzo Boccaccia所说,使用TreeWillExpandListener

  • Also, need to call nodesWereInserted on the tree, so the proper number of nodes will be displayed. See this code

    此外,需要在树上调用nodesWeresert,因此将显示适当数量的节点。看到这段代码

  • I have determined that if you don't know the child count, TreeNode.getChildCount() needs to return at least 1 (it can't return 0)

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

#1


3  

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

scroll a little down, there is the exact tutorial on how to create lazy loading nodes for the jtree, complete with examples and documentation

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

#2


0  

I'm not sure if it's entirely applicable, but I recently worked around problems with a slow tree by pre-computing the answers to methods that would normally require going through the list of children. I only recompute them when children are added or removed or updated. In my case, some of the methods would have had to go recursively down the tree to figure out things like 'how many bytes are stored' for each node.

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

#3


0  

If you need a lot of access to a particular feature of your data structure that is expensive to compute, it may make sense to pre-compute it.

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

In the case of TreeNodes, this means that your TreeNodes would have to store their Child count. To explain it a bit more in detail: when you create a node n0 this node has a childcount (cc) of 0. When you add a node n1 as a child of this one, you n1.cc + cc++.

对于TreeNodes,这意味着您的TreeNodes必须存储其子计数。更详细地解释一下:当你创建一个节点n0时,这个节点的子计数(cc)为0.当你添加一个节点n1作为这个节点的子节点时,你就是n1.cc + cc ++。

The tricky bit is the remove operation. You have to keep backlinks to parents and go up the hierarchy to subtract the cc of your current node.

棘手的一点是删除操作。您必须保持对父项的反向链接,并向上移动层次结构以减去当前节点的cc。

In case you just want to have the a hasChildren feature for your nodes or override getChildCount, a boolean might be enough and would not force you to go up the whole hierarchy in case of removal. Or you could remove the backlinks and just say that you lose precision on remove operations. The TreeNode interface actually doesn't force you to provide a remove operation, but you probably want one anyway.

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

Well, that's the deal. In order to come up with precomputed precise values, you will have to keep backlinks of some sorts. If you don't you'd better call your method hasHadChildren or the more amusing isVirgin.

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

#4


0  

There are a few parts to the solution:

该解决方案有几个部分:

  • Like Lorenzo Boccaccia said, use the TreeWillExpandListener

    就像Lorenzo Boccaccia所说,使用TreeWillExpandListener

  • Also, need to call nodesWereInserted on the tree, so the proper number of nodes will be displayed. See this code

    此外,需要在树上调用nodesWeresert,因此将显示适当数量的节点。看到这段代码

  • I have determined that if you don't know the child count, TreeNode.getChildCount() needs to return at least 1 (it can't return 0)

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