我读了很多关于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中的打印。但是,如果我在观察者的更新中添加打印,则不会打印任何内容。如果我在Progresstracker中进行检查,观察者计数为1。
为什么观察者没有得到通知或执行任何东西,即使调用了Notify?线程和执行模块出错了吗?进度条和标签也将停留在它们的初始值上。
不要推倒重来。JavaFX属性模式是可观察模式的现成实现:不需要自己实现它。此外,task
已经定义了用于更新各种属性的方法,可以从任何线程调用这些属性,但将在FX应用程序线程上安排实际更新。例如,请参见updateProgress()
和updateMessage()
。
因此您可以执行以下操作,例如:
public static Task<Void> createKey(String length) {
Task<Void> task;
task = new Task<Void>() {
final int totalSteps = ... ;
@Override
public Void call() throws Exception {
updateProgress(0, totalSteps);
updateMessage("Start");
doStuff();
updateProgress(1, totalSteps);
updateMessage("First");
doStuff();
updateProgress(2, totalSteps);
updateMessage("Second");
// and so on
return null;
}
};
new Thread(task)
.start();
return task ;
}
而且
private void createKeyPressed(ActionEvent event) {
// Make Progressbar visible
pbKeyProgress.visibleProperty().set(true);
if (!Check.keyFileExistant() || cbKeyOverwrite.selectedProperty().get()) {
Task<Void> task = Creator.createKey(cbKeyLength.getValue());
pbKeyProgress.progressProperty().bind(task.progressProperty());
lblKeyProgress.textProperty().bind(task.messageProperty());
} else {
}
}
如果我在windows的命令行上执行我的python脚本,它运行得很好,但是当我在bash上运行它时,它只是一直在等待另一行,但是如果我尝试其他命令,比如,它会显示:
我目前正在做一个项目,在这个项目中,我将时间转换为基数10时间(本质上,它最终会显示已经过去的一天的百分比。例如:中午12:00将显示为基数10时间的50.00)。目前,我知道我的算法是正确的,因为如果我把它打印到控制台,它会正确地打印出来,但是由于某种原因,我无法显示我的图形用户界面。如果我删除了试图不断更新GUI以显示正确数字的部分,GUI显示良好,但没有数字。我的代码如下: 有人知道我将如何
我有使用selenium测试web服务器junit测试。当我使用ant从命令行运行测试时,一切工作正常,浏览器打开,测试按计划进行。浏览器打开,我可以看到测试正在运行。最近,我尝试添加自动测试,作为运行在Jenkins上的Ci循环的一部分。我以ant build命令运行它。我可以看到ant正在正常执行(测试类已经构建,我可以看到从测试到控制台的输出),但浏览器窗口从未打开,因此测试失败。这是我的a
我最近在我的Mac上下载了JDK7U25(我运行的是OSX10.7.5)用于我的java developers类。在http://www.Oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html从Oracle下载了.dmg文件并成功安装了软件包之后,我尝试在Library>Java>JavaVirtualMac
我有一个JAR文件,它在运行时输出一些东西到终端上。但是,当我双击JAR文件时,什么也没有发生,我的Mac告诉我检查控制台可能的错误,我什么也没有发现。 另一方面,从终端运行JAR工作正常,并且JAR按预期运行。 我正在使用IntelliJ构建我的JAR,我确信我的配置对于构建一个JAR文件是正确的。
我怎么让它工作?