Я редко работаю с client-side, может поэтому возникла такая проблема.
Итак, какие возможности по data binding я нашел в java fx:
1. Через ChangeListener:
@FXML
private TextField firstNameField;
private Person person;
public void initialize(final URL arg0, final ResourceBundle arg1) {
firstNameField.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(final ObservableValue<? extends String> paramObservableValue,
final String paramT1, final String paramT2) {
person.setFirstName(paramT2);
}
});
}
В этом случае мы получаем громоздний и никому ненужный код + одностороннюю связь (мы слушаем только изменения с UI)
2. Через проперти:
@FXML
private TextField firstNameField;
private final StringProperty firstName = new SimpleStringProperty(this, "firstName");
public void initialize(final URL arg0, final ResourceBundle arg1) {
Bindings.bindBidirectional(firstNameField.textProperty(), firstName);
}
Тут все красиво. Но! У меня есть POJO объект Person, как это значение попадет в него? Т.е. мне надо для каждого поля каждой модели пересетывать значения, сначала в одну сторону (что бы отобразить поля модели), затем в другую (что бы внести изменения в модель)? Какой тогда в этом смысл, если с тем же успехом я могу точно так же вытащить значения из текстовых филдов (тем более, что они все тоже должны быть в контроллере, что бы сделать байндинг)?
3. Запихнуть проперти в класс модели, и дальше как в #2.
public class Person {
private StringProperty firstName = new SimpleStringProperty(this, "firstName", "");
public final String getFirstName() { return firstName.get(); }
public final void setFirstName(String value) { firstName.set(value); }
public final StringProperty firstNameProperty() { return firstName; }
}
Это решает проблему, описанную в #2, но при этом каверкает класс модели… Хотелось бы оставить их POJO.
Что хотелось бы видеть: в контроллер приходит объект модели, мы пихаем его в какую то обертку, которая байндит эту модель на TextField'ы и другие контролы. Пусть даже байндинг необходимо будет явно объявлять:
public void initialize(final URL arg0, final ResourceBundle arg1) {
Bindings.bindBidirectional(firstNameField.textProperty(), personWrapper.getProperty("firstName"));
}
Может быть что то подобное все-таки есть?
Отдельный вопрос возник про маппинг поля с типом enum на группу RadioButton'ов… Без танцев с бубном мне этого сделать не получилось… Хотя, казалось бы, все достаточно просто. Сделать EnumProperty и рулить все через ToggleGroup… И такое средство хотелось бы иметь из коробки, а не писать велосипеды…
Буду благодарен любым конструктивным ответам.
Коллеги, если Вы уж минусуете, хоть объясняйте, в чем причина. Что бы была возможность исправить косяки. Спасибо.