JavaFX绑定和空值 [英] JavaFX binding and null values

查看:939
本文介绍了JavaFX绑定和空值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我有一个属性:

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

我还有一个文本字段:

  @FXML 
private Text txtCurrentOperation;

我想绑定 textProperty 我的第一个想法是使用FluentAPI及其/ when / else构造,但是它是热切的评估,所以解决方案:

  Bindings.when(operation.isNotNull())
.then(null)
。否则(operation.get()。getName()));

将抛出NPE,因为的参数否则

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

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



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



我的下一个尝试是逻辑交换绑定方向,并添加监听器到操作属性并让它以编程方式更新该字段。它的工作原理很简单,只要更新的需要只取决于操作对象实例:

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

它比较简单,但不起作用:它抛出绑定值无法设置。 例外,我不明白为什么控件的text属性被视为有约束力。



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



这看起来很简单和日常的问题,我确定我错过了解决方案。

解决方案

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

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

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

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

请注意中的空值检查Bindings.select 不是超级有效。 JIRA问题


I was wondering how to bind values where the source of the bind could be null.

I have a property:

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

I also have a text field:

@FXML
private Text txtCurrentOperation;

I would like to bind the textProperty of the field to the value of the operation object.

My first thought was to use FluentAPI with its when/then/otherwise construct, but it is eagerly evaluated so the solution:

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

will throw a NPE, because the parameter of otherwise is evaluated no matter what the result of the when.

My next idea was to use lambda somehow:

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

But the bind has no lambda enabled solution. (Later I realized that it couldn't have, becasue the real work goes backward: the change of the binded object (operation) will trigger the update of the binder (the field text property).)

Some articles I found suggested to use an "extremal" value for the property instead of null. But Operation is a complex and heavy weight component so it is not trivial to construct an artifical instance to represent null. Even more, this seems to me boilercode, something the binding mechanism is designed to help eliminating.

My next try was to logically swap the binding direction and add listener to the operation property and let it update the field programatically. It works and rather simple as long as the need of update only depends the operation object instances:

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

It is relatively simple, but doesn't work: it throws "A bound value cannot be set." exception and I don't see why is the text property of the control regarded as bound.

I ran out of ideas. After much searching, I still cannot solve the simple problem to update a text field differently based on whether the source is null or not.

This seems so simple and everyday problem, that I am sure I missed the solution.

解决方案

If a 3rd party library is an option, check out EasyBind. Try something like this:

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

There's also a JavaFX JIRA issue for the type of functionality provided by EasyBind. If you don't want to use a 3rd party library, try Bindings.select:

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

Be aware the null checking in Bindings.select isn't super efficient. There's a JIRA issue for it.

这篇关于JavaFX绑定和空值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆