MegaMufa
@MegaMufa

Как использовать обычные классы в JavaFx приложении?

Добрый день.

Есть java библиотека. Мне нужно написать для нее гуй. Я вот я не пойму, как без лишних оберток привязать объекты из библиотеки к интерфейсу.

Проблема в том, что в javaxf приложениях поля моделей, которые биндятся к интерфейсу должны быть типов javafx.beans.property.* (например не String, а SimpleStringProperty). А классы, находящиеся в библиотеке содержат поля с обычными строками/интами/итд. Как можно привязать эти объекты к интерфейсу?

Единственное, что мне в голову пришло - для каждого класса написать обертку, которая будет конвертировать типы. Но слишком запарно для каждого класса их делать.

Подскажите, как решается такая задача?
  • Вопрос задан
  • 707 просмотров
Решения вопроса 1
rzoner
@rzoner
Добрый день,

Если Вам достаточно отобразить на UI какие-то модельки, то можно обойтись без биндингов: setText на Label/TextField/etc.
Если Вам нужно создавать/редактировать модельки, то у Вас все равно будет Controller/Presenter/ViewModel (Вы же не будете это делать в setOnAction(e -> {}) ).
В Controller/Presenter/ViewModel Вы можете создать свойства-обертки, используя:
1) JavaBeanStringPropertyBuilder (самый простой способ, но имя поля модельки хардкодится строкой).
2) BeanPathAdapter из jfxtras (более продвинутый вариант, но имя опять таки хардкодится).
3) Создать кучу SimpleFooBarProperty и заполнять их данными из модельки.
4) Создать кучу SimpleFooBarProperty, переопределив методы get/set:

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();
}
};

При этом моделька хранится в Controller/Presenter/ViewModel и можно добавить метод setModel(), который будет заменять модельку.
Единственная проблема -- после вызове setModel() свойства не уведомят подписанные на них контролы, что произошло измнение. Для этого нужно вызвать метод fireValueChangedEvent, который protected, к сожалению.
Обойти эту проблему можно следующим образом:
1) Добавляем блок инициализации в переопределенное свойство:
{ allNotifiers.add(this::fireValueChangedEvent); }
2) В Controller/Presenter/ViewModel создаем
protected List allNotifiers = new ArrayList<>();
public void raiseAllPropertiesUpdate() {
allNotifiers.stream.forEach(Runnable::run);
}
3) В методе setModel() добавляем вызов raiseAllPropertiesUpdate().
Теперь при подмене модели каждое проперти уведомит подписанные на него проперти/контроллы об изменении.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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