JavaFx: NPE в Bindings.when (). Then (). В противном случае () - PullRequest
0 голосов
/ 17 декабря 2018

У меня проблема с использованием Bindings.when.then.otherwise.

Вот простой пример:

public class Controller implements Initializable {

    @FXML
    private SubController subPaneController;

    @FXML
    private Label sum;

    // Simple flag, ofc I can use any condition as "when" instead of this.
    private BooleanProperty subPaneLoaded = new SimpleBooleanProperty();

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        // ofc NPE since subPane is not yet initialized
        //sum.textProperty().bind(subPaneController.sumBinding().asString()); 

        // but here the "then" is evaluated even if "when" is false 
        sum.textProperty().bind(Bindings.when(subPaneLoaded)
                .then(subPaneController.sumBinding().asString()) // and NPE here at evaluation.
                .otherwise(""));
    }

}

public class SubController {

    /**
     * Calculates the sum of a few properties used in this controller.
     */
    IntegerBinding sumBinding() {
        return Bindings.createIntegerBinding(() -> 0);
    }

}

Проблема в том, что здесь ответ, затем или в противном случае оценивается независимо от результата при .

Я действительно не могу использовать Bindings.select() или, по крайней мере, мне не удалось заставить его работать.

Мой вспомогательный контроллер инициализируется при открытии этого модуля нажатием кнопки.Каждое изменение, внесенное в этот модуль, я хочу, чтобы оно отображалось на главном экране в виде текста метки и, конечно, обновлялось live , поэтому я хочу использовать реализацию, которую я только что показал.

Если у вас есть какие-либо другие предложения о том, как решить проблему обновления в реальном времени без NPE, я буду признателен за это.

Простое связывание не является для меня решением, поскольку я не могу использоватьэто сторонний фреймворк.

Я использую Java 1.8.0_172

1 Ответ

0 голосов
/ 18 декабря 2018

У вас есть 2 способа:

1.Listener

When - это просто API-интерфейс привязки, который удобен для слушателей.Если поведение вам не подходит 1 , создайте свое собственное:

subPaneLoaded.addListener(new InvalidationListener() {
    @Override
    public void invalidated(Observable observable) {
        sum.textProperty().bind(subPaneController.sumBinding().asString());
        subPaneLoaded.removeListener(this);
    }
}); 

Когда SubController готов (если вы контролируете subPaneLoaded хорошо), вы регистрируете привязкудля метки, которая теперь гарантированно не равна нулю.Затем вы также удаляете привязку из subPaneLoaded, потому что она выполнила свою работу.

2.@FXML initialize ()

Вы можете установить привязку в методе контроллера initialize():

public class SubController { 

    @FXML
    public void initialize() {
        sum.textProperty().bind(sumBinding().asString()); 
    }

    IntegerBinding sumBinding() {
        return Bindings.createIntegerBinding(() -> 0);
    }
}

Этот метод вызывается при загрузке содержимого FXML (см. Введение в FXML ), что также следует избегать NPE.Вам просто нужен способ сделать доступным для него sum.

Я думаю, что второй подход чище.Одноразовый слушатель немного странный, но все же хорошо.


1 Стремительное поведение оценки не подходит большинству пользователей, поэтому его планируется изменить вбудущее.

...