java - 调用 SwingWorker.get( ) 时防止 GUI 卡住

标签 java swing swingworker

我有一个程序,我在加载文件的同时显示一个窗口,通知用户文件正在加载。我决定制作一个 FileLoader 类,它是一个实际处理加载文件的 SwingWorker 和一个实现 PropertyChangeListener 的 ProgressWindow 以通知用户传递给它的 SwingWorker 的状态。

我的代码目前看起来像这样:

FileLoader loader = new FileLoader(filePath);
new ProgressWindow(loader, "Loading File", "Loading File");
//ProgressWindow's constructor calls loader.execute() inherited from SwingWorker
doc = loader.get(); //GUI Freezes when called

问题是每当我调用 loader.get() 时,它都会卡住 GUI,因此进度窗口中的进度条不会运行,整个过程毫无意义。据我所知,这是因为控制 GUI 的线程与调用 loader.get() 的线程相同,它在 loader.execute() 运行时暂停。

到目前为止,我已尝试为 loader.get() 命令或 loader.execute() 方法创建一个新线程,并在该线程上调用 SwingUtilities.invokeLater(),但随后整个程序卡住。

我考虑过为 SwingWorker.isDone() 创建一个 ChangeListener,然后运行 ​​loader.get(),但这需要对我的代码进行一些修改,而我不想这样做。

谁能告诉我让它发挥作用的最佳方法是什么?

最佳答案

get()join() 类似,它会阻塞直到被调用,并会等待 SwingWorker 完成后再被调用。错误地使用它会完全抵消最初使用 SwingWorker 的所有优势。

解决方案:在您知道 SwingWorker 已完成其处理之前,不要调用 get(),方法是在 SwingWorker 的 done() 方法中调用它,或者,如果您需要从调用代码调用它,则在 SwingWorker 的“状态”属性为 SwingWorker.StateValue.DONE 时,在已添加到 SwingWorker 的 PropertyChangeListener 中调用它。

类似于:

  final FileLoader loader = new FileLoader(filePath);

  loader.addPropertyChangeListener(new PropertyChangeListener() {
     @Override
     public void propertyChange(PropertyChangeEvent evt) {
        if ("state".equals(evt.getPropertyName())) {
           // since DONE is enum, no need for equals(...) method
           if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
              try {
                 loader.get();
              } catch (InterruptedException e) {
                 e.printStackTrace();
              } catch (ExecutionException e) {
                 e.printStackTrace();
              }
           }
        }
     }
  });

  new ProgressWindow(loader, "Loading File", "Loading File");

注意:代码未编译也未测试

编辑:添加了 try/catch。

关于java - 调用 SwingWorker.get( ) 时防止 GUI 卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11547537/

相关文章:

java - SwingUtilities.invokeLater、SwingWorker 和 gif 图标动画问题

实现 Map 并保持插入顺序的 Java 类?

java - 整数井字棋

java - 如何在 Window Builder 中生成不同数量的文本框和标签

java - 使用 jFreeChart 的多个图形中的多个图形

java - SwingWorker 的 ExecutorService 参数

java - 看起来 "imperative"支持响应式(Reactive)代码的代码是否常见?

java - 我如何分析约 13GB 的数据?

Java:在桌面上放置窗口时考虑任务栏/菜单栏/等?

java - SwingWorker 的 done 方法甚至在 doInBackground 完成之前随机执行