简体   繁体   English

停止/取消SwingWorker线程?

[英]Stop/cancel SwingWorker thread?

I'm trying to find out how to stop a SwingWorker thread from running when I press a button. 我正试图找出如何在按下按钮时停止运行SwingWorker线程。 I have been looking around and I'm having some trouble working out how to do this. 我一直在四处寻找,我在解决如何做到这一点时遇到了一些麻烦。 At the moment this is what I have: 目前这就是我所拥有的:

new MySwingWorkerClass(args).execute();

I'm then creating a button which I want to use in order to stop the thread: 我正在创建一个按钮,我想用它来停止线程:

button = new JButton("Stop");
button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) 
        {
        // Stop the swing worker thread
        }
});

I have already looked around in search of an answer, so far I have managed to find the cancel method. 我已经环顾四周寻找答案,到目前为止我已经设法找到了取消方法。 I don't understand how to use this to stop my swing worker though. 我不明白如何使用它来阻止我的摇摆工作者。 I tried the following but it didn't work: 我尝试了以下但它不起作用:

SwingWorker.cancel(true);

You need to keep a reference to your SwingWorker, then you use that reference to cancel the worker thread. 您需要将基准存到自己的SwingWorker,然后使用该引用取消工作线程。

MySwingWorker myWorker = new MySwingWorkerClass(args).execute();

button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) 
    {
        // Stop the swing worker thread
        myWorker.cancel(true);
    }
});

Here is a full example: 这是一个完整的例子:

在此输入图像描述

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();
            }

        });
    }

}

You need to periodically check its cancelled flag (ie isCancelled() ). 您需要定期检查其取消的标志(即isCancelled() )。 SwingWorker leaves how to handle the interrupt up to you. SwingWorker留下了如何处理中断的方法。

For more information, see Cancelling Background Tasks . 有关更多信息,请参阅取消后台任务

I think you have to restart the counter after every stop. 我想你必须在每次停止后重启计数器。

For startButton, you have to have worker restarted as in 对于startButton,您必须重新启动worker,如同

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

To stop you can use 停止你可以使用

worker.setStopFlag(); // in stopButton actionPerformed block.

in Worker class private boolean stopFlag = false; 在Worker类中,private boolean stopFlag = false;

and add 并添加

if( stopFlag)
break;

after Thread.sleep(60); 在Thread.sleep(60)之后; and finally put setter for stopFlag at the end of Worker class as 最后在worker类的末尾为setFlag设置了set

void setStopFlag(){
    stopFlag = true;
}

By the way, you can use cancel(true) if you want to have exception exit. 顺便说一句,如果你想要异常退出,你可以使用cancel(true)。

you can try overidding the done() method and put it in try catch and catch the java.util.concurrent.CancellationException. 您可以尝试重写done()方法并将其放在try catch中并捕获java.util.concurrent.CancellationException。 Something like 就像是

. . .

@Overide
done() {
   try {
     get();
   } catch (CancellationException e) {
       // Do your task after cancellation
   }
}

. . .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM