我有一个基本的Swing UI,带有一个标记为“播放”的按钮。按下按钮后,标签变为“暂停”。现在,当按下按钮时,它变为“继续”。
在“播放”中,我将实例化并执行一个SwingWorker。我想要的是能够暂停该线程(不要取消该线程),并根据上述按钮按下来恢复它。但是,我不想在doInBackground()中求助于Thread.sleep()。这似乎有点骇人听闻。有什么方法可以阻止运行doInBackground的线程?
暂停和恢复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());
}
}
});
这是一个完整的示例。请注意,如果工作者已停止,则无法再暂停或恢复它。
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;
}
}
}
我要做的是暂停< code>KafkaConsumer,如果在使用消息的过程中出现错误。 这是我写的 然后我写了一个REST服务来恢复消费者 现在,我有两个问题。第一个问题:当我打电话给消费者时。来自<code>@KafkaListener</code>注释方法的pause()会发生什么?消费者立即暂停,或者我可以接收到同一主题分区的其他偏移量上的其他消息。例如,我有偏移量为3的“message1
问题内容: 我在viewDidAppear中有一个图像,并用以下代码对其进行了动画处理: 我想在点击时暂停动画,如果再次点击它则继续播放动画。 问题答案: 暂停和恢复动画的2个功能,我从这里开始转换为Swift。 我有一个按钮可以暂停或恢复在中初始化的动画:
嗨,我在camel中有一个JMS消费者路由,我的要求是在特定事件时停止/暂停该路由(基于某个字段值),然后使用调度器恢复该路由。为此,我创建了两个路由,一个是我的原始jms消费者路由,另一个是调度程序路由,它们恢复jms消费者路由,虽然我能够暂停路由,但第二个路由不恢复暂停的路由,它显示的状态为已启动。 以下是我的两条路线 请帮助我如何实现上述场景。
有些情况下,例如爬取大的站点,我们希望能暂停爬取,之后再恢复运行。 Scrapy通过如下工具支持这个功能: 一个把调度请求保存在磁盘的调度器 一个把访问请求保存在磁盘的副本过滤器[duplicates filter] 一个能持续保持爬虫状态(键/值对)的扩展 Job 路径 要启用持久化支持,你只需要通过 JOBDIR 设置 job directory 选项。这个路径将会存储 所有的请求数据来保持一
问题内容: 我正在开发游戏,我想创建一个暂停菜单。这是我的代码: 但 仍在运行… 我想在玩家单击暂停菜单时暂停计时器,并在玩家返回游戏时继续运行计时器,但是我如何暂停?请帮帮我。 问题答案: 您需要使其无效并重新创建。然后,如果您使用相同的按钮暂停和恢复计时器,则可以使用bool来跟踪状态:
问题内容: 我注意到,有很多主题是有关使用暂停/恢复MP3的,因此为了帮助所有人,我专门为此设计了整个课堂!请参阅下面的答案。 注意:这是供我个人使用的,因此它可能不如某些人希望的那样健壮。但是由于其简单性,进行简单的修改并不难。 问题答案: 播放器的一个非常简单的实现,实际上是暂停播放。它通过使用单独的线程播放流并告诉播放器线程是否/何时暂停和继续工作来工作。