SwingWorker 简单使用方法

SwingWorker 设计用于需要在后台线程中运行长时间运行任务的情况,并可在完成后或者在处理过程中向 UI 提供更新。SwingWorker 的子类必须实现 doInBackground() 方法,以执行后台计算。

工作流

SwingWorker 的生命周期中包含三个线程:

当前 线程:在此线程上调用 execute() 方法。它调度 SwingWorker 以在 worker 线程上执行并立即返回。可以使用 get 方法等待 SwingWorker 完成。

  • Worker 线程:在此线程上调用 doInBackground() 方法。所有后台活动都应该在此线程上发生。要通知 PropertyChangeListeners 有关绑定 (bound) 属性的更改,请使用 firePropertyChange 和 getPropertyChangeSupport() 方法。默认情况下,有两个可用的绑定属性:state 和 progress。

  • 事件指派线程:所有与 Swing 有关的活动都在此线程上发生。SwingWorker 调用 process 和 done() 方法,并通知此线程的所有 PropertyChangeListener。

  • 通常,当前 线程就是事件指派线程。

例如很多大型软件在启动的时候,界面会显示正在加载XXX模块,要实现类似功能的时候,SwingWorker会非常方便。

使用方法:
实现一个SwingWorker的子类,并重写需要的方法,在工作线程中实例化一个该子类,调用execute()以启动任务。

  • 需要重写的方法:

    1. doInBackground():必须重写,任务的逻辑代码。
    2. done():任务完成以后的操作,此方法在EDT内部。
    3. process():规定相应进度如何显示(例如更新一个组件以显示当前进度),此方法在EDT内部。
    4. 构造方法。
      除了构造方法以外,所有方法都不应该在代码内被显式的调用,相应的线程会自动调用它们。
  • 需要使用的方法:

    1. get():获取任务结束以后的最后结果,这个方法应该放置在done()的内部。
    2. publish():发布进度,这个方法应该位于doInBackground()内部。

    例:

import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.*;

public class Test extends SwingWorker<Integer,Integer>{

    private JFrame window;
    private JTextField text;

    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                new Test().execute();
            }
        });
    }

    Test(){
        window = new JFrame();
        window.setVisible(true);
        window.setSize(150, 150);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        text = new JTextField();
        window.add(text);
    }

    @Override
    protected Integer doInBackground() throws Exception {
        if(SwingUtilities.isEventDispatchThread())
            System.out.println("doInBackground()在EDT");
        int i=0;
        while(i!=100){
            Thread.sleep(100);
            publish(i++);
        }
        return i;
    }

    @Override
    protected void done() {
        if(SwingUtilities.isEventDispatchThread())
            System.out.println("done()在EDT");
        try {
            System.out.println("任务结束了,done(),结果为"+get());
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    protected void process(List<Integer> chunks) {
        if(SwingUtilities.isEventDispatchThread())
            System.out.println("process()在EDT");
        for(int i:chunks){
            text.setText(String.valueOf(i));
        }
    }

}
  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值