3.5.3.1.2. CollectionContainer
Интерфейс CollectionContainer
предназначен для работы с коллекцией экземпляров сущности. Это потомок InstanceContainer
, в котором дополнительно определены следующие методы:
-
setItems()
- устанавливает коллекцию экземпляров сущности для контейнера. -
getItems()
- возвращает неизменяемый список сущностей, хранимых в контейнере. Используйте этот метод для обхода коллекции, получения потока данных или экземпляра сущности по его позиции в списке. Если требуется получить экземпляр сущности по его идентификатору, используйте методgetItem(entityId)
. Например:@Inject private CollectionContainer<Customer> customersDc; private Optional<Customer> findByName(String name) { return customersDc.getItems().stream() .filter(customer -> Objects.equals(customer.getName(), name)) .findFirst(); }
-
getMutableItems()
- возвращает изменяемый список сущностей, хранимых в контейнере. Все изменения списка, вызванные методамиadd()
,addAll()
,remove()
,removeAll()
,set()
,clear()
, публикуют событиеCollectionChangeEvent
. Визуальные компоненты, подписанные на это событие, будут обновлены автоматически. Например:@Inject private CollectionContainer<Customer> customersDc; private void createCustomer() { Customer customer = metadata.create(Customer.class); customer.setName("Homer Simpson"); customersDc.getMutableItems().add(customer); }
Используйте метод
getMutableItems()
только тогда, когда необходимо изменить коллекцию. В остальных случаях предпочтительнее использоватьgetItems()
. -
setItem()
- устанавливает текущий экземпляр сущности для контейнера. Если передан не null, переданный экземпляр должен уже иметься в коллекции, чтобы быть выбранным. Метод публикует событиеItemChangeEvent
.Нужно учитывать, что визуальные компоненты, такие как Table, не отслеживают событие
ItemChangeEvent
, публикуемое контейнером. Поэтому, если вам нужно выбрать строку в таблице, используйте методsetSelected()
вместо методаsetItem()
контейнера, содержащего коллекцию. Текущий экземпляр контейнера также будет изменен, так как контейнер отслеживает события компонента. Пример:@Inject private CollectionContainer<Customer> customersDc; @Inject private GroupTable<Customer> customersTable; private void selectFirstRow() { customersTable.setSelected(customersDc.getItems().get(0)); }
-
getItem()
- переопределяет аналогичный метод родительского интерфейсаInstanceContainer
и возвращает текущий экземпляр. Если текущий экземпляр не задан, метод выбрасывает исключение. Используйте этот метод, если вы уверены, что для контейнера задан текущий экземпляр, в этом случае не требуется проверка возвращаемого значения на null. -
getItemOrNull()
- переопределяет аналогичный метод родительского интерфейсаInstanceContainer
и возвращает текущий экземпляр. Если текущий экземпляр не задан, метод возвращает null. Всегда проверяйте полученное значение на null перед использованием. -
getItemIndex(entityId)
- возвращает позицию сущности с данным идентификатором в списке, возвращаемом методамиgetItems()
иgetMutableItems()
. Этот метод принимаетObject
, поэтому вы можете передать как id сущности, так и экземпляр сущности целиком. Реализация контейнера поддерживает отображение идентификаторов на индексы, поэтому метод работает быстро даже с большими списками. -
getItem(entityId)
- возвращает экземпляр сущности из коллекции по её идентификатору. Это ускоренный метод, который сначала получает позицию экземпляра с помощьюgetItemIndex(entityId)
, а затем возвращает экземпляр из списка, используя методgetItems().get(index)
. Метод выбрасывает исключение, если экземпляр с переданным id отсутствует в коллекции. -
getItemOrNull(entityId)
- то же, что иgetItem(entityId)
, но возвращает null, если экземпляр с данным id отсутствует в коллекции. Всегда проверяйте полученное значение на null перед использованием. -
containsItem(entityId)
- возвращает true, если экземпляр с данным id есть в коллекции. Это упрощённый метод, в котором на самом деле используетсяgetItemIndex(entityId)
. -
replaceItem(entity)
- если экземпляр с тем же id есть в коллекции, он заменяется переданным экземпляром. Если таковой экземпляр отсутствует, переданный экземпляр будет добавлен к списку. Метод публикует событиеCollectionChangeEvent
с типомSET_ITEM
илиADD_ITEMS
, в зависимости от операции. -
setSorter()
- задаёт для контейнера переданный сортировщик. Стандартной реализацией интерфейсаSorter
являетсяCollectionContainerSorter
. Платформа задаёт его автоматически, если для контейнера определён загрузчик, однако можно создать и собственную реализацию, если необходимо. -
getSorter()
- возвращает текущий сортировщик данного контейнера.
- События CollectionContainer
-
В дополнение к событиям InstanceContainer, интерфейс
CollectionContainer
позволяет зарегистрировать слушатели для событияCollectionChangeEvent
, которое вызывается при изменении коллекции сущностей, то есть при добавлении, удалении или замене элементов коллекции. Пример подписки на событие для контейнера, объявленного в XML с идентификаторомcustomersDc
:@Subscribe(id = "customersDc", target = Target.DATA_CONTAINER) private void onCustomersDcCollectionChange( CollectionContainer.CollectionChangeEvent<Customer> event) { CollectionChangeType changeType = event.getChangeType(); (1) Collection<? extends Customer> changes = event.getChanges(); (2) // ... }
1 - тип изменения: REFRESH, ADD_ITEMS, REMOVE_ITEMS, SET_ITEM. 2 - коллекция сущностей, которые были добавлены или удалены из контейнера. Если тип изменения - REFRESH, то фреймворк не может определить, какие элементы были добавлены или удалены, поэтому данная коллекция пустая.