Sử dụng Platform.runLater(...)
cho các hoạt động nhanh chóng và đơn giản và Task
cho các hoạt động phức tạp và lớn.
Ví dụ: Tại sao chúng ta không thể sử dụng Platform.runLater(...)
cho các phép tính dài (Lấy từ tài liệu tham khảo bên dưới).
Vấn đề: Chuỗi nền chỉ đếm từ 0 đến 1 triệu và cập nhật thanh tiến trình trong giao diện người dùng.
Mã sử dụng Platform.runLater(...)
:
final ProgressBar bar = new ProgressBar();
new Thread(new Runnable() {
@Override public void run() {
for (int i = 1; i <= 1000000; i++) {
final int counter = i;
Platform.runLater(new Runnable() {
@Override public void run() {
bar.setProgress(counter / 1000000.0);
}
});
}
}).start();
Đây là một đoạn mã ghê tởm, một tội ác chống lại thiên nhiên (và lập trình nói chung). Đầu tiên, bạn sẽ mất các tế bào não khi chỉ nhìn vào tổ hợp các Runnables kép này. Thứ hai, nó sẽ làm tràn ngập hàng đợi sự kiện với ít Runnables - thực tế là một triệu trong số chúng. Rõ ràng, chúng tôi cần một số API để giúp dễ dàng hơn khi viết các công cụ nền sau đó giao tiếp lại với giao diện người dùng.
Mã sử dụng Tác vụ:
Task task = new Task<Void>() {
@Override public Void call() {
static final int max = 1000000;
for (int i = 1; i <= max; i++) {
updateProgress(i, max);
}
return null;
}
};
ProgressBar bar = new ProgressBar();
bar.progressProperty().bind(task.progressProperty());
new Thread(task).start();
nó không mắc phải lỗi nào trong mã trước
Tham khảo:
Worker Threading trong JavaFX 2.0