Java 防止Swing GUI在调用既访问Swing组件又耗时的方法时变得无响应

Java 防止Swing GUI在调用既访问Swing组件又耗时的方法时变得无响应,java,multithreading,swing,swingworker,Java,Multithreading,Swing,Swingworker,以下一行: SwingUtilities.updateComponentTreeUI(aComponent); 正在使我的GUI无响应 当调用此方法来更新大部分GUI上的laf时,需要花费大量时间,因此会使GUI在此操作期间无响应 由于此操作是在操纵GUI,因此也不能使用SwingWorker进行此操作。 从SwingWorker文档中: 不应在事件分派线程上运行耗时的任务。 否则,应用程序将变为 反应迟钝 应在事件分派线程上访问Swing组件 只是 不过,这里的问题是,该操作正在访问Sw

以下一行:

SwingUtilities.updateComponentTreeUI(aComponent);
正在使我的GUI无响应

当调用此方法来更新大部分GUI上的laf时,需要花费大量时间,因此会使GUI在此操作期间无响应

由于此操作是在操纵GUI,因此也不能使用SwingWorker进行此操作。 从SwingWorker文档中:

  • 不应在事件分派线程上运行耗时的任务。 否则,应用程序将变为 反应迟钝

  • 应在事件分派线程上访问Swing组件 只是

不过,这里的问题是,该操作正在访问Swing组件,而且非常耗时


有没有一种好方法可以防止这种无响应?

我建议您通过GUI来识别任何自定义或第三方组件,这些组件包含许多子组件,或者有任何异常或低效的方法来重新验证自身。看起来情况就是这样,正如你提到的,日期选择器是一个严重的瓶颈

您建议将对
updateComponentTree
的调用分为几个子任务,这些子任务允许在其间发生事件,这可能是一个“黑客”行为,但也不太糟糕,除非字体的更改改变了元素的大小,并可能导致用户错过按钮等


如果可能,我建议查看date picker组件中的代码,看看是否可以重写它,这样它就可以删除/处置这些组件,而不是在弹出窗口中隐藏这些组件,并在必要时重新创建它们。这对使用日期选择器时的响应性没有明显影响,但在弹出窗口不可见时肯定会加快组件树更新。

因为您所做的是更改L&F,这可能会严重影响GUI的外观和可用性,问问自己是否真的希望应用程序在这段时间内响应。最好使用显示消息(“请稍候…”或其他内容),并在L&F更新时冻结GUI


现在,正如其他人所建议的,您可能想调查为什么更新组件树如此缓慢。

猜测它需要如此多的时间,因为它是一个大型组件树。。。您可以在子组件上调用它,将暂停分解为更小的部分吗?关键问题是,当正确的MVC体系结构允许您仅通过刷新特定组件的模型来更新它们时,为什么要手动更新此组件树。@Riduidel我正在做的是更改所有swing组件上的字体。更改laf和更新组件树似乎是一种顺利的方法,而不必手动更改所有组件上的字体。100组件不需要任何可测量的时间。。因此,任务是跟踪是否/在哪里存在瓶颈可能已经在您的机器上。