【发布时间】:2014-06-11 22:43:50
【问题描述】:
我正在开发一个桌面 GUI 应用程序。我目前正在使用 Swing,但我希望将来能够将其移植到 JavaFX 或 Android。
目前,我正在努力实现一个“与 UI 无关”的后台任务类:目标是能够从应用程序的核心包(不依赖于特定的 GUI)提交后台任务并观察进度任务,如果有 GUI(使用 GUI 特定的进度条等)。
Swing 有 SwingWorker<T, V> (link),JavaFX 有 Task<V> (link),Android 有 AsyncTask<Params, Progress, Result> (link)。它们都具有相同的用途,实际上具有相似的 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 中的 Task 和 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 的 computeResult() 中调用 SwingWorker 的 publish(partialResult)。因此,我的用户永远不会看到后台任务的有意义的进展。当然我可以使用不确定的进度条,但我不喜欢它们。
我怎样才能克服这个问题并制作一个通用的后台任务?
【问题讨论】:
-
您的任务可以提供一个回调/侦听器/观察者接口,核心实现可以注册到该接口,这样您的
Task将能够引发事件,侦听器会拾取并采取行动 -
您的评论实际上是一个可以接受的答案,谢谢。
标签: java swing oop swingworker