调用SwingWorker.get()时防止GUI冻结 [英] Preventing GUI From Freezing When Calling SwingWorker.get( )

查看:115
本文介绍了调用SwingWorker.get()时防止GUI冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a program where I am loading a file while at the same time I am displaying a window to inform the user that the file is being loaded. I decided to make a FileLoader class that was a SwingWorker which actually handled loading the file and a ProgressWindow that implements PropertyChangeListener to inform the user about the status of the SwingWorker that was passed into it.

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

My code currently looks like this:

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()运行时,该线程会被保持。

The problem is that whenever I call loader.get(), it freezes the GUI, thus the progress bar in the Progress Window doesn't run and the whole thing is pointless. As far as I can tell, this is because the thread controlling the GUI is the same thread that calls loader.get(), which goes on hold while loader.execute() is running.

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

So far, I've tried creating a new thread for either the loader.get() command or the loader.execute() method, and calling SwingUtilities.invokeLater() on the thread, but then the whole program freezes.

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

I've considered creating a ChangeListener for when SwingWorker.isDone() and then running loader.get(), but this would require some reworking of my code that I would rather not do.

有人能告诉我最好的办法是什么?

Could anyone tell me what the best way is to get this to work?

推荐答案

get()就像 join()一样,它会阻止直到被调用,并等待SwingWorker在被调用之前完成。错误地使用它可以完全取消使用SwingWorker的所有优点。

get() is like join() in that it will block until called, and will wait for the SwingWorker to finish before being called. Using it wrongly can completely nullify all the advantages of using a SwingWorker in the first place.

解决方案:不要调用 get()直到你知道SwingWorker完成了它的处理,通过在SwingWorker的 done()方法中调用它,或者如果你需要从它调用它调用代码,然后在SwingWorker的state属性为SwingWorker.StateValue.DONE时已添加到SwingWorker的PropertyChangeListener中。

Solution: Don't call get() until you know that the SwingWorker is done with its processing, by either calling it in the SwingWorker's done() method, or if you need to call it from the calling code, then in a PropertyChangeListener that has been added to the SwingWorker when the SwingWorker's "state" property is SwingWorker.StateValue.DONE.

类似于:

  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");

注意:代码未编译或测试

Note: code not compiled nor tested

编辑:尝试/捕捉添加。

try/catch added.

这篇关于调用SwingWorker.get()时防止GUI冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆