JavaFX绑定和空值

问题描述:

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

我有一个属性:

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参数进行评估,无论when的结果是什么。

我的下一个想法是使用拉姆达莫名其妙:

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

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

我发现的一些文章建议为属性使用“极值”值而不是null。但是Operation是一个复杂而重量级的组件,因此构造一个人工实例来表示null并不是微不足道的。更重要的是,这对我来说似乎是boilercode,这个绑定机制旨在帮助消除。

我的下一个尝试是逻辑交换绑定方向,并将侦听器添加到操作属性,并让它以编程方式更新字段。它的工作原理和相当简单,只要更新只需要依赖的操作对象实例:它抛出:

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

这是比较简单的,但是不工作“A限值不能设置。”例外,我不明白为什么控件的文本属性被视为绑定。

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

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

如果第三方库是一个选项,请查看EasyBind。尝试是这样的:

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

还有一个JavaFX JIRA issue通过EasyBind提供的功能类型。如果你不希望使用第三方库,尽量Bindings.select

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

注意空在Bindings.select检查是不是超级效率。有一个JIRA issue for it

+0

感谢这两种解决方案。尽管第二个代码有小小的打字错误(在选择(操作部分)之后出现错位的右括号),但它效果很好。我阅读了关于低效率的文章,但这不是一个问题,因为单一的绑定会更改很少 另外我检查了这个库,它看起来像是在兑现,所以我可能也会试一试。 – Balage1551 2014-09-19 19:54:09

+0

另外,lambda的另一个解决方案(在EasyBind的示例中找到,但不需要库):'txtCurrentOperation。 textProperty()。bind(Bindings.createStringBinding() - > operation.isNull()。get()?“null”:operation.get()。getName(),operation));' – Balage1551 2014-09-19 20:12:29

+0

这解决了我的问题保存按钮为我的编辑器API在这里被打破 – 2017-10-05 04:56:17

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

+0

这是一个javafx的问题不是javafx vs kotlin的问题 – JRichardsz 2017-05-28 14:22:40

+0

@JRichardsz,javafx和java和kotlin是一样的我的观点是如果你由于某种原因KO特林,这个问题有一个很好的解决方案。 Tornadofx只是一个在javafx之上的库。 – Darksnake 2017-05-29 12:37:20