Использование TableView с неизменяемыми объектами. Ошибка бесконечного цикла

 
 
 
Сообщения:26
Доброго времени суток.

Задача: Имеется список неизменяемых объектов. Необходимо отобразить этот список в виде таблице TableView через которую также можно будет его редактировать. Часть полей неизменяемых объектов представлены в виде целых чисел и должны отображаться в ячейках таблицы в виде элемента Spiner.

С чем возникли сложности: У объектов есть несколько операций позволяющих задать значение для некоторых полей или выполнить какие-то вычисления. Поскольку объекты неизменяемы - каждая такая операция создает и возвращает новый объект этого же типа содержащий все внесенные изменения. И тут есть два момента:

1. Необходимо заменить старую версию объекта на новую в списке элементов таблицы. Список элементов таблицы представлен типом ObservableList, так что когда он будет изменен TableView автоматически обновиться.
2. Теперь важный момент со Spiner. Единственный способ подписаться на события от этого элемента, это подписаться на прослушивание событий от его свойства spiner.valueProperty().addListener(...). Событие будет срабатывать ВСЕГДА, КОГДА ИЗМЕНЯЕТСЯ ЭТО СВОЙСТВО.

В сумме эти два момента дают следующее:
клиент взаимодействует со спинером ->
изменяется его свойство valueProperty() ->
вызывается слушатель этого свойства ->
слушатель изменяет объект текущей строки таблицы и его новую версию записывает в список элементов таблицы ->
список (напомню - его тип ObservableList) уведомляет таблицу что он был изменен ->
таблица обновляется, обновляя значение каждой ячейки измененной строки и таким образом обновляет свойство valueProperty() нашего спинера ->
цепочка начинается сначала...

Самое интересное, что когда таблица обновляет свойство valueProperty() спинера, передаваемое таблицей значение автоматически увеличевается или уменьшается (в зависимости от последней используемой операции со спинером - нажата стрелка "увеличить" или "уменьшить").

Вопрос: как решить проблему бесконечного цикла обновлений?

P.s. этот пример хорошо демонстрирует главную опасность использования паттерна наблюдатель.
Изменен:08 сен 2020 09:57
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет