我正在学习如何在JavaFX中使用Task
。我试图找出Task
的设计模式,以便不断更新应用程序线程使用的ArrayList
。
以下是我到目前为止的代码。它有效,但我想确保我遵循最佳做法。这是一个合适的设计模式吗?如果没有,你能建议一个更好的方法吗?
最终,我的目标是使用长时间运行Canvas
生成的像素数据更新Task
,但希望首先在简单的案例中获得设计模式。
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
import java.util.List;
interface Updateable {
public void update(List<Integer> data);
}
public class TaskExample extends Application implements Updateable {
private ListView<Integer> list_view = new ListView<>();
public void update(List<Integer> data) {
list_view.getItems().clear();
list_view.getItems().addAll(data);
}
@Override
public void start(Stage primaryStage) throws Exception {
MyTask task = new MyTask(this);
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
primaryStage.setScene(new Scene(list_view));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class MyTask extends Task<Void> {
private ObservableList<Integer> data = FXCollections.observableArrayList();
private Updateable ui;
public MyTask(Updateable ui) {
this.ui = ui;
addListener();
}
@Override
protected Void call() throws InterruptedException {
for (int i=0; i<10; i++) {
Thread.sleep(1000);
data.add(i);
}
return null;
}
private void addListener() {
data.addListener((ListChangeListener.Change<? extends Integer> c) -> {
Platform.runLater(() -> {
ui.update(data);
});
});
};
}
根据@ James_D的评论更新了MyTask
class MyTask extends Task<Void> {
private ObservableList<Integer> data = FXCollections.observableArrayList();
private Updateable ui;
public MyTask(Updateable ui) {
this.ui = ui;
addListener();
}
@Override
protected Void call() throws InterruptedException {
for (int i=0; i<10; i++) {
Thread.sleep(1000);
final int j = i;
Platform.runLater(() -> {
data.add(j);
});
}
return null;
}
private void addListener() {
data.addListener((ListChangeListener.Change<? extends Integer> c) -> {
ui.update(data);
});
};
}