简体   繁体   English

如何使用JButtons启动和暂停SwingWorker线程

[英]How to use JButtons to Start and Pause SwingWorker thread

I'm trying to learn Threads in Swing. 我正在尝试学习Swing中的线程。

I have a Frame with a JProgressBar (progress), five JButtons (Start, Suspend, Resume, Cancel, Close), and a JLabel (label1). 我有一个带有JProgressBar(进度),五个JButton(开始,挂起,恢复,取消,关闭)和JLabel(标签1)的框架。

The frame opens. 框架打开。 Only Start is enabled. 仅启用启动。 Start calls my class Progressor: 开始调用我的班级进展者:

Updated Again Once and For All 一次又一次更新

Progressor progressor; 进步者进步者 //declared as class variable, initialized new in constructor and again in overridden done method //声明为类变量,在构造函数中初始化new ,然后在重写的done方法中再次初始化

Here's the ButtonListener class: 这是ButtonListener类:

public class ButtonListener implements ActionListener{
    public void actionPerformed(ActionEvent e)
    {

        if (e.getSource() == jbStart) {
            progressor.execute();
            label1.setText("Progressing ...");
            jbCancel.setEnabled(true);
            jbResume.setEnabled(true);
            jbSuspend.setEnabled(true);
            jbClose.setEnabled(true);
        }
        if(e.getSource() == jbCancel) {
            progressor.cancel(true);
            label1.setText("Progress Canceled");
        }
        if (e.getSource() == jbSuspend) {
            label1.setText(progressor.suspendProgress());
        }
        if (e.getSource() == jbResume) {
            label1.setText(progressor.resumeProgress());
        }
        if (e.getSource() == jbClose) {
            dispose();
        }

    }

}//buttonlistener } // buttonlistener

Here's the SwingWorker class: 这是SwingWorker类:

public class Progressor extends SwingWorker<Void, Integer> {

    private volatile boolean suspend = false;
    private Object lock = new Object();

    @Override
    protected Void doInBackground() {

        for (int i = 0; i <= 10; i++) {
            checkForSuspend();
            try {
                Thread.sleep(1000);
            }
            catch (InterruptedException e) {
            }
            publish(i);
        }   
        return null;
    }

    @Override
    protected void process(List<Integer> list) {
        int value = list.get(list.size() - 1);
        progress.setValue(value);

    }

    public void checkForSuspend() {
        synchronized (lock) {
            while (suspend) {
                try {
                    lock.wait();
                } catch (InterruptedException ie){
                }
            }
        }
    }//checkForSuspend

    @Override
    protected void done() {
        label1.setText("All Done.  Press close to exit");
        progressor = new Progressor();
    }

    public synchronized String suspendProgress() {
        suspend = true;
        return "Progress suspended ...";
    }

    public synchronized String resumeProgress() {
        synchronized (lock) {
            suspend = false;
            lock.notify();
            return "Progress resumed ...";
        }
    }


}//Progressor class

Everything works except the cancel doesn't doesn't actually cancel the thread (the progress bar continues). 一切正常,但cancel实际上并没有取消线程(进度条继续)。

Should I suspend it before canceling? 我应该在取消之前将其暂停吗?

This How to Pause and Resume a Thread in Java from another Thread question looks very similar to yours and has some nice examples in the answers. 这个如何从另一个线程问题中暂停和恢复Java中的线程的方法与您的问题非常相似,并且在答案中有一些不错的示例。

As for your own code and why it does not work: 至于您自己的代码以及为什么它不起作用:

  1. You create a new progressor on every click. 您每次点击都会创建一个新的进度器。 You should be using and controlling one, instead of creating new ones every time. 您应该使用和控制一个,而不是每次都创建一个新的。
  2. When suspending your progressor finishes work instead of suspending. 暂停进度器时,请完成工作而不是暂停。 As the above question states - you should be looking at the flag at some points of your computation and acting on it. 正如上述问题所指出的那样-您应该在计算的某些时候查看标志并对其进行操作。 Example: 例:

     while (!cancel) { if (!suspended) { for (int i = 1; i <= 10; i++) { Thread.sleep(1000); publish(i); } } } 

    The above code will suspend when it next reaches 10 (unless you resumed it before that), and finish when you press cancel (Cancel needs to be added as an extra flag in the obvious manner). 上面的代码在下一个达到10时将暂停(除非您在此之前将其恢复),并在按Cancel时结束(取消必须以明显的方式添加为额外的标志)。

Your thread should run inside a while loop that looks for a boolean to change value from another object, then simply change the state with setPause(true/false) when you click the button: 您的线程应该在while循环中运行,该循环寻找一个布尔值以更改另一个对象的值,然后在单击按钮时使用setPause(true / false)更改状态:

while(true){
    if(object_everyone_can_reference.getPause()){
    Thread.sleep(1000);
     }

 }

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

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