Я пытаюсь провести рефакторинг своего кода JavaFX (например, моего собственного многоколоночного ComboBox), используя простые поля , чтобы свойства (наблюдаемые) , которые я пытаюсь изучить.
В моей реализации поля так или иначе связаны - например, изменение одного поля приводит к сбросу других полей к некоторым значениям:
private MyModel model; // data (in rows and cols) for my multicolumn combo
private int valueColumn; // column index to get the combo value from
private int displayColumn; // column index to get the combo text from
// model setter
// - setting a new model leads to clearing valueColumn and displayColumn to
// (default) 0 (values used for previous model are not relevant)
public void setModel(MyModel model) {
this.model = model;
valueColumn = 0;
displayColumn = 0;
reactToComboChange();
}
public setValueColumn(int valueColumn) {
this.valueColumn = valueColumn;
reactToComboChange();}
В этой простой реализации (простопример) гарантируется, что поля будут сразу же изменены в допустимое состояние до начала какой-либо реакции - reactToComboChange()
.
При рефакторинге к наблюдаемым, вместовызова метода «реакции» в установщиках полей, я использую прослушиватели изменений.
Моя проблема заключается в том, что код слушателя запускается после изменения каждого отдельного свойства , то есть в ситуации, когда комбинация «»связанных свойств может быть «недопустимым» (еще не все свойства установлены для целевого юридического значения) - например, новая модель уже установлена, valueColumnProperty, измененный в слушателе modelProperty, немедленно уведомляет свой список, но третье свойство displayColumnProperty все еще неизменено (сброс на 0) и т. д.
modelProperty().addListener((ob, ov, nv) -> {
setValueColumn(0);
setDisplayColumn(0);
reactToComboChange();
});
valueColumnProperty().addListener((ob, ov, nv) -> {
reactToComboChange();
});
...
Это был только теоретический пример.У меня общий вопрос: есть ли способ как-то изменить сразу несколько связанных свойств, прежде чем все слушатели будут уведомлены? (я думаю, ответ - нет). Существует ли какая-то стандартная стратегия для решения такой ситуации?Есть ли какой-то стандартный шаблон для связанных свойств, который я должен изучить и использовать? Я не могу понять ...
Мое практическое решение - использовать булеву переменную isChangingModelNow
(для которой установлено значение true в начале modelPropertyListerи обратно в false в конце этого прослушивателя), чтобы предотвратить любое действие в прослушивателях valueColumn и displayColumn, уведомленное из-за изменений, сделанных в слушателе modelProperty, но это скорее взлом ...