暂停和恢复SwingWorker.doInBackground()

迈克·尼奇

我有一个基本的Swing UI,带有一个标记为“播放”的按钮。当按下按钮时,标签变为“暂停”。现在,当按下按钮时,它变为“继续”。

在“播放”中,我将实例化并执行一个SwingWorker。我想要的是能够暂停该线程(不要取消该线程),并根据上述按钮按下来恢复它。但是,我不想在doInBackground()中求助于Thread.sleep()。这似乎有点骇人听闻。有什么方法可以阻止运行doInBackground的线程?

dic19

暂停和恢复SwingWorker.doInBackground()

首先,您必须确保可以暂停正在执行的后台任务,否则问题就没有意义了。所以我们可以说任务可以暂停,那么你可能会延长的SwingWorker类,使自己可暂停使用一个简单的标志变量来控制后台线程状态的工人:暂停不暂停

public abstract class PausableSwingWorker<K, V> extends SwingWorker<K, V> {

    private volatile boolean isPaused;

    public final void pause() {
        if (!isPaused() && !isDone()) {
            isPaused = true;
            firePropertyChange("paused", false, true);
        }
    }

    public final void resume() {
        if (isPaused() && !isDone()) {
            isPaused = false;
            firePropertyChange("paused", true, false);
        }
    }

    public final boolean isPaused() {
        return isPaused;
    }
}

子类可能会检查isPaused()状态,以便有效地继续执行任务。例如:

PausableSwingWorker<Void, String> worker = new PausableSwingWorker<Void, String>() {
    @Override
    protected Void doInBackground() throws Exception {
        while (!isCancelled()) {
            if (!isPaused()) {
                // proceed with background task
            } else {
                Thread.sleep(200); // Optional sleep to avoid check status continuously
            }
        }
        return null;
    }
};

您还可以向工作器添加PropertyChangeListener并侦听paused属性更改:

worker.addPropertyChangeListener(new PropertyChangeListener() {
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if ("paused".equals(evt.getPropertyName())) {
           System.out.println("Old status: " + evt.getOldValue());
           System.out.println("New status: " + evt.getNewValue());
        }
    }
});

示例(已更新以使用PropertyChangeListener)

这是一个完整的示例。请注意,如果工人停止了,则无法再暂停或恢复它。

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class Demo {

    private void createAndShowGUI() {

        final JTextArea textArea = new JTextArea(20, 50);

        final PausableSwingWorker<Void, String> worker = new PausableSwingWorker<Void, String>() {
            @Override
            protected Void doInBackground() throws Exception {
                while (!isCancelled()) {
                    if (!isPaused()) {
                        publish("Writing...");
                    } else {
                        Thread.sleep(200);
                    }
                }
                return null;
            }

            @Override
            protected void process(List<String> chunks) {
                String text = String.format("%s%n", chunks.get(chunks.size() - 1));
                textArea.append(text);
            }
        };

        worker.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if ("paused".equals(evt.getPropertyName())) {
                    String text = (Boolean)evt.getNewValue() ? "Paused..." : "Resumed...";
                    textArea.append(String.format("%s%n", text));
                }
            }
        });

        Action pause = new AbstractAction("Pause") {
            @Override
            public void actionPerformed(ActionEvent e) {
                worker.pause();
            }
        };

        Action resume = new AbstractAction("Resume") {
            @Override
            public void actionPerformed(ActionEvent e) {
                worker.resume();
            }
        };

        Action stop = new AbstractAction("Stop") {
            @Override
            public void actionPerformed(ActionEvent e) {
                worker.cancel(true);
            }
        };

        JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        buttonsPanel.add(new JButton(pause));
        buttonsPanel.add(new JButton(resume));
        buttonsPanel.add(new JButton(stop));

        JPanel content = new JPanel(new BorderLayout(8, 8));
        content.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
        content.add(new JScrollPane(textArea), BorderLayout.CENTER);
        content.add(buttonsPanel, BorderLayout.SOUTH);

        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                if (!worker.isDone()) {
                    worker.cancel(true);
                }
                e.getWindow().dispose();
            }
        });

        frame.add(content);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        worker.execute();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Demo().createAndShowGUI();
            }
        });
    }

    abstract class PausableSwingWorker<K, V> extends SwingWorker<K, V> {

        private volatile boolean isPaused;

        public final void pause() {
            if (!isPaused() && !isDone()) {
                isPaused = true;
                firePropertyChange("paused", false, true);
            }
        }

        public final void resume() {
            if (isPaused() && !isDone()) {
                isPaused = false;
                firePropertyChange("paused", true, false);
            }
        }

        public final boolean isPaused() {
            return isPaused;
        }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

SwingWorker不执行doInBackGround()

来自分类Dev

SwingWorker无法正确运行doInBackground

来自分类Dev

执行SwingWorker doInBackground时的用户输入

来自分类Dev

AysncTask doInBackground()与ToggleButton和EditText

来自分类Dev

如何在SwingWorker的doInBackground()中停止调用的静态方法

来自分类Dev

致命异常AsyncTask#1和Android doInBackground()

来自分类Dev

致命异常AsyncTask#1和Android doInBackground()

来自分类Dev

暂停和恢复功能

来自分类Dev

暂停和恢复BackgroundWorker

来自分类Dev

暂停和恢复下载

来自分类Dev

暂停SwingWorker

来自分类Dev

暂停和恢复圆形动画

来自分类Dev

SpriteKit暂停和恢复SKView

来自分类Dev

暂停和恢复书脊动画

来自分类Dev

Libgdx中的暂停和恢复

来自分类Dev

Swift:暂停和恢复NSTimer

来自分类Dev

如何暂停和恢复流程

来自分类Dev

Android AsyncTask / doInBackground模式

来自分类Dev

在doInbackground时显示进度

来自分类Dev

调用doInBackground的NoSuchMethodException

来自分类Dev

doInBackground 不更新变量

来自分类Dev

无法从 doInBackground 获取数据

来自分类Dev

摇摆动画暂停和恢复

来自分类Dev

如何暂停和恢复jQuery间隔

来自分类Dev

状态恢复,如何拦截和暂停SKScene

来自分类Dev

停止,中断,暂停和恢复Java线程

来自分类Dev

暂停和恢复线程活动

来自分类Dev

如何暂停和恢复UIView.animateWithDuration

来自分类Dev

JMeter-按需暂停(和恢复)执行