【问题标题】:SwingWorker, Cancel-Button doesn't workSwingWorker,取消按钮不起作用
【发布时间】:2014-02-09 18:11:22
【问题描述】:

我有一个带有开始和停止按钮的窗口。开始按钮启动算法,停止按钮应该停止它。我使用SwingWorker 在后台运行算法,通常调用worker.cancel(true) 应该停止算法运行。我还有一个标签,可以显示状态,例如如果我按下“Stop”,Labeltext 会变为“stopped”,所以问题不在 Button 的 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;
    }

}

此时,按下停止按钮只会导致标签文本发生变化,但后台的算法仍在运行。现在这困扰了我很长一段时间,我就是无法继续。

非常感谢您的帮助,非常感谢。

edit1:我现在在 actionPerformed 之外生成了一个新的 worker 实例,所以现在每次鼠标点击都不会生成新的 Worker。

【问题讨论】:

  • 如果在 mapp() 中有一个循环,你必须在那里处理一个 InterruptedException。我不认为你会来你的“SwingWorker isCancelled”。
  • 您正在每个button click 中创建一个worker 实例,请参阅Worker worker = new Worker(); 它们与您取消的那个与您要取消的那个无关。

标签: java multithreading swing swingworker


【解决方案1】:

也许如果你在Worker 类的doInBackground() 方法上使用while 而不是if,你会解决你的问题。您必须将mapp() 退出while 循环,因为您只想调用它一次。你应该这样做:

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 解释的那样,以及那些“其他原因”在我发布的链接上进行了讨论。

您可以直接使用Threads 来解决您的问题。您的代码将是这样的:

    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() 执行完成之前停止它。

我建议您详细了解SwingWorkerThreadTask,以找到解决问题的最佳方法。

【讨论】:

  • 感谢您的回答,但我之前也尝试过,但没有成功。
  • 我想问题就在那里。 Mapp() 调用不同的方法,大部分工作都在那里完成。但是我不明白,worker在后台处理这个方法,所以取消worker,也应该取消那个方法的处理。
  • 我已经编辑了答案。我不知道为什么您的 mapp() 不会停止,但也许这个新答案会引导您走上正确的道路。
  • 在你的第一个 sn-p 中:你也可以不支持取消,因为mapp() 将一直执行直到它完成。只有当您可以将整个执行分成几个部分时,取消才有意义。在执行某个部分之后(或之前),您检查取消标志并在收到信号时执行此操作。如果任务被取消,只需执行所有操作并等待直到任务被取消将进入无限循环。
  • 第二个sn-p:请不要打电话给stop。你可以打断它,你可以使用 CountDownLatch ...
【解决方案2】:

您的问题是工作程序中没有循环:如果您想使用标志取消进程,该进程应不时检查标志,因此如果您的方法 Worker.mapp() 必须停止,检查那里的标志,而不是在调用它之前和之后。

【讨论】:

  • AND:他在两个不同的worker实例上调用execute和cancel。请注意上下文,“worker”是在其中创建的。每次单击按钮都会创建一个新的 Worker。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-14
  • 2014-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多