我想知道如何绑定绑定源可能为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属性被视为绑定。
我没有想法了。经过多次搜索,我仍然无法根据源是否为空来解决更新文本字段的简单问题。
这似乎是如此简单和日常的问题,我相信我错过了解决方案。
答案 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}
。虽然,这个功能似乎还没有记录,所以花了一些时间来发现它。