Swing:当JTree更新花费太长时间并冻结其他GUI元素时该怎么办?

时间:2010-04-07 10:48:30

标签: java multithreading user-interface swing swingworker

我知道Java Swing中的GUI代码必须放在里面 SwingUtilities.invokeAndWaitSwingUtilities.invokeLater。 这样线程工作正常。

可悲的是,在我的情况下,GUI更新了那个比后台线程花费更长时间的东西。更具体一点:我用大约400个条目更新一个JTree,嵌套深度最大为4,所以应该没什么可怕的,对吧?但它有时需要一秒钟!我需要确保用户能够无延迟地键入JTextPane。好吧,猜猜看,慢速JTree更新会导致输入过程中JTextPane的延迟。只有在树更新后才会刷新。

我正在使用Netbeans并且凭经验知道Java应用程序可以更新大量信息而不会冻结UI的其余部分。

怎么做?

注意1:所有这些DefaultMutableTreeNode都是在invokeAndWait之外准备的。
注意2:当我用invokeAndWait替换invokeLater时,树不会更新。
注3:喜欢递归树扩展需要花费最多时间。
注意4:我正在使用自定义树单元格渲染器,将尝试不使用并报告。
注意4a:我的树状单元渲染器使用映射来缓存和重用已创建的JTextComponent,具体取决于树节点(作为密钥)。

CLUE 1 :哇! 没有设置自定义单元格渲染器,快10倍。我想,我需要很少的关于编写自定义树单元格渲染器的好教程。遗憾的是,我需要自定义单元格渲染器。

This tutorial involving lazy loading might help, I'll work this through.

2 个答案:

答案 0 :(得分:2)

[缺少一些细节,例如:每次用户更新JTextPane时会发生什么类型的处理?整棵树正在重建吗?]

无论如何,过去对我有用的东西(当我因JTree更新而经历了显着的放缓)是我推出了自己的TreeModel。

大多数程序员选择使用DefaultTreeModel。这确实是一种在大多数情况下都能很好地运行的现成解决方案。但是,当需要更新树的重要部分时,它非常慢。显然,编写自己的TableModel比使用固定解决方案更有效,但它比你想象的要痛苦得多。

特别是,我的自定义树模型很快,因为它本身不构建任何树。它只是观察我的域模型,并通过从该模型中提取相关信息来计算对其调用的方法(getChild(),getParent(),...)的答案。试试吧。它就像一个魅力。

答案 1 :(得分:1)

我不知道为什么它只适用于invokeAndWait()(这很奇怪),但一个简单的黑客就是在新的后台线程中调用此方法。

我还建议你不要一次填充所有树。这通常是大量的工作,不能轻易加快。相反,只更新那些可见的节点,并在用户展开时更新更多节点。