编程语言
首页 > 编程语言> > java-SwingWorker,取消按钮不起作用

java-SwingWorker,取消按钮不起作用

作者:互联网

我有一个带有“开始”和“停止”按钮的窗口.开始按钮将启动算法,停止按钮应将其停止.我使用SwingWorker在后台运行算法,并且通常调用worker.cancel(true)应该停止算法运行.我也有一个标签,可以可视化状态,例如如果我按“停止”,则Labeltext更改为“已停止”,因此问题不在按钮的actionLister上.

我的代码如下所示:

public class MainWindow extends JFrame implements ActionListener, WindowListener
{
 // Some code, like generating JFrame, JButtons and other stuff not affencting the task.

 Worker worker = new Worker();

    public void actionPerformed(ActionEvent e)
    {       
    boolean isStarted = false;



    // Start Button
    if (e.getSource() == this.buttonStart)
    {
        if(!isStarted)
        {
        System.out.println("start");
        labelSuccess.setText("Mapping started!");
        this.setEnabled(true);
        worker.execute();
        isStarted = false;
        }
    }
    // Stop Button
    if (e.getSource() == this.buttonStop)
        {
        labelSuccess.setText("Mapping stopped!");
        worker.cancel(true);
        }
  }

class Worker extends SwingWorker<Void, Void> {

    @Override
    protected Void doInBackground() throws Exception {

    if(!isCancelled())
    {
        mapp();
        Thread.sleep(60);
    if (isCancelled()) {
     System.out.println("SwingWorker - isCancelled");
    }
    }
        return null;
    }

}

此时,按下“停止”按钮只会导致Label-Text更改,但是后台的算法仍在运行.现在,这困扰了我好一阵子,我实在受不了了.

非常感谢您的帮助,不胜感激.

edit1:我现在在actionPerformed之外生成了一个新的worker实例,因此现在每次单击鼠标都不会生成新的Worker.

解决方法:

也许如果在Worker类的doInBackground()方法上使用while而不是if,则可以解决您的问题.您必须退出whilep循环,因为您只想一次调用它.您应该执行以下操作:

class Worker extends SwingWorker<Void, Void> {

    @Override
    protected Void doInBackground() throws Exception {

    mapp();    
    while(!isCancelled()){
        Thread.sleep(60);
    }
     System.out.println("SwingWorker - isCancelled");    
        return null;       
}

这个link可能有助于理解如何使用SwingWorker.

编辑:

如您在另一个问题(如thisthis)上看到的那样,使用SwingWorker在管理cancel方法方面存在一些问题,因为该方法试图取消执行此任务.如果任务已经完成,已经被取消或由于某些其他原因而无法取消,则该尝试将失败,例如Oracle的解释,这些“其他原因”将在我发布的链接中进行讨论.

您可以直接使用线程来解决您的问题.您的代码将如下所示:

    public class MainWindow extends JFrame implements ActionListener, WindowListener
    {
     // Some code, like generating JFrame, JButtons and other stuff not affencting the task.

        final Thread th1 = new Thread(new Runnable() {

                    @Override
                    public void run() {
                        mapp();                 

                    }
                }); 
        public void actionPerformed(ActionEvent e)
        {       
        boolean isStarted = false;

    // Start Button
    if (e.getSource() == this.buttonStart)
    {
        if(!isStarted)
        {
        System.out.println("start");
        labelSuccess.setText("Mapping started!");
        this.setEnabled(true);
        th1.start();
        isStarted = false;
        }
    }
    // Stop Button
    if (e.getSource() == this.buttonStop)
        {
        labelSuccess.setText("Mapping stopped!");
        th1.stop();
        }
  }

该解决方案使用了不建议使用的stop()方法,但是它可以工作.我已经尝试过使用interrupt(),但是我不知道为什么线程要运行到完成mapp()的执行.显然,使用stop()并不是最好的方法,但可以在完成mapp()之前停止执行.

我建议您了解有关SwingWorker,线程和任务的更多信息,以找到解决问题的最佳方法.

标签:swingworker,multithreading,swing,java
来源: https://codeday.me/bug/20191122/2058049.html