【发布时间】:2021-02-17 03:45:55
【问题描述】:
我阅读了很多关于 JavaFX GUI 模型、Plattform->RunLater 和线程的信息,但我仍然不知道如何正确处理。我有一个 JavaFX GUI,单击按钮即可执行进程并更新进度条和标签。这在线程和平台上运行良好,但我不得不将其更改为观察者模型。
我在单例模型中调用进度跟踪器,该模型由执行流程的类更新并且是可观察的。我还实现了一个观察者,它应该更新两个 UI 元素。
带有按钮事件的 GUI 控制器
private void createKeyPressed(ActionEvent event) {
// Make Progressbar visible
pbKeyProgress.visibleProperty().set(true);
if (!Check.keyFileExistant() || cbKeyOverwrite.selectedProperty().get()) {
ProgressTracker.getTracker().addObserver(new ProgressObserver(pbKeyProgress, lblKeyProgress));
Creator.createKey(cbKeyLength.getValue());
} else {
}
}
进度观察者
public class ProgressObserver implements Observer {
private final ProgressBar progressBar;
private final Label statusLabel;
public ProgressObserver(ProgressBar progressBar, Label statusLabel) {
this.progressBar = progressBar;
this.statusLabel = statusLabel;
}
@Override
public void update(Observable o, Object o1) {
Platform.runLater(() -> {
System.out.println("Tracker set to "+ProgressTracker.getProgress() + " " + ProgressTracker.getStatus());
progressBar.setProgress(ProgressTracker.getProgress());
statusLabel.setText(ProgressTracker.getStatus());
});
}
}
进度跟踪器
public synchronized void setTracker(int currentStep, String currentStatus) {
checkInstance();
instance.step = currentStep;
instance.status = currentStatus;
instance.notifyObservers();
System.out.println(instance.countObservers());
}
创作者
public static void createKey(String length) {
Task<Void> task;
task = new Task<Void>() {
@Override
public Void call() throws Exception {
initTracker(0,"Start");
doStuff();
ProgressTracker.getTracker().setTracker(1,"First");
doStuff();
ProgressTracker.getTracker().setTracker(2,"Second");
// and so on
return null;
}
};
new Thread(task)
.start();
}
ProgressTracker 中的打印被执行。但是,如果我在 Observer 的更新中添加打印,则不会打印任何内容。如果我在 Progresstracker 中检查,观察者计数为 1。
为什么 Observer 没有得到通知或执行任何操作,即使 Notify 被调用?我把线程和执行模型弄错了吗? 进度条和标签也将保持其初始值。
【问题讨论】:
-
我推荐你阅读that的文章。
-
线程看起来都正确。错误可能在您的代码中的其他地方(如果您无法弄清楚,请尝试创建minimal reproducible example)。不过,您实际上是在重新发明轮子:JavaFX properties pattern 是观察者模式的现成实现,使用起来比编写自己的实现要方便得多。您也可以调用任务的
updateProgress()和updateMessage()方法,然后只需将进度条和标签绑定到任务的相应属性即可。
标签: multithreading javafx observers