当前位置: 首页 > 知识库问答 >
问题:

Observer不会在JavaFX GUI中运行update

皇甫德庸
2023-03-14

我读了很多关于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?线程和执行模块出错了吗?进度条和标签也将停留在它们的初始值上。

共有1个答案

司空兴为
2023-03-14

不要推倒重来。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文件是正确的。

  • 我怎么让它工作?