Из документации из ObservableValue
(которая наследуется от Binding
и Property
):
Реализация ObservableValue
может поддерживать отложенную оценку,Это означает, что значение не пересчитывается сразу после изменений, а лениво при следующем запросе значения.Все привязки и свойства в этой библиотеке поддерживают отложенную оценку.
ObservableValue
генерирует два типа событий: события изменения и события аннулирования.Событие изменения указывает, что значение изменилось.Событие аннулирования генерируется, если текущее значение больше не является допустимым.Это различие становится важным, если ObservableValue
поддерживает ленивую оценку, потому что для лениво оцененного значения никто не знает, действительно ли неверное значение изменилось, пока оно не будет пересчитано.По этой причине генерация событий изменения требует тщательной оценки, в то время как события недействительности могут быть сгенерированы для нетерпеливых и ленивых реализаций.
Реализации этого класса должны стремиться генерировать как можно меньше событий, чтобы не тратить слишком много времени на обработчики событий.,Реализации в этой библиотеке помечают себя как недействительные, когда происходит первое событие недействительности.Они больше не генерируют события аннулирования до тех пор, пока их значение не будет пересчитано и снова станет действительным.
Два типа слушателей могут быть присоединены к ObservableValue
: InvalidationListener
для прослушивания событий аннулирования и ChangeListener
для прослушиваниясобытия изменения.
Важное примечание: добавление ChangeListener
приводит к принудительным вычислениям, даже если реализация ObservableValue
поддерживает отложенную оценку.
Обратите внимание, что оба Property#bind
и Bindings#createXXXBinding
регистрируют InvalidationListener
на зависимости / зависимостях, а не ChangeListener
.
Как видите, привязки и свойства в ядре JavaFX ленивы.Вы никогда не запрашиваете значение после удаления элемента из ObservableList
, поэтому значение никогда не пересчитывается.Поскольку значение никогда не пересчитывается, ваш Callable
не вызывается во второй раз.
Я был действительно удивлен, что вы видели "List has changed"
даже один раз.Ни один из вашего кода не запрашивает значение, поэтому я не ожидал, что значение будет вычислено.Однако, глядя на реализацию, похоже, что акт регистрации InvalidationListener
вызывает проверку ObservableValue
(т. Е. Значение запрашивается) - и #bind
добавляет InvalidationListener
.Я не уверен, почему реализация делает это, но это делает.