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

本文探讨了在Java Swing应用中使用SwingWorker时遇到的问题,即停止按钮无法有效取消后台运行的算法。作者通过分析代码发现,原本的SwingWorker实现中,`doInBackground()`方法的条件判断没有正确控制任务的中断。解决方案包括改用`while(!isCancelled())`循环,并考虑使用`Thread.stop()`或`Thread.interrupt()`方法来停止线程。文章还提醒读者深入学习SwingWorker、多线程和任务管理,以便找到更好的解决方案。
摘要由CSDN通过智能技术生成

我有一个带有“开始”和“停止”按钮的窗口.开始按钮将启动算法,停止按钮应将其停止.我使用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 {

@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 {

@Override

protected Void doInBackground() throws Exception {

mapp();

while(!isCancelled()){

Thread.sleep(60);

}

System.out.println("SwingWorker - isCancelled");

return null;

}

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

编辑:

如您在另一个问题(如this或this)上看到的那样,使用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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值