如何在Java中使用SwingWorker?
与我上一个问题相关:从Java中的另一个类调用重绘?
我是Java的新手,我看过SwingWorker上的一些教程。然而,我不确定如何使用我在上一个问题中给出的示例代码来实现它。
任何人都可以解释一下如何使用SwingWorker来理解我的代码片段和/或指向我一个像样的教程吗?我看过,但我不确定我是否理解。
与我上一个问题相关:从Java中的另一个类调用重绘?
我是Java的新手,我看过SwingWorker上的一些教程。然而,我不确定如何使用我在上一个问题中给出的示例代码来实现它。
任何人都可以解释一下如何使用SwingWorker来理解我的代码片段和/或指向我一个像样的教程吗?我看过,但我不确定我是否理解。
通常,SwingWorker 用于在 Swing 中执行长时间运行的任务。
在事件调度线程 (EDT) 上运行长时间运行的任务可能会导致 GUI 锁定,因此完成的任务之一是使用 SwingUtilities.invokeLater
和 invokeAndWait
,它保持 GUI 响应,从而在运行所需任务之前优先处理其他 AWT 事件(以 a 的形式)。Runnable
但是,问题在于它不允许将数据从执行方法返回到原始方法。这就是SwingWorker
旨在解决的问题。SwingUtilities
Runnable
Java教程中有一个关于SwingWorker的部分。
下面是一个示例,其中 a 用于在单独的线程上执行耗时的任务,并在一秒钟后显示一个包含答案的消息框。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();
}
}
}
和 方法的返回类型被指定为 的第一种类型,第二种类型是用于返回 和 方法的类型,本示例中未使用和。doInBackground
get
SwingWorker
publish
process
然后,为了调用 ,调用该方法。在此示例中,我们将 把 a 挂接到 a 以执行 :SwingWorker
execute
ActionListener
JButton
AnswerWorker
JButton b = new JButton("Answer!");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
new AnswerWorker().execute();
}
});
可以将上述按钮添加到 中,然后单击以在一秒钟后获取消息框。以下内容可用于初始化 Swing 应用程序的 GUI:JFrame
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);
}
运行应用程序后,将有两个按钮。一个标有“答案!”,另一个标有“无”。当单击“回答!”按钮时,起初不会发生任何事情,但单击“无”按钮将起作用并证明GUI是响应式的。
并且,一秒钟后,结果将显示在消息框中。AnswerWorker
同意:
在事件调度线程 (EDT) 上运行长时间运行的任务可能会导致 GUI 锁定。
不同意:
因此,其中一件事情是使用SwingUtilities.invokeLater和roctionAndWait来保持GUI的响应。
invokeLater仍然在EDT上运行代码,并且可以冻结你的UI!试试这个:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
至少我,一旦我点击触发上述代码执行的操作的按钮,就无法移动鼠标。我错过了什么吗?