JavaFX绑定和空值

时间:2014-09-19 15:20:08

标签: data-binding properties javafx

我想知道如何绑定绑定源可能为null的值。

我有一个属性:

private ObjectProperty<Operation> operation = new SimpleObjectProperty<>(null);

我还有一个文本字段:

@FXML
private Text txtCurrentOperation;

我想将字段的textProperty绑定到操作对象的值。

我的第一个想法是使用FluentAPI及其when / then / otherwise构造,但是热切地评估了解决方案:

Bindings.when(operation.isNotNull())
    .then("null")
    .otherwise(operation.get().getName()));

将抛出NPE,因为无论otherwise的结果如何,都会评估when的参数。

我的下一个想法是以某种方式使用lambda:

txtCurrentOperation.textProperty().bind(() ->
        new SimpleStringProperty(
             operation.isNotNull().get() ? "Null" : operation.get().getName()
            ));

但是bind没有启用lambda的解决方案。 (后来我意识到它不可能,因为真正的工作倒退了:绑定对象(操作)的更改将触发绑定器的更新(字段文本属性)。)

我发现有些文章建议使用属性的“极值”值而不是null。但是Operation是一个复杂且重量级的组件,因此构造一个表示null的人工实例并非易事。更重要的是,这似乎是我的锅炉代码,绑定机制旨在帮助消除。

我的下一个尝试是逻辑交换绑定方向并将侦听器添加到操作属性,并让它以编程方式更新字段。只要更新的需要仅取决于操作对象实例,它就可以工作而且非常简单:

 operation.addListener((e) -> {
        txtCurrentOperation.setText(operation.isNull().get() ? 
            "Null" : operation.get().getName());
 });
 operation.set(oper);

它相对简单,但不起作用:它抛出“无法设置绑定值”。异常,我不明白为什么控件的text属性被视为绑定。

我没有想法了。经过多次搜索,我仍然无法根据源是否为空来解决更新文本字段的简单问题。

这似乎是如此简单和日常的问题,我相信我错过了解决方案。

2 个答案:

答案 0 :(得分:6)

如果可以选择第三方库,请查看EasyBind。尝试这样的事情:

EasyBind.select(operation)
        .selectObject(Operation::nameProperty)
        .orElse("null");

EasyBind提供的功能类型还有JavaFX JIRA issue。如果您不想使用第三方库,请尝试Bindings.select

Bindings.when(operation.isNotNull())
    .then("null")
    .otherwise(Bindings.select(operation, "name"));

请注意Bindings.select中的空检查不是非常有效。有JIRA issue for it

答案 1 :(得分:0)

如果有人使用的不是Java本身而是Kotlin。 使用精彩的tornadofx库是个好主意。 在那里你可以使用operation.select{it.name}。虽然,这个功能似乎还没有记录,所以花了一些时间来发现它。