Как в JavaFX 2 правильно сделать data binding?

Я редко работаю с 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… И такое средство хотелось бы иметь из коробки, а не писать велосипеды…

Буду благодарен любым конструктивным ответам.

Коллеги, если Вы уж минусуете, хоть объясняйте, в чем причина. Что бы была возможность исправить косяки. Спасибо.
  • Вопрос задан
  • 8635 просмотров
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы