停止/取消SwingWorker线程?

时间:2011-11-10 17:31:59

标签: java swing swingworker

我正在尝试了解如何在按下按钮时停止运行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);

4 个答案:

答案 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);
    }
});

以下是一个完整的例子:

enter image description here

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)。