我正在尝试了解如何在按下按钮时停止运行SwingWorker线程。我一直在四处寻找,我在解决如何做到这一点时遇到了一些麻烦。目前这就是我所拥有的:
new MySwingWorkerClass(args).execute();
然后我创建了一个按钮,我想用它来停止线程:
button = new JButton("Stop");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
// Stop the swing worker thread
}
});
我已经四处寻找答案了,到目前为止我已经设法找到了取消方法。我不明白如何使用它来阻止我的摇摆工作者。我尝试了以下但是没有用:
SwingWorker.cancel(true);
答案 0 :(得分:39)
您需要将引用保留到您的 SwingWorker,然后使用该引用取消工作线程。
MySwingWorker myWorker = new MySwingWorkerClass(args).execute();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
// Stop the swing worker thread
myWorker.cancel(true);
}
});
以下是一个完整的例子:
public class WorkerDemo extends JFrame {
private boolean isStarted = false;
private JLabel counterLabel = new JLabel("Not started");
private Worker worker = new Worker();
private JButton startButton = new JButton(new AbstractAction("Start") {
@Override
public void actionPerformed(ActionEvent arg0) {
if(!isStarted) {
worker.execute();
isStarted = false;
}
}
});
private JButton stopButton = new JButton(new AbstractAction("Stop") {
@Override
public void actionPerformed(ActionEvent arg0) {
worker.cancel(true);
}
});
public WorkerDemo() {
add(startButton, BorderLayout.WEST);
add(counterLabel, BorderLayout.CENTER);
add(stopButton, BorderLayout.EAST);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
class Worker extends SwingWorker<Void, Integer> {
int counter = 0;
@Override
protected Void doInBackground() throws Exception {
while(true) {
counter++;
publish(counter);
Thread.sleep(60);
}
}
@Override
protected void process(List<Integer> chunk) {
// get last result
Integer counterChunk = chunk.get(chunk.size()-1);
counterLabel.setText(counterChunk.toString());
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new WorkerDemo();
}
});
}
}
答案 1 :(得分:14)
您需要定期检查已取消的标记(即isCancelled()
)。 SwingWorker
留下了如何处理由您决定的中断。
有关详细信息,请参阅Cancelling Background Tasks。
答案 2 :(得分:2)
您可以尝试重写done()方法并将其放在try catch中并捕获java.util.concurrent.CancellationException。像
这样的东西。 。
@Overide
done() {
try {
get();
} catch (CancellationException e) {
// Do your task after cancellation
}
}
。 。
答案 3 :(得分:2)
我认为你必须在每次停止后重启计数器。
对于startButton,您必须重新启动工作程序,如
private JButton startButton = new JButton(new AbstractAction("Start") {
@Override
public void actionPerformed(ActionEvent arg0) {
if(!isStarted) {
worker = new Worker(); // New line
worker.execute();
isStarted = false;
}
}
});
要停止,您可以使用
worker.setStopFlag(); // in stopButton actionPerformed block.
在Worker类中 private boolean stopFlag = false;
并添加
if( stopFlag)
break;
在Thread.sleep(60)之后; 最后将setFreg的setter作为
放在Worker类的末尾void setStopFlag(){
stopFlag = true;
}
顺便说一句,如果你想要退出异常,可以使用cancel(true)。