На фундаментальном уровне вы, похоже, ожидаете следующего:
IntegerProperty property = new SimpleIntegerProperty(5);
int i = property.get();
property.set(10);
System.out.println(i);
Чтобы распечатать 10
вместо 5
.Это не может произойти в Java, потому что Java всегда передача по значению .То же самое верно при добавлении значения к ObservableList
;все, что вы сделали, взяли значение свойства в момент и добавили его в список.После этого свойство и список являются полностью отдельными объектами.
Нет фундаментального способа наблюдать переменные для изменений в Java.Чтобы получать уведомления об изменениях, должен существовать код, который реализует это поведение.IntegerProperty
- это просто оболочка вокруг int
, которая перехватывает код, изменяющий значение, и уведомляет наблюдателей об изменении.Что-то вроде:
public void set(int newValue) {
this.value = newValue;
notifyObservers();
}
Примечание. Реальная реализация IntegerProperty
более сложна, чем эта.
То же самое относится и к ObservableList
.Все основные реализации - это просто обертки вокруг обычного List
, а ObservableList
просто перехватывает вызовы и уведомляет наблюдателей об изменениях.Вот почему, если вы оберните свой собственный List
с помощью FXCollections.observableList(List)
, вы больше не сможете напрямую изменять List
, потому что это обходит обтекание ObservableList
и, таким образом, никакие события изменения не будут запущены.
Если вы хотите, чтобы ObservableList
обновлялся при изменении IntegerProperty
, вам необходимо добавить прослушиватель к IntegerProperty
, который соответствующим образом обновит ObservableList
.Если вы хотите знать об изменениях содержащихся элементов через ObservableList
, вам нужно использовать экстрактор - см. этот ответ .
это, очевидно, работает, но дает много ошибок, которые я не понимаю.
Игнорирование противоречия между ", очевидно, работает " и " дает мне много ошибок", на самом деле вы не предоставляете ошибки, которые получаете.Без ошибок трудно понять, что происходит не так.Однако у вас есть следующее (что может или не может быть связано с вашими ошибками):
li.addListener((ListChangeListener<Integer>) change -> {
li.set(3, li.get(0) + li.get(2));
});
Это изменение ObservableList
, вызвавшее событие изменения.Вы не должны этого делать :
Предупреждение: Этот класс напрямую обращается к списку источников для получения информации об изменениях.
Это эффективно делаетИзменение объекта недействительным, когда в списке происходит другое изменение.
По этой причине небезопасно использовать этот класс в другом потоке.
Это также означает, что список источников не может бытьизменен внутри слушателя , так как это сделает недействительным этот объект Change для всех последующих слушателей.