H
H
HaruAtari2016-06-11 22:54:34
Java
HaruAtari, 2016-06-11 22:54:34

How to use regular classes in JavaFx application?

Good afternoon.
There is a java library. I need to write a gui for her. I don’t understand how to bind objects from the library to the interface without unnecessary wrappers.
The problem is that in javaxf applications, model fields that are bound to the interface must be of types javafx.beans.property.* (for example, not String, but SimpleStringProperty). And the classes in the library contain fields with ordinary strings / ints / etc. How it is possible to bind these objects to the interface?
The only thing that came to my mind was to write a wrapper for each class that will convert types. But it's too hard for every class to make them.
Tell me, how is this problem solved?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
R
rzoner, 2016-06-13
@HaruAtari

Good afternoon,
If it is enough for you to display some models on the UI, then you can do without bindings: setText on Label/TextField/etc.
If you need to create/edit models, then you will still have a Controller/Presenter/ViewModel (you won't do it in setOnAction(e -> {}) ).
In Controller/Presenter/ViewModel you can create wrapper properties using:
1) JavaBeanStringPropertyBuilder (Easiest way, but model field name is hardcoded as a string).
2) BeanPathAdapter from jfxtras (a more advanced version, but the name is again hardcoded).
3) Create a bunch of SimpleFooBarProperty and fill them with data from the model.
4) Create a bunch of SimpleFooBarProperty by overriding get/set methods:
private ObjectProperty date = new SimpleObjectProperty() {
@Override
public Date get() {
return model.getReservationDate();
}
@Override
public void set(Date newValue) {
if (model.getReservationDate() != null && model.getReservationDate().equals(newValue)) return;
model.setReservationDate(newValue);
fireValueChangedEvent();
}
};
In this case, the model is stored in the Controller / Presenter / ViewModel and you can add the setModel () method, which will replace the model.
The only problem is that after calling setModel() , the properties will not notify the controls subscribed to them that a change has occurred. To do this, you need to call the fireValueChangedEvent method, which, unfortunately, is protected.
You can get around this problem as follows:
1) Add an initialization block to the overridden property:
{ allNotifiers.add(this::fireValueChangedEvent); }
2) In Controller/Presenter/ViewModel we create
protected List allNotifiers = new ArrayList<>();
public void raiseAllPropertiesUpdate() {
allNotifiers.stream.forEach(Runnable::run);
}
3) In the setModel() method, add a call to raiseAllPropertiesUpdate().
Now, when a model is changed, each property will notify the properties/controls subscribed to it about the change.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question