JavaFx:NPE at Bindings.when().then().others()

JavaFx:NPE at Bindings.when().then().others(),java,javafx,binding,nullpointerexception,javafx-8,Java,Javafx,Binding,Nullpointerexception,Javafx 8,我在使用Bindings.when.then.others时遇到问题 下面是一个简单的例子: public class Controller implements Initializable { @FXML private SubController subPaneController; @FXML private Label sum; // Simple flag, ofc I can use any condition as "when" ins

我在使用Bindings.when.then.others时遇到问题

下面是一个简单的例子:

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

}
问题的答案是,then或Other独立于when的结果进行评估

我不能真正使用Bindings.select,或者至少我没有设法让它工作

当按下按钮打开模块时,我的子控制器初始化。在该模块中所做的每一项更改,我都希望以标签文本的形式显示在主视图中,当然也希望实时更新,这就是为什么我希望使用刚才展示的实现

如果你有任何其他建议,如何解决,以实现没有NPE的实时更新,我将不胜感激

不是我的解决方案,因为我不能使用这个第三方框架

我正在使用java 1.8.0172

您有两种方法:

1.听众 When仅仅是绑定的API便利,这是侦听器的便利。如果行为不适合你1,创建自己的:

subPaneLoaded.addListener(new InvalidationListener() {
    @Override
    public void invalidated(Observable observable) {
        sum.textProperty().bind(subPaneController.sumBinding().asString());
        subPaneLoaded.removeListener(this);
    }
}); 
如果控制子面板加载良好,那么当子滚动程序准备就绪时,就为标签注册绑定,现在保证该绑定为非空。然后还可以从子面板中删除绑定,因为它已经完成了它的工作

2. @FXML初始化 您可以在控制器的initialize方法中设置绑定:

public class SubController { 

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

    IntegerBinding sumBinding() {
        return Bindings.createIntegerBinding(() -> 0);
    }
}
加载FXML内容时调用此方法,请参见,这也应该避免NPE。你只需要找到一种方法让sum可以访问它

我认为第二种方法更干净。一个一次性的倾听者有点奇怪,但仍然很好


1“急切求值”行为不适合大多数用户,因此计划在将来进行更改。

能否向我们显示堆栈跟踪/错误消息?您知道如何提问-请回答!这些解决方案或多或少都是权宜之计,我真的不想使用第二个解决方案,即使它更干净,因为我的分包商不应该知道sum标签,因为它不是唯一向该标签添加信息的控制器。第一种方法可能很好,但正如您所提到的,使用单一时间侦听器有点奇怪。@Sunflame任何解决方案都是一种变通方法,因为我们现在无法更改When的行为,而且您还要求提供任何其他建议,这基本上意味着变通方法。如果没有一个简单的答案,这就是我所能提出的全部建议。