JavaFX binding and null values

I was wondering how to bind values ​​where the binding source can be null.

I have a property:

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

I also have a text box:

 @FXML private Text txtCurrentOperation; 

I would like to bind textProperty fields to the value of the work object.

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

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

will cause NPE, because the otherwise parameter is evaluated regardless of the result of when .

My next idea was to use lambda somehow:

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

But the binding does not have the solution allowed by the lambda. (Later, I realized that this cannot be, because the real work goes backward: changing a related object (operation) will lead to updating the binder (a property of the field text).)

In some articles, I suggested using an “extreme” value for a property instead of null. But the operation is a complex and heavy component, so it’s easy to build an artificial instance to represent null. Moreover, it seems to me boilercode that the binding mechanism is designed to help eliminate.

My next attempt was to logically change the direction of the binding and add a listener to the property of the operation and allow it to update the field programmatically. It works and is quite simple, while the need for updating depends only on instances of the operation object:

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

It is relatively simple, but it doesn’t work: it throws out “The bound value cannot be set”. an exception, and I don’t understand why the text property of the control is considered bound.

I'm out of ideas. After a long search, I still can not solve a simple problem to update the text field in different ways depending on whether the source is zero or not.

It seems such a simple and everyday problem that I'm sure I missed this solution.

+8
properties data-binding javafx
source share
2 answers

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

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

There is also a JavaFX JIRA issue for the type of functionality provided by EasyBind. If you do not want to use a third-party library, try Bindings.select :

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

Remember that zero checking in Bindings.select not super efficient. There is a jira problem for him .

+6
source share

Just in case, if someone uses not Java itself, but Kotlin. It is a good idea to use the wonderful tornadofx library. There you can simply use operation.select{it.name} . Although, this feature does not seem to have been documented yet, so it took a while to detect it.

0
source share

All Articles