| [ Web Proxy ] |
| Viewing: https://deepwiki.com/patternfly-java/patternfly-java/4.2-collection-management | [Back] [Original] |
This page covers the abstractions that govern how patternfly-java components manage ordered, mutable collections of child items. The interfaces documented here are used uniformly across all data-display, navigation, and container components in the components module. For information about the individual component types that implement these abstractions, see the component pages under section 5.
Almost every container component in patternfly-java holds a collection of typed child items. Rather than each component implementing its own add/remove/update logic ad hoc, the library provides a small set of shared interfaces and helper classes that are implemented consistently across the entire component library:
| Abstraction | Kind | Purpose |
|---|---|---|
HasItems | Interface | Core CRUD operations on a typed collection |
HasIdentifier | Interface | Provides a stable string key per item |
AurHandler | Class | Delegates add / update / remove lifecycle callbacks |
Ordered | Interface | Extends HasItems with comparator-driven DOM insertion |
AsyncItems | Functional interface | Supplies items lazily via a Promise |
AsyncStatus | Enum | Tracks the current load state of an async collection |
components/src/main/java/org/patternfly/component/HasItems.java42-43
HasItems<E, C, S> is the primary interface for any component that contains a collection. The three type parameters are:
E the DOM element type of the container component (e.g., HTMLUListElement)C the container component itself (for fluent chaining)S the item type; must implement HasIdentifier<? extends HTMLElement, ?>The interface extends Iterable<S>, so any component implementing it can be used directly in a for-each loop.
| Method | Description | Line Reference |
|---|---|---|
add(S item) | Adds a single item (abstract; each component implements DOM placement) | HasItems.java78 |
addItem(S item) | Default alias for add | HasItems.java68-70 |
addItems(Iterable<T>, Function<T,S>) | Bulk add with a display mapping function | HasItems.java54-60 |
items() | Returns all items as a List<S> | HasItems.java93-97 |
size() | Number of items currently held | HasItems.java104 |
isEmpty() | True if no items | HasItems.java111 |
contains(String identifier) | True if an item with that identifier exists | HasItems.java119 |
item(String identifier) | Returns the item for the given identifier, or null | HasItems.java126 |
updateItem(S item) | Replaces the DOM element and internal state for an existing item (abstract) | HasItems.java155 |
updateItem(String identifier) | Convenience overload; looks up item then delegates | HasItems.java146-148 |
updateItem(T item, Function<T,S>) | Maps a model object to a subcomponent, then updates | HasItems.java136-138 |
removeItem(String identifier) | Removes item from the DOM and internal map (abstract) | HasItems.java173 |
clear() | Removes all items | HasItems.java187 |
onAdd(AddItemHandler<C,S>) | Registers a listener fired after each add | HasItems.java86 |
onUpdate(UpdateItemHandler<C,S>) | Registers a listener fired after each updateItem | HasItems.java162 |
onRemove(RemoveItemHandler<C,S>) | Registers a listener fired after each removeItem or clear | HasItems.java180 |
The internal storage in all implementations is a LinkedHashMap<String, S> keyed by the item's identifier, which preserves insertion order while enabling O(1) lookup.
Sources: components/src/main/java/org/patternfly/component/HasItems.java42-200 components/src/main/java/org/patternfly/component/list/DataList.java74-83 components/src/main/java/org/patternfly/component/table/Tbody.java62-72
Every item in a HasItems collection must implement HasIdentifier, which exposes a single method identifier() returning a String. This identifier is used as the map key for all lookup, update, and remove operations. It also corresponds to the data-identifier dataset attribute set on the item's HTML element, which enables DOM-level lookups where needed.
AurHandler<C, S> (Add-Update-Remove Handler) is a concrete helper class that all HasItems implementations instantiate to manage their lifecycle callbacks. Each component constructs one at initialization:
The component then delegates callback registration and firing through it:
| Component calls | AurHandler does |
|---|---|
aur.onAdd(handler) | Registers an AddItemHandler |
aur.onUpdate(handler) | Registers an UpdateItemHandler |
aur.onRemove(handler) | Registers a RemoveItemHandler |
aur.added(item) | Fires all registered onAdd handlers; returns the component for chaining |
aur.updated(oldItem, newItem) | Fires all registered onUpdate handlers |
aur.removed(item) | Fires all registered onRemove handlers |
The three handler types are parameterized functional interfaces:
AddItemHandler<C, S> receives (C component, S item)UpdateItemHandler<C, S> receives (C component, S oldItem, S newItem)RemoveItemHandler<C, S> receives (C component, S item)Lifecycle flow diagram adding an item:
Sources: components/src/main/java/org/patternfly/component/list/DataList.java75-84 components/src/main/java/org/patternfly/component/table/Tbody.java62-73 components/src/main/java/org/patternfly/component/menu/MenuList.java90-105
components/src/main/java/org/patternfly/component/Ordered.java42-122
Ordered<E, C, S> extends HasItems and adds comparator-driven DOM insertion. It is intended for situations where items arrive asynchronously in an unpredictable order, but the visual sequence must remain consistent.
Ordered interface hierarchy
ordered() activates ordering using defaultOrder(), which sorts by the data-order attribute on each item's HTML element.ordered(Comparator<S>) activates ordering using a caller-supplied comparator.addOrdered(container, item) called internally by the component's add method. It uses a TreeSet over the current items, walks the sorted set to find the insertion point, and calls insertBefore to place the new item's DOM element at the correct position.comparator() returns the active comparator, or null if ordering is disabled.When comparator() returns null, addOrdered falls back to a plain container.add(item.element()) append.
Sources: components/src/main/java/org/patternfly/component/Ordered.java59-122 components/src/main/java/org/patternfly/component/list/DataList.java89-94 components/src/main/java/org/patternfly/component/table/Tbody.java87-92
Several components support deferred item loading. The mechanism is a two-part design:
AsyncItems<C, S> is a functional interface whose single method signature is:
A caller passes an AsyncItems instance to the component (e.g., via MenuList.add(AsyncItems<...>) or TreeViewItem.add(AsyncItems<...>)). The component stores it and calls apply(this) when it is ready to load.
AsyncStatus is an enum that tracks the current state of an async collection:
| Value | Meaning |
|---|---|
static_ | Items were added synchronously; no async loading configured |
pending | An AsyncItems has been registered; loading not yet started, or reset() was called |
resolved | The promise resolved successfully |
rejected | The promise was rejected (network error, etc.) |
AsyncStatus state transitions
components/src/main/java/org/patternfly/component/menu/MenuList.java187-230
add(AsyncItems<MenuList, MenuItem>) sets status = pending and stores the supplier.load() is called (by the owning Menu component when the menu is opened).asyncItems.apply(this) is invoked; on resolve, the loading item is removed and real items are added via addItem. If the result set is empty, a "No items found" item is added.status = rejected.reset() can be called to return to pending and clear current items, enabling reload().components/src/main/java/org/patternfly/component/tree/TreeViewItem.java346-384
The TreeViewItem implementation defers showing the loading indicator using a setTimeout (LOADING_TIMEOUT ms). This prevents a flash of a loading spinner when items load quickly. On collapse after a successful load, the children are retained; reset() collapses and clears them, ready for re-expansion.
Sources: components/src/main/java/org/patternfly/component/menu/MenuList.java136-230 components/src/main/java/org/patternfly/component/tree/TreeViewItem.java196-406
The following table summarizes which components implement HasItems or Ordered, and what their item types are. Components implementing Ordered also implement HasItems (since Ordered extends it).
| Component | Interface | Item Type | File |
|---|---|---|---|
MenuList | Ordered | MenuItem | component/menu/MenuList.java |
Tbody | Ordered | Tr | component/table/Tbody.java |
DataList | Ordered | DataListItem | component/list/DataList.java |
DescriptionList | Ordered | DescriptionListGroup | component/list/DescriptionList.java |
List | Ordered | ListItem | component/list/List.java |
SimpleList | Ordered | SimpleListItem | component/list/SimpleList.java |
SimpleListGroup | Ordered | SimpleListItem | component/list/SimpleListGroup.java |
TreeView | HasItems | TreeViewItem | component/tree/TreeView.java |
TreeViewItem | HasItems | TreeViewItem | component/tree/TreeViewItem.java |
Tabs | HasItems | Tab | component/tabs/Tabs.java |
Navigation | HasItems | NavigationItem | component/navigation/Navigation.java |
NavigationGroup | HasItems | NavigationItem | component/navigation/NavigationGroup.java |
ExpandableNavigationGroup | HasItems | NavigationItem | component/navigation/ExpandableNavigationGroup.java |
Accordion | HasItems | AccordionItem | component/accordion/Accordion.java |
JumpLinks | HasItems | JumpLinksItem | component/jumplinks/JumpLinks.java |
JumpLinksList | HasItems | JumpLinksItem | component/jumplinks/JumpLinksList.java |
LabelGroup | HasItems | Label | component/label/LabelGroup.java |
AlertGroup | HasItems | Alert | component/alert/AlertGroup.java |
Breadcrumb | HasItems | BreadcrumbItem | component/breadcrumb/Breadcrumb.java |
ToggleGroup | HasItems | ToggleGroupItem | component/togglegroup/ToggleGroup.java |
ToolbarContent | HasItems | ToolbarItem | component/toolbar/ToolbarContent.java |
ToolbarToggleGroup | HasItems | ToolbarItem | component/toolbar/ToolbarToggleGroup.java |
ProgressStepper | HasItems | ProgressStep | component/progressstepper/ProgressStepper.java |
Sources: components/src/main/java/org/patternfly/component/menu/MenuList.java63-65 components/src/main/java/org/patternfly/component/table/Tbody.java47-48 components/src/main/java/org/patternfly/component/list/DataList.java62-64 components/src/main/java/org/patternfly/component/tree/TreeView.java78-80
The diagram below maps the major types to their roles and shows which concrete classes implement each interface.
Sources: components/src/main/java/org/patternfly/component/HasItems.java42-200 components/src/main/java/org/patternfly/component/Ordered.java42-122 components/src/main/java/org/patternfly/component/menu/MenuList.java90-100 components/src/main/java/org/patternfly/component/tree/TreeViewItem.java162-165
When updateItem(S item) is called, the component locates the existing item by item.identifier(), replaces its DOM element with the new item's element in-place, then updates the internal map and fires aur.updated(oldItem, newItem). The base-class helper replaceItemElement(S item, BiConsumer<S, S> consumer) handles the DOM swap; the BiConsumer receives (oldItem, newItem) and is responsible for updating the map and calling the AurHandler.
A typical implementation follows this pattern (shown from Tbody):
components/src/main/java/org/patternfly/component/table/Tbody.java172-178
replaceItemElement(item, (oldItem, newItem) -> {
items.put(newItem.identifier(), newItem);
aur.updated(oldItem, newItem);
});
This pattern is identical across DataList, SimpleList, MenuList, TreeView, Navigation, and all other implementations.
Sources: components/src/main/java/org/patternfly/component/table/Tbody.java172-178 components/src/main/java/org/patternfly/component/list/DataList.java175-180 components/src/main/java/org/patternfly/component/menu/MenuList.java280-285
Refresh this wiki
Enter email to refresh| Web Proxy Viewer | New URL | Original Page |