java - Swingworker.done() 在完成后卡住 GUI 几秒钟

标签 java multithreading swing swingworker event-dispatch-thread

我有一个 SwingWorker,它在后台读取和处理文件,然后在 JTextPane 中格式化并以各种样式显示数据。

如果文件很大(超过 200K),我将显示一个带有进度条的对话框。在 SwingWorker 的 done() 方法中,我填充了 JTextPane,然后隐藏了对话框。 done() 方法如下所示:

protected void done() {
   populateTextPane();

   hideProgressDialog();
   System.out.println("After hideProgressDialog");
}

当它运行时,我会看到对话框消失,控制台上出现 println 消息,但随后 GUI 又卡住了 10-15 秒,卡住结束时数据在 JTextPane 中可见。

我认为 done() 方法中发生的任何事情都会在事件调度线程中发生。但显然 JVM 正在生成另一个线程来隐藏对话框并在填充 JTextPane 时执行 println。我想一直显示进度对话框,直到 GUI 准备好再次接受用户输入...我如何检测 done() 中的所有内容何时真正完成?

最佳答案

done 方法在 EDT 上执行。如果您对此有疑问,可以随时使用 EventQueue.isDispatchThread() 方法进行检查。

一个可能的解释是 populateTextPane() 方法安排了在 EDT 上重绘 JTextPane。这意味着 done() 方法已完成,然后您才能在 UI 中看到 populateTextPane() 方法的结果。

你可以尝试如下重写done方法

protected void done() {
   populateTextPane();
   SwingUtilities.invokeLater( new Runnable(){
     @Override
     public void run(){
       hideProgressDialog();
       System.out.println("After hideProgressDialog");
     }
   } );
}

这将确保 hideProgressDialog 仅在 EDT 上 populateTextPane() 任何可能的 Runnable 计划之后执行。但是,这仍会使您的 UI 卡住 10-15 秒。唯一的区别是进度对话框仍然可见。

如果进度对话框显示在 JTextPane 的顶部,不确定这是否有效。 RepaintManager 可能决定仅在对话框变得不可见后重绘 JTextPane(因此不再隐藏 JTextPane)。

关于java - Swingworker.done() 在完成后卡住 GUI 几秒钟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15604782/

相关文章:

java - 通过 Stream 过滤操作并维护为 map 而不是 Stream

Qt 串口的 C++ 线程模式

java - 防止缓慢的作业接管线程池

java - 移动圆圈时的滞后问题

java - 当取消选择复选框或单选按钮时,如何防止 if 语句更改值

java - 从Gradle中删除Play服务 map 实现

java - Google Cloud Endpoints 需要 Android SDK 级别 11 或更高版本

java - 字符编码问题?

java - 使用 SynchronousQueue 解决消费者生产者并发问题。公平属性不起作用

java - 当 JCheckBox 由表模型生成时初始化它们