如何实现UI不可知的后台工作者任务

时间:2014-06-11 22:43:50

标签: java swing oop swingworker

我正在开发桌面GUI应用程序。我目前正在使用Swing,但我希望将来能够将它移植到JavaFX或Android。

目前,我正在努力实现一个后台任务类,它将是" UI不可知的":目标是能够从应用程序的核心软件包中提交后台任务(不是取决于特定的GUI)并观察任务的进度,如果有GUI(使用GUI特定的进度条等)。

Swing有SwingWorker<T, V>link),JavaFX有Task<V>link),Android有AsyncTask<Params, Progress, Result>({{3} })。它们都有相同的用途,实际上也有类似的API。

此界面为后台任务提供了必要的功能,实际上可以在所有提到的工具包中找到。

public interface BackgroundTask<Result, PartialResult> {

    /**
     * This is where the background computation belongs. Background thread.
     * <p>
     * Equivalent of {@link javax.swing.SwingWorker#doInBackground()}, {@link javafx.concurrent.Task#call()}
     * and {@link android.os.AsyncTask#doInBackground()}.
     */
    public Result computeResult();

    /**
     * Can be called from {@link #computeResult()} to update GUI with partial
     * results. Background thread.
     * <p>
     * Equivalent of {@link javax.swing.SwingWorker#publish(Object[])}, and
     * {@link android.os.AsyncTask#publishProgress(Progress)} (sort of). The equivalent in
     * JavaFX is not just a simple method.
     */
    public void partialUpdate(PartialResult... partials);

    /**
     * Called to process partial results. UI thread.
     * <p>
     * Equivalent of {@link javax.swing.SwingWorker#process(java.util.List)} and
     * {@link android.os.AsyncTask#onProgressUpdate(Progress)}
     */
    public void onPartialResult(List<PartialResult> partials);
}

我的后台任务将实现此界面。我需要一些代码将BackgroundTask的实例转换为Swing中的SwingWorker(JavaFX中的任务和以后的Android中的AsyncTask)。

直接实施如下:

public class SwingBackgroundTask<Result, PartialResult> extends SwingWorker<Result, PartialResult> {
    private final BackgroundTask<Result, PartialResult> task;

    public SwingBackgroundTask(BackgroundTask<Result, PartialResult> task) {
        this.task = task;
    }

    @Override
    protected Result doInBackground() throws Exception {
        return task.computeResult();
    }

    @Override
    protected void process(List<PartialResult> chunks) {
        task.onPartialResult(chunks);
    }
}

然而,它没用。显然,我无法从BackgroundTask的publish(partialResult)内部调用SwingWorker computeResult()。因此,我的用户永远不会看到后台任务的有意义进展。当然,我可以使用不确定的进度条,但我不喜欢它们。

如何克服此问题并制作通用后台任务?

1 个答案:

答案 0 :(得分:1)

当您尝试将流程与特定实施方案分离时,您需要提供某种API,以便您能够以统一的方式提供反馈。

可能最简单的方法是为Task类提供某种观察者/听众,感兴趣的各方可以注册通知,Task可以用来提供反馈。

这将允许Task引发有关给定状态更改或其他通知的事件,并且实现将能够以特定于实现的方式处理...