Observer不会在JavaFX GUI中运行更新 [英] Observer won't run update in JavaFX GUI

查看:167
本文介绍了Observer不会在JavaFX GUI中运行更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读了很多关于JavaFX GUI模型, Plattform-> RunLater 和Threads,但我仍然不知道如何做到这一点。我有一个JavaFX GUI,点击按钮执行一个过程并更新了Progres Bar和Label。这与Threading和Plattform运行良好,但我不得不将其更改为观察者模型。
我在Singleton模型中调用Progress Tracker,由执行该过程的类更新并且是Observable。我实现了一个Observer,它应该更新两个UI元素。

I read much about the JavaFX GUI Model, Plattform->RunLater and Threads, but i still do not figure out how to get this right. I had a JavaFX GUI wich on a button click executed a process and updated a Progres Bar and Label. This was running well with Threading and Plattform, but i had to Change this to an Observer Model. I invoke a Progress Tracker in a Singleton Model, wich gets updated by the class executing the process and is Observable. I implemented an Observer as well wich should update the two UI Elements.

带按钮事件的Gui控制器

Gui Controller with Button Event

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 {
    }
}

Progress Observer

Progress Observer

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());
        });

    }

}

Progress Tracker

Progress Tracker

    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中的Print将被执行。但是,如果我在Observer的更新中添加一个打印件,则不会打印任何内容。如果我在Progresstracker中检查,则观察者计数为1.
为什么即使调用Notify,观察者也不会得到通知或执行任何操作?我的线程和执行模式是否错误?
进度条和标签也将保持其初始值

The Print within the ProgressTracker gets executed. However, if i add a print within the update of the Observer nothing will be printed. If i check within the Progresstracker, the Observer Count is 1. Why does the Observer not get notified or execute anything, even if the Notify is called? Did i get the Threading and Execution Modell wrong? The Progress Bar and the Label will also stay on their initial values

推荐答案

不要重新发明轮子。 JavaFX Properties Pattern 是一个现成的实现Observable模式:没有必要自己实现它。此外,任务已经定义了更新各种属性的方法,这些方法可以从任何线程调用,但会在FX应用程序线程上安排实际更新。请参阅 updateProgress() updateMessage()

Don't reinvent the wheel. The JavaFX Properties Pattern is a ready-made implementation of the Observable pattern: there is no need to implement it yourself. Additionally, Task already defines methods for updating various properties, which can be called from any thread but will schedule the actual updates on the FX Application Thread. See updateProgress() and updateMessage(), for example.

所以你可以做,例如:

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 {
    }
}

这篇关于Observer不会在JavaFX GUI中运行更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆