Observer won't run update in JavaFX GUI

吃可爱长大的小学妹 提交于 2019-12-12 03:33:43

问题


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

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

    public synchronized void setTracker(int currentStep, String currentStatus) {

    checkInstance();
    instance.step = currentStep;
    instance.status = currentStatus;
    instance.notifyObservers();
    System.out.println(instance.countObservers());
}

Creator

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

}

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


回答1:


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.

So you can do, 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 ;

}

and

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


来源:https://stackoverflow.com/questions/43095744/observer-wont-run-update-in-javafx-gui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!