停止/取消 SwingWorker 线程?

发布于 2024-12-15 02:51:14 字数 524 浏览 2 评论 0原文

我试图找出如何在按下按钮时停止 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);

I'm trying to find out how to stop a SwingWorker thread from running when I press a button. 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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

旧梦荧光笔 2024-12-22 02:51:14

您需要保留对您的 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();
            }

        });
    }

}

You need to keep a reference to your SwingWorker, then you use that reference to cancel the worker thread.

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:

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

        });
    }

}
审判长 2024-12-22 02:51:14

您需要定期检查其已取消标志(即 isCancelled())。 SwingWorker 离开如何处理中断由你决定。

有关详细信息,请参阅取消后台任务

You need to periodically check its cancelled flag (i.e. isCancelled()). SwingWorker leaves how to handle the interrupt up to you.

For more information, see Cancelling Background Tasks.

温柔嚣张 2024-12-22 02:51:14

您可以尝试覆盖done()方法并将其放入try catch中并捕获java.util.concurrent.CancellationException。类似的东西



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



you can try overidding the done() method and put it in try catch and catch the java.util.concurrent.CancellationException. Something like

.
.
.

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

.
.
.

一片旧的回忆 2024-12-22 02:51:14

我认为每次停止后都必须重新启动计数器。

对于 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 类中
私有布尔stopFlag = false;

添加

if( stopFlag)
break;

并在 Thread.sleep(60); 之后
最后将 stopFlag 的 setter 放在 Worker 类的末尾,顺便说

void setStopFlag(){
    stopFlag = true;
}

一下,如果你想要异常退出,你可以使用 cancel(true) 。

I think you have to restart the counter after every stop.

For startButton, you have to have worker restarted as in

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;

and add

if( stopFlag)
break;

after Thread.sleep(60);
and finally put setter for stopFlag at the end of Worker class as

void setStopFlag(){
    stopFlag = true;
}

By the way, you can use cancel(true) if you want to have exception exit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文