如何在Java中使用SwingWorker?

与我以前的问题相关: 从Java中的另一个类调用repaint? 。

我是新来的Java,我已经看了一些关于SwingWorker的教程,但我不确定如何使用上一个问题给出的示例代码来实现它。

任何人都可以解释如何使用SwingWorker与我的一点点的代码,或者指向我一个体面的教程,请? 我看了,但我不知道我明白了。

通常,SwingWorker用于在Swing中执行长时间运行的任务。

在事件调度线程(EDT)上运行长时间运行的任务会导致GUI被锁住,所以完成的一件事情就是使用SwingUtilities.invokeLaterinvokeAndWait ,它保持了GUI的响应,从而优先处理其他的AWT事件运行所需的任务(以Runnable的形式)。

但是, SwingUtilities的问题是它不允许从执行的Runnable返回到原始方法的数据。 这就是SwingWorker设计目标。

Java教程有一个关于SwingWorker的章节。

下面是一个示例,其中SwingWorker用于在单独的线程上执行耗时的任务,并在稍后用答案显示消息框。

首先,将扩展SwingWorker一个类:

 class AnswerWorker extends SwingWorker<Integer, Integer> { protected Integer doInBackground() throws Exception { // Do a time-consuming task. Thread.sleep(1000); return 42; } protected void done() { try { JOptionPane.showMessageDialog(f, get()); } catch (Exception e) { e.printStackTrace(); } } } 

doInBackgroundget方法的返回类型被指定为SwingWorker的第一个类型,第二个类型是用于返回publishprocess方法的类型,在本例中没有使用。

然后,为了调用SwingWorker ,调用execute方法。 在这个例子中,我们将一个ActionListener挂钩到一个JButton来执行AnswerWorker

 JButton b = new JButton("Answer!"); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { new AnswerWorker().execute(); } }); 

上面的按钮可以被添加到一个JFrame ,然后点击一秒钟以获得一个消息框。 以下内容可用于初始化Swing应用程序的GUI:

 private void makeGUI() { final JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.getContentPane().setLayout(new FlowLayout()); // include: "class AnswerWorker" code here. // include: "JButton" b code here. f.getContentPane().add(b); f.getContentPane().add(new JButton("Nothing")); f.pack(); f.setVisible(true); } 

一旦应用程序运行,将会有两个按钮。 一个标有“答案”! 和另一个“没有”。 当点击“答案”时 按钮,一开始没有任何事情发生,但点击“Nothing”按钮将工作,并证明GUI是响应。

而且,一秒钟之后, AnswerWorker的结果将出现在消息框中。

同意:

在事件调度线程(EDT)上运行长时间运行的任务会导致GUI锁定。

不同意:

所以所做的一件事就是使用SwingUtilities.invokeLater和invokeAndWait来保持GUI的响应。

invokeLater仍然在EDT上运行代码,并可以冻结你的UI! 尝试这个:

 SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { Thread.sleep(100000); } catch (InterruptedException e) { e.printStackTrace(); } } }); 

至少我,不能移动我的鼠标一旦我点击按钮,触发actionPerformed与上面的代码。 我错过了什么吗?