JavaFX绑定和空值
我想知道如何绑定绑定的来源可能为null的值。
我有一个属性:
private ObjectProperty<Operation> operation = new SimpleObjectProperty<>(null);
我也有一个文本字段:
@FXML private Text txtCurrentOperation;
我想将字段的textProperty
绑定到操作对象的值。
我的第一个想法是使用FluentAPI的时候/然后/否则构造,但它是热切的评价,所以解决方案:
Bindings.when(operation.isNotNull()) .then("null") .otherwise(operation.get().getName()));
会抛出一个NPE,因为不管什么时候的结果, otherwise
参数都被评估。
我的下一个想法是不知何故使用lambda:
txtCurrentOperation.textProperty().bind(() -> new SimpleStringProperty( operation.isNotNull().get() ? "Null" : operation.get().getName() ));
但绑定没有启用lambda的解决方案。 (后来我意识到它不可能有,因为真正的工作倒退:绑定对象(操作)的更改将触发活页夹(字段文本属性)的更新。)
我发现一些文章建议使用属性的“极值”值而不是null。 但是Operation是一个复杂而重量级的组件,所以构造一个人工实例来表示null是不平凡的。 更重要的是,这在我看来锅炉代码,这是一个绑定机制旨在帮助消除。
我的下一个尝试是逻辑交换绑定的方向,并添加侦听器的操作属性,并让它以编程方式更新字段。 它的工作原理相当简单,只要更新的需要只取决于操作对象实例:
operation.addListener((e) -> { txtCurrentOperation.setText(operation.isNull().get() ? "Null" : operation.get().getName()); }); operation.set(oper);
它比较简单,但不起作用:它会抛出“无法设置绑定值”。 例外,我不明白为什么控制的文本属性被视为绑定。
我跑出了想法。 经过大量的搜索,我仍然不能解决简单的问题来根据源是否为空来不同地更新文本字段。
这似乎是如此简单和日常的问题,我相信我错过了解决方案。
如果第三方库是一个选项,请检查EasyBind 。 尝试这样的事情:
EasyBind.select(operation) .selectObject(Operation::nameProperty) .orElse("null");
EasyBind提供的功能类型也有一个JavaFX JIRA问题 。 如果您不想使用第三方库,请尝试Bindings.select
:
Bindings.when(operation.isNotNull()) .then("null") .otherwise(Bindings.select(operation, "name"));
注意Bindings.select
的空检查不是超高效的。 有一个JIRA的问题 。
以防万一,如果有人不使用Java本身,但KOTLIN。 使用美妙的tornadofx库是一个好主意。 在那里你可以使用operation.select{it.name}
。 虽然这个功能似乎还没有被记录下来,所以花了一些时间来发现它。