java - 使用 invokeLater 或 SwingWorker 从另一个线程更新 Swing 组件

标签 java swing multithreading

我正在开发一个带有 Swing GUI 的小型应用程序。应用程序在另一个线程中执行 IO 任务,当该线程完成时,GUI 应相应更新以反射(reflect)线程的操作结果。在 (worker, non-GUI) 中运行的类在构造函数中传递给它的对象将用于更新 GUI,所以我不需要将 GUI 的东西放在非 GUI 类中,而是传递用于更新 GUI 的对象到那个类(class)。 据我了解这里阅读的形式,(线程/Swing )更新(更改)Swing GUI 的安全选项将使用 javax.swing.SwingUtilities.invokeLater(), javax.swing.SwingUtilities .invokeLaterWait() 和/或 javax.swing.SwingWorker() 基本上做同样的事情。

Swing 的这个全线程问题让我有点困惑,但我需要使用线程在 GUI 应用程序中做任何有意义的事情,而不是在 EDT 中处理时挂起 GUI,所以我现在感兴趣的是:

  1. invokeLaterinvokeLaterWait 是否喜欢向 EDT 发送消息并等待它在处理完该调用之前的消息时执行此操作?

  2. 从 Swing 线程安全的角度来看,做这样的事情是否正确:

    interface IUPDATEGUI {  
      public void update();  
    }  
    
    // in EDT/where I can access components directly    
    class UpdateJList implements IUPDATEGUI {    
      public void update() {    
        // update JList...    
        someJList.revalidate();    
        someJList.repain();    
      }    
    }    
    
    class FileOperations implements Runnable {  
      private IUPDATEGUI upObj;  
      List<File> result = new ArrayList<File>; // upObject is accessing this  
    
      public void FileOperations(IUPDATEGUI upObj) {
        this.upObj = upObj;
      }
    
      private void someIOTask() {
        // ...
        // IO processing finished, result is in "result"
      }
    
      public void run() {
        someIOTask();
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            upObj.update();  // access result and update JList
          }
        }; );
      }
    }
    

如果这不正确,那么应该怎么做?

如果可以的话,我宁愿使用 invokeLater 而不是 SwingWorker ,因为我不需要更改我的整个类,而且它在某种程度上更整洁/区分我(例如在 Win32 应用程序中发送消息)。

提前致谢。

最佳答案

使用 invokeLater()invokeAndWait() 将 Runnable 参数传递到 EDT 中等待执行的队列中。因此,当 EDT 能够处理请求时,调用 invokeLater() 将导致 Runnable 在 EDT 中执行。 invokeAndWait() 只是等待(在调用线程中)直到执行发生。

如果您想执行在执行结束时或处于中间状态时通知 EDT 的后台任务,那么使用 SwingWorker 是理想的选择。一个示例是将流程的当前进度传递给 JProgressBar。

对于您的示例,SwingWorker 似乎是更好的选择,但如果您不想过多更改代码,那么在过程完成时调用 invokeLater() 就可以了。

关于java - 使用 invokeLater 或 SwingWorker 从另一个线程更新 Swing 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2247703/

相关文章:

java - JVM 是否具有检测并行化机会的能力?

java - 我们如何以编程方式获取 IntelliJ 中方法的调用层次结构

java - 如何在 Java 中创建泛型类但限制可以使用的类型?

java双输入面板

java - 如何在 JEditorPane 中显示 html 文件

java - 使用 ConcurrentHashMap 缓存

java - 从 IBM Domino 中的 session 获取 AdministrationProcess 时,服务器上的操作受到限制

java - 如何在StatelessKieSession中设置AgendaGroup 流口水

Java - 学习 MVC

multithreading - VB6 的线程模型是什么?