【问题标题】:Is TreeModel really as bad as I think?TreeModel 真的有我想的那么糟糕吗?
【发布时间】:2011-02-04 17:35:56
【问题描述】:

当我第一次看到javax.swing.tree.TreeModel 时,我认为编写所有方法需要大量工作。然后我找到了DefaultTreeModel,并认为它可以通过适配器模式轻松用于文件树。所以我开始编写适配器并且有点失败。我需要能够访问给定TreeNode 的相应文件(这很容易,因为它可以是一个实例变量),但我也需要它。这可以使用 Map 解决,但它占用了大量内存。切换到 WeakHashMap 有帮助。

这很有效,但是当树发生变化时我遇到了一些奇怪的问题。此外,由于File.list() 被多次调用,这一切都非常缓慢。有多种愚蠢的方法,例如 getChildCount()getChild(Object parent, int index)getIndexOfChild(Object parent, Object child),在我的幼稚实现中,每个调用都会导致读取目录。

这一切都做了很多工作,结果很糟糕。当然,是我的错,但这不是使用有缺陷的过于复杂的模型的直接后果吗?

如果有像List getChildren(Object) 这样的单一方法,它就不会发生。也许我做错了,正确的方法是什么?

最后,我使用 per class 适配器编写了MyCachingTreeModel implements TreeModel,这一切都解决了。但我仍然很好奇它还能如何解决。

更新:

以上内容可能看起来像是一种咆哮,而不是一个正确的问题。所以我再试一次:

如何有效地为文件系统树实现 TreeModel,以便显示目录的当前状态?

我的解决方案在这里不算,因为我绕过了整个模型。此外,它缓存太多,几乎没有注意到任何变化。

【问题讨论】:

    标签: java swing jtree


    【解决方案1】:

    (编辑很晚:)

    如何有效地为文件系统树实现 TreeModel,以便显示目录的当前状态?

    我认为使用 JTree 显示目录树并不是一个很好的方法,因此它始终是最新的。 问题是模型必须在发生重要变化时通知其侦听器(= JTree),而这只有在我们定期重新检查文件时才有可能。所以你的模型至少需要一个自己的线程。自然,它应该只检查那些节点实际显示的文件——但模型并不真正知道这一点(只能通过getValue() 的最后调用来猜测)。

    也许可以将其与缓存问题结合起来:缓存与最后查询的节点相对应的目录对象,并带有“最后检查”时间。在第一次创建后的一段时间内,它们仍然有效,我们缓存子文件列表,但稍后将它们丢弃。对于这些被树查询的相同对象,我们也会在一段时间后再次查看文件系统,并在与以前不同时触发正确的更改事件。

    这仍然依赖于大量启发式方法来了解必须检查哪些文件 - 也许我们应该打破分层并让我们的模型简单地询问树显示哪些节点,然后仅重新检查(和缓存)那些。


    (旧的不是真正的答案:)

    创建 TreeModel API 时(与整个 Swing 同时),集合框架还没有出现。这也是我们在 Swing 的多个地方需要一个 Vector(而不是 List)的原因。

    【讨论】:

    • 我并没有真正找到问题,这似乎更像是一个咆哮。很抱歉没有回答这个问题。 (我从来没有实现过文件系统树——几天前我的最后一个 TreeModel 来自一个内存结构,主要由带有子列表的对象组成,所以实现非常简单,后来由于不得不使用过滤器而变得有点复杂。 )
    • 同意,这是一种咆哮。我将对其进行重新表述,并使其成为一个真正的问题。
    【解决方案2】:

    拥有更复杂的 API 的全部意义正是为了避免频繁调用像 File.list() 这样的东西。这个想法是,对于像计算孩子这样可能需要多次完成的事情,您可以提供一种实现,它比实际获取所有孩子然后计算他们所做的工作更少。

    话虽如此,API 规范中似乎并未真正充分传达这一点,否则您不必问这个问题。 :)

    【讨论】:

    • 即使是 - 我应该如何处理文件?在这种情况下没有更便宜的操作,如果他们要求整个列表并多次使用它而不是一次又一次地询问,它会更快。可能存在他们的 API 更好的情况,但我不知道。
    • 是的,我的意思是在你的情况下,正确的解决方案可能是在你第一次获得文件列表后缓存它,听起来你就是在那里登陆的。但是您当然可以想象这样一种情况,您从数据库中获取分层数据,并且 COUNT 查询会比 SELECT 查询更快,或者您甚至可能将子对象的数量非规范化到父对象上。
    【解决方案3】:

    另外:考虑一下 NetBeans 平台及其节点和资源管理器 API

    【讨论】:

    • 我看了一下,但是看起来很复杂。您是否将其作为“可能会变得更糟”的例子提及?
    猜你喜欢
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 2011-08-10
    • 2011-03-12
    • 2013-01-15
    • 2013-07-19
    相关资源
    最近更新 更多