CollectionContainer
The CollectionContainer
interface is designed to hold a collection of entities of the same type. It is a descendant of the InstanceContainer
interface.
You can define CollectionContainer
in the XML descriptor in the following way:
<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>
Methods
CollectionContainer
defines the following specific methods:
-
setItems()
- sets a collection of entities to the container. -
getItems()
- returns an immutable list of entities stored in the container. Use this method to iterate over the collection, to get a stream or to get an instance by its position in the list. If you need to get an entity instance by its id, usegetItem(entityId)
. For example:@ViewComponent private CollectionContainer<Department> departmentsDc; private Optional<Department> findByName(String name) { return departmentsDc.getItems().stream() .filter(department -> Objects.equals(department.getName(), name)) .findFirst(); }
-
getMutableItems()
- returns a mutable list of entities stored in the container. All list changes caused by theadd()
,addAll()
,remove()
,removeAll()
,set()
,clear()
methods produceCollectionChangeEvent
, so subscribed visual components will update accordingly. For example:@ViewComponent private CollectionContainer<Department> departmentsDc; private void createDepartment() { Department department = metadata.create(Department.class); department.setName("Operations"); departmentsDc.getMutableItems().add(department); }
Use getMutableItems()
only when you want to change the collection. In other cases, it is preferable to usegetItems()
. -
setItem()
- sets the current item for this container. If the provided item is not null, it must exist in the collection. The method sendsItemChangeEvent
.Please note that visual components like DataGrid do not listen to
ItemChangeEvent
sent by the container. So if you want to select a row in aDataGrid
, use the selection model of theDataGrid
instead of thesetItem()
method of the collection container. The current item of the container will also be changed because the container listens to the component. For example:@ViewComponent private DataGrid<Department> departmentsTable; @ViewComponent private CollectionContainer<Department> departmentsDc; private void selectFirstRow() { departmentsTable.getSelectionModel() .select(departmentsDc.getItems().get(0)); }
-
getItem()
- overrides the method ofInstanceContainer
and returns the current item. If the current item is not set, the method throws an exception. Use this method when you are sure that the current item has been set for the container, then you don’t have to check the returned value fornull
. -
getItemOrNull()
- overrides the method ofInstanceContainer
and returns the current item. If the current item is not set, this method returns null. Please always check the returned value fornull
before using it. -
getItemIndex(entityId)
- returns the position of an instance with the given id in the list returned by thegetItems()
andgetMutableItems()
methods. This method acceptsObject
and you can pass either id or the entity instance itself. The container implementation maintains a map of ids to indexes, so the method works fast even on large lists. -
getItem(entityId)
- returns an instance from the collection by its id. It’s a shortcut method that first obtains the instance position usinggetItemIndex(entityId)
and then returns the instance from the list usinggetItems().get(index)
. The method throws an exception if the instance with the specified id doesn’t exist in the collection. -
getItemOrNull(entityId)
- same asgetItem(entityId)
but returns null if the instance with the specified id doesn’t exist in the collection. Always check the returned value for null before using it. -
containsItem(entityId)
- returns true if an instance with the specified id exists in the collection. It’s a shortcut method that usesgetItemIndex(entityId)
under the hood. -
replaceItem(entity)
- if the item with the same id exists in the container, it is replaced with the given instance. If not, the given instance is added to the items list. The method sendsCollectionChangeEvent
of theSET_ITEM
orADD_ITEMS
type depending on what has been done. -
setSorter()
- sets the given sorter for this container. A standard implementation of theSorter
interface isCollectionContainerSorter
. It is set by the framework automatically when the container is associated with a loader. You can provide your own implementation if needed. -
getSorter()
- returns the sorter currently set for this container.
Events
In addition to events of InstanceContainer, the CollectionContainer
interface allows you to register listeners to the CollectionChangeEvent
event which is sent when the container items collection is changed: on adding, removing and replacing elements. Example of subscribing to the event for a container defined in the view XML with departmentsDc
id:
@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 | Gets a type of changes: REFRESH , ADD_ITEMS , REMOVE_ITEMS , SET_ITEM . |
2 | Collection of entities that were added or removed from the container. If the change type is REFRESH , the framework cannot determine what exactly items were added or removed, so this collection is empty. |