暂停和恢复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; } }}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)