📜  Java中的 SwingWorker(1)

📅  最后修改于: 2023-12-03 14:42:52.521000             🧑  作者: Mango

Java中的 SwingWorker

在使用Java编写GUI程序时,经常需要在后台线程中处理耗时的任务,例如网络请求或磁盘I/O操作。这些任务如果在主线程中执行会导致GUI界面无响应或卡死,给用户带来不好的体验。为了解决这个问题,Java提供了SwingWorker类。

SwingWorker的作用

SwingWorker是一个抽象类,它允许将长时间运行的任务放在后台线程中,而不会阻塞用户界面。SwingWorker主要用于以下两个方面:

  • 执行耗时的后台任务
  • 处理后台任务执行完毕后的结果

SwingWorker不仅可以在后台线程中执行任务,而且还可以与Swing框架进行交互,例如在后台任务完成后更新进度条或将结果呈现在GUI界面上。

SwingWorker的使用方法

SwingWorker是一个泛型类,需要使用两个类型参数:第一个是任务的执行结果类型,第二个是任务执行过程中产生的数据类型(可选)。如果后台任务不会产生额外的数据,则第二个类型参数可以为Void。

实现SwingWorker

实现SwingWorker需要继承它,并重写doInBackground和done方法。

doInBackground方法用于执行后台任务。它不应该直接访问GUI组件,因为它是在后台线程中执行的。如果需要更新GUI组件,可以使用publish和process方法。

done方法用于处理任务执行完毕后的结果。它可以访问GUI组件,因为它会在EDT线程中执行。

class MySwingWorker extends SwingWorker<Integer, String> {
    @Override
    protected Integer doInBackground() throws Exception {
        // 执行后台任务
        return 0;
    }
 
    @Override
    protected void done() {
        // 处理任务执行完毕后的结果
    }
}
启动SwingWorker

启动SwingWorker只需要调用execute方法即可。execute方法会启动一个新的线程来执行doInBackground方法。

MySwingWorker worker = new MySwingWorker();
worker.execute();
更新GUI组件

SwingWorker提供了publish和process方法来更新GUI组件。

publish方法用于在后台线程中发布中间结果,它接受一个可变参数,表示任务执行过程中产生的数据。publish方法会将数据传递给process方法。

class MySwingWorker extends SwingWorker<Integer, String> {
    @Override
    protected Integer doInBackground() throws Exception {
        // 执行后台任务
        publish("中间结果1");
        publish("中间结果2");
        return 0;
    }
 
    @Override
    protected void process(List<String> chunks) {
        // 更新GUI组件
        for (String chunk : chunks) {
            // 更新GUI组件
        }
    }
 
    @Override
    protected void done() {
        // 处理任务执行完毕后的结果
    }
}

process方法用于在EDT线程中更新GUI组件,它接受一个List类型的参数,表示在后台线程中发布的中间结果。process方法会将中间结果逐个传递给它,开发者可以在其中更新GUI组件。

获取任务执行结果

在done方法中可以调用get方法来获取任务执行的结果。get方法会阻塞线程,直到任务执行完毕并返回结果。get方法还可以处理异常,例如任务执行过程中发生了异常。

class MySwingWorker extends SwingWorker<Integer, String> {
    @Override
    protected Integer doInBackground() throws Exception {
        // 执行后台任务
        return 0;
    }
 
    @Override
    protected void done() {
        try {
            int result = get();
            // 处理任务执行完毕后的结果
        } catch (InterruptedException e) {
            // 处理异常
        } catch (ExecutionException e) {
            // 处理异常
        }
    }
}
总结

SwingWorker是一个非常实用的工具类,它可以将耗时的任务放在后台线程中执行,避免阻塞用户界面。使用SwingWorker需要继承它并重写doInBackground和done方法,启动SwingWorker只需要调用execute方法。SwingWorker还可以与Swing框架进行交互,例如更新GUI组件和处理任务执行结果。