SwingWoker线程杂记
简介
SwingWorker有两个参数即SwingWorker< T,V>,T是doInBackground和get方法的返回类型;V是publish和process方法要处理的数据类型
SwingWorker中的方法
方法:返回类型 | 作用或结果 |
---|---|
#doInBackground (): T | 执行任务并返回T类型的结果 |
+excute(): void | 安排SwingWorker线程来执行工作线程 |
+get(): T | 等待SwingWorker完成后在主线程中调用该方法返回doInBackground()结果 |
+isDone(): boolean | 主线程调用,doInBackground()完成后返回ture,否则false |
+cancel(): boolean | 按传入的参数决定是否取消任务 |
#publish(V data): void | 发送process方法要处理的数据。这个方法用于从doInBackground中传送之间结果,以处理process方法中的事件分发线程。注意,v…表示变种参数 |
#process(): void | 异步的接受事件分发线程来自publish方法传来的数据 |
#setProgress(): void | 设置进展属性,传入参数应为int类型0到100 |
#getProgress(): void | 返回进展约束属性 |
SwingWorker简单应用
import javax.swing.*;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
public Main{
public static void main(String[] args) {
SwingUtilities.invokeLater(
new Runnable() {
@Override
public void run() {
createGUI();
}
}
);
}
public static void creatGUI() {
JFrame jf = new JFrame("测试窗口");
jf.setSize(300, 300);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
final JLabel label = new JLabel("正在下载: 0%");
panel.add(label, BorderLayout.NORTH);
final JTextArea textArea = new JTextArea();
panel.add(textArea, BorderLayout.CENTER);
jf.setContentPane(panel);
jf.setVisible(true);
// 创建后台任务
SwingWorker<String, Integer> task = new SwingWorker<String, Integer>() {
@Override
protected String doInBackground() throws Exception {
for (int i = 0; i < 100; i += 10) {
// 延时模拟耗时操作
Thread.sleep(1000);
// 设置 progress 属性的值(通过属性改变监听器传递数据到事件调度线程)
setProgress(i); // 缺少该方法仍能运行,setProgress()作用为:设置进展约束属性。这个值应该从0到100
// 通过 SwingWorker 内部机制传递数据到事件调度线程
publish(i);
}
// 返回计算结果
return "下载完成";
}
@Override
protected void process(List<Integer> chunks) {
// 此方法在 调用 doInBackground 调用 public 方法后在事件调度线程中被回调
Integer progressValue = chunks.get(0);
textArea.append("已下载: " + progressValue + "%\n");
}
@Override
protected void done() {
// 此方法将在后台任务完成后在事件调度线程中被回调
String result = null;
try {
// 获取计算结果
result = get();// get返回doInBackground()返回类型
} catch (Exception e) {
e.printStackTrace();
}
label.setText(result);
textArea.append(result);
}
};
// 添加属性改变监听器
task.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
Object progressValue = evt.getNewValue();
label.setText("正在下载: " + progressValue + "%");
}
}
});
// 启动任务
task.execute();
}
}
以上代码改编自https://blog.csdn.net/xietansheng/article/details/78389265
注:doInBackground方法作为任务线程的一部分执行,它负责完成线程的基本任务,并以返回值来作为线程的执行结果。继承类须覆盖该方法并确保包含或代理任务线程的基本任务。不要直接调用该方法,应使用任务对象的execute方法来调度执行。
当从任务线程调用publish方法时,SwingWorker类调度process方法,如果SwingWorker通过publish发布了一些数据,那么也应该实现process方法来处理这些中间结果,任务对象的父类会在事件分发线程上激活process方法,因此在此方法中程序可以安全的更新UI组件。
无论何时调用setProgress方法,SwingWorker类都会产生一个propertyChangeEvent。setProgress方法设置一个0到100之间的新的进度值,这个值包装在PropertyChangeEvent中,这个事件的监听器使用getNewValue()方法获取进度值。
刚写博客各位多支持以下鸭