JavaFX绑定和空值

Bal*_*551 10 data-binding javafx properties

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

我有一个属性:

private ObjectProperty<Operation> operation = new SimpleObjectProperty<>(null);
Run Code Online (Sandbox Code Playgroud)

我还有一个文本字段:

@FXML
private Text txtCurrentOperation;
Run Code Online (Sandbox Code Playgroud)

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

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

Bindings.when(operation.isNotNull())
    .then("null")
    .otherwise(operation.get().getName()));
Run Code Online (Sandbox Code Playgroud)

将抛出一个NPE,因为otherwise无论结果是什么,都会评估参数when.

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

txtCurrentOperation.textProperty().bind(() ->
        new SimpleStringProperty(
             operation.isNotNull().get() ? "Null" : operation.get().getName()
            ));
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

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

Rya*_*n J 7

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

EasyBind.select(operation)
        .selectObject(Operation::nameProperty)
        .orElse("null");
Run Code Online (Sandbox Code Playgroud)

对于EasyBind提供的功能类型,还存在JavaFX JIRA问题.如果您不想使用第三方库,请尝试Bindings.select:

Bindings.when(operation.isNotNull())
    .then("null")
    .otherwise(Bindings.select(operation, "name"));
Run Code Online (Sandbox Code Playgroud)

请注意,null检入Bindings.select不是非常有效.有一个JIRA问题.


Dar*_*ake 5

以防万一有人使用的不是 Java 本身而是 Kotlin。使用很棒的tornadofx库是个好主意。在那里你可以使用operation.select{it.name}. 虽然,这个功能似乎还没有被记录下来,所以需要一些时间来发现它。

  • @JRichardsz,javafx 对于 java 和 kotlin 都是相同的。我的观点是,如果您出于某种原因使用 kotlin,那么该问题有一个很好的解决方案。Tornadofx 只是 javafx 之上的一个库。 (3认同)