CollectionContainer
Интерфейс CollectionContainer
предназначен для работы с коллекцией экземпляров сущности. Это потомок интерфейса InstanceContainer
.
CollectionContainer
можно определить в XML-дескрипторе следующим образом:
<collection id="departmentsDc"
class="com.company.onboarding.entity.Department">
<fetchPlan extends="_base">
<property name="hrManager" fetchPlan="_base"/>
</fetchPlan>
<loader id="departmentsDl" readOnly="true">
<query>
<![CDATA[select e from Department e]]>
</query>
</loader>
</collection>
Методы
В CollectionContainer
определены следующие методы:
-
setItems()
- устанавливает коллекцию экземпляров сущности для контейнера. -
getItems()
- возвращает неизменяемый список сущностей, хранимых в контейнере. Используйте этот метод для обхода коллекции, получения потока (Java stream) или экземпляра сущности по его позиции в списке. Если требуется получить экземпляр сущности по его идентификатору, используйте методgetItem(entityId)
. Например:@ViewComponent private CollectionContainer<Department> departmentsDc; private Optional<Department> findByName(String name) { return departmentsDc.getItems().stream() .filter(department -> Objects.equals(department.getName(), name)) .findFirst(); }
-
getMutableItems()
- возвращает изменяемый список сущностей, хранимых в контейнере. Все изменения списка, вызванные методамиadd()
,addAll()
,remove()
,removeAll()
,set()
,clear()
, публикуют событиеCollectionChangeEvent
. Визуальные компоненты, подписанные на это событие, будут обновлены автоматически. Например:@ViewComponent private CollectionContainer<Department> departmentsDc; private void createDepartment() { Department department = metadata.create(Department.class); department.setName("Operations"); departmentsDc.getMutableItems().add(department); }
Используйте метод getMutableItems()
только тогда, когда необходимо изменить коллекцию. В остальных случаях предпочтительнее использоватьgetItems()
. -
setItem()
- устанавливает текущий экземпляр сущности для контейнера. Если передан неnull
, переданный экземпляр должен уже иметься в коллекции, чтобы быть выбранным. Метод публикует событиеItemChangeEvent
.Нужно учитывать, что визуальные компоненты, такие как DataGrid, не отслеживают событие
ItemChangeEvent
, публикуемое контейнером. Поэтому, если вам нужно выбрать строку вDataGrid
, используйте selection model компонентаDataGrid
вместо методаsetItem()
контейнера, содержащего коллекцию. Текущий экземпляр контейнера также будет изменен, так как контейнер отслеживает события компонента. Пример:@ViewComponent private DataGrid<Department> departmentsTable; @ViewComponent private CollectionContainer<Department> departmentsDc; private void selectFirstRow() { departmentsTable.getSelectionModel() .select(departmentsDc.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()
- возвращает текущий сортировщик данного контейнера.
События
В дополнение к событиям InstanceContainer, интерфейс CollectionContainer
позволяет зарегистрировать слушатели для события CollectionChangeEvent
, которое вызывается при изменении коллекции сущностей, то есть при добавлении, удалении или замене элементов коллекции. Пример подписки на событие для контейнера, объявленного в XML с идентификатором departmentsDc
:
@Subscribe(id = "departmentsDc", target = Target.DATA_CONTAINER)
public void onDepartmentsDcCollectionChange(
final CollectionContainer.CollectionChangeEvent<Department> event) {
CollectionChangeType changeType = event.getChangeType(); (1)
Collection<? extends Department> changes = event.getChanges(); (2)
// ...
}
1 | Тип изменения: REFRESH , ADD_ITEMS , REMOVE_ITEMS , SET_ITEM . |
2 | Коллекция сущностей, которые были добавлены или удалены из контейнера. Если тип изменения – REFRESH , то фреймворк не может определить, какие элементы были добавлены или удалены, поэтому данная коллекция пустая. |