This document explains the foundational patterns and abstractions that underpin all PatternFly Java components. It covers the base classes, interface-based composition system, type-safe builder pattern, and collection management infrastructure that enable consistent component behavior across the library.
For information about specific component implementations, see Component Library. For details on the build system that generates design tokens and icons, see Code Generation.
PatternFly Java components are built on a small set of foundational abstractions that provide common functionality while enabling extensibility through composition.
BaseComponent is the root class for all PatternFly components. It provides:
The class uses Java generics to preserve type information through method chains:
This pattern allows subclasses like Button to return their own type from builder methods, enabling button().primary().disabled(true) to work with full type safety.
Sources: components/src/main/java/org/patternfly/component/button/Button.java82-93 components/src/main/java/org/patternfly/component/form/Checkbox.java62-66
Sources: components/src/main/java/org/patternfly/component/button/Button.java82 components/src/main/java/org/patternfly/component/form/Checkbox.java62 components/src/main/java/org/patternfly/component/table/Table.java62 components/src/main/java/org/patternfly/component/menu/MenuToggle.java72 components/src/main/java/org/patternfly/component/table/Tr.java85
PatternFly Java favors interface composition over inheritance hierarchies. Components implement multiple small interfaces to declare their capabilities, avoiding the rigidity of deep inheritance trees.
Components implement focused interfaces that add specific behaviors:
| Interface | Purpose | Example Methods | Example Components |
|---|---|---|---|
Disabled | Enable/disable functionality | disabled(boolean) | Button, Checkbox, MenuToggle |
ComponentIcon | Icon management | icon(Element), removeIcon() | Button, MenuToggle |
HasValue<T> | Value access/mutation | value(), value(T) | Checkbox (Boolean) |
Expandable | Expand/collapse behavior | expand(), collapse(), expanded() | Tr, TreeViewItem |
Closeable | Close/dismiss capability | close() | Modal, Popover, Tab |
Primary, Secondary | Style modifiers | primary(), secondary() | Button, MenuToggle |
ElementTextMethods | Text content access | text(String), text() | Button, Checkbox, Cell |
Each interface is narrow in scope, typically 1-3 methods. This allows components to mix-and-match capabilities declaratively.
Sources: components/src/main/java/org/patternfly/component/button/Button.java82-93 components/src/main/java/org/patternfly/component/form/Checkbox.java62-66 components/src/main/java/org/patternfly/component/menu/MenuToggle.java72-80
A Button declares its full capability set through interfaces. The Java compiler enforces that all interface methods are implemented, while the fluent API preserves type information.
Sources: components/src/main/java/org/patternfly/component/button/Button.java82-93
Many components implement HasIdentifier, which provides:
The identifier() method returns the component's unique string ID, which is typically generated using Id.unique() with a component type prefix.
Sources: components/src/main/java/org/patternfly/component/table/Tr.java85-89 components/src/main/java/org/patternfly/component/table/Cell.java33-37
The ComponentContext interface enables components to store arbitrary key-value data without polluting their API with fields:
| Method | Purpose |
|---|---|
store(String key, T value) | Store a value under a key |
has(String key) | Check if key exists |
get(String key) | Retrieve stored value |
This pattern is used for:
Example usage pattern:
The backing storage is a Map<String, Object> field in implementing classes. Type safety is provided at retrieval time through generics.
Sources: components/src/main/java/org/patternfly/component/table/Tr.java124 components/src/main/java/org/patternfly/component/table/Tr.java239-242 components/src/main/java/org/patternfly/component/table/Cell.java40
All PatternFly components use a builder pattern with method chaining for configuration. The pattern is type-safe: every method returns the component's actual type, not a base type.
The key to type safety is the recursive generic bound:
The second type parameter (Button) tells the base class what type to return from builder methods. This enables:
Without this pattern, each method would return BaseComponent, forcing type casts.
PatternFly components consistently use two return patterns:
this: Methods that configure state return the component itselfexpand(), collapse()) return nothingSources: components/src/main/java/org/patternfly/component/button/Button.java218-222 components/src/main/java/org/patternfly/component/table/Tr.java292-308
Components provide static factory methods for common construction patterns:
Each factory method creates a fully initialized component ready for further configuration via builder methods.
Sources: components/src/main/java/org/patternfly/component/button/Button.java97-139 components/src/main/java/org/patternfly/component/menu/MenuToggle.java84-130 components/src/main/java/org/patternfly/component/form/Checkbox.java71-85
Container components (Table, TreeView, Menu, Navigation, Tabs, Wizard) manage collections of child items using a consistent pattern.
The HasItems<E, B, I> interface defines standard collection operations:
| Method | Purpose |
|---|---|
add(I item) | Add item to collection |
iterator() | Iterate over items |
size(), isEmpty() | Collection size queries |
contains(String identifier) | Check for item by ID |
item(String identifier) | Retrieve item by ID |
updateItem(I item) | Replace existing item |
removeItem(String identifier) | Remove item by ID |
clear() | Remove all items |
Type parameters:
E: The HTML element type of the containerB: The builder type (for method chaining)I: The item type (must implement HasIdentifier)Sources: components/src/main/java/org/patternfly/component/table/Tr.java88
Items are stored in a LinkedHashMap to preserve insertion order. Every mutation operation triggers lifecycle events through AurHandler.
Sources: components/src/main/java/org/patternfly/component/table/Tr.java123-127 components/src/main/java/org/patternfly/component/table/Tr.java152-157 components/src/main/java/org/patternfly/component/table/Tr.java395-408
AurHandler coordinates lifecycle events for collection items:
Container components expose event registration methods:
This enables reactive patterns where external code responds to collection changes without tight coupling.
Sources: components/src/main/java/org/patternfly/component/table/Tr.java133 components/src/main/java/org/patternfly/component/table/Tr.java251-264
Some containers support sorted insertion via the Ordered<I> interface:
Items are inserted in sorted order according to the provided comparator. This is used in Menu and Table for alphabetically sorted items or custom orderings.
Sources: Diagram 3 in high-level architecture overview
PatternFly components follow a consistent event registration pattern:
| Pattern | Example | Purpose |
|---|---|---|
on<Event> | onClick, onChange, onToggle | Register event handler |
on<Action> | onAdd, onUpdate, onRemove | Register lifecycle handler |
All registration methods:
Common handler types:
The Event parameter is always first, followed by the component/item, then any event-specific data.
Handlers are stored in List fields and invoked using forEach loops, allowing multiple independent observers of the same event.
Sources: components/src/main/java/org/patternfly/component/button/Button.java321-324 components/src/main/java/org/patternfly/component/form/Checkbox.java225-228 components/src/main/java/org/patternfly/component/table/Table.java206-214 components/src/main/java/org/patternfly/component/table/Tr.java251-269
Component construction follows a standard pattern:
BaseComponentstoreComponent() registers in global lookup tableSources: components/src/main/java/org/patternfly/component/menu/MenuToggle.java149-181
Some components perform finalization after being attached to the DOM:
The Attachable interface provides attach() and detach() hooks triggered by MutationObserver when components enter/leave the DOM.
Sources: components/src/main/java/org/patternfly/component/table/Table.java102-118
Components synchronize state between Java objects and DOM elements:
State changes may trigger:
Sources: components/src/main/java/org/patternfly/component/form/Checkbox.java196-207
The Table component demonstrates complex state management:
Selection state is managed at three levels:
Sources: components/src/main/java/org/patternfly/component/table/Table.java81-83 components/src/main/java/org/patternfly/component/table/Table.java245-278 components/src/main/java/org/patternfly/component/table/Tr.java441-463
Some components use the delegate pattern to redirect operations to child elements:
The ElementContainerDelegate interface allows a component to specify which child element should receive content added via add() methods:
This is used by Button to ensure content is added to the text span rather than the button's root element.
Sources: components/src/main/java/org/patternfly/component/button/Button.java163-166
Similarly, ElementTextDelegate redirects text operations:
This allows Checkbox.text("Label") to set the label text, not the checkbox wrapper's text.
Sources: components/src/main/java/org/patternfly/component/form/Checkbox.java115-118
The core architecture provides:
| Pattern | Purpose | Key Types |
|---|---|---|
| Component Foundation | Base classes for all components | BaseComponent |
| Interface Composition | Capability declaration via mixins | Disabled, HasValue, Expandable, etc. |
| Type-Safe Builders | Fluent API with type preservation | Generic bounds <E, B> |
| Component Context | Arbitrary data storage | ComponentContext, HasIdentifier |
| Collection Management | Standard container operations | HasItems, AurHandler, Ordered |
| Event Handling | Consistent event registration | on<Event> methods, functional interfaces |
| Lifecycle Hooks | DOM attachment/detachment | Attachable interface |
| Delegate Pattern | Redirect operations to children | ElementContainerDelegate, ElementTextDelegate |
These patterns work together to create a consistent, type-safe, composable component system that minimizes boilerplate while maintaining flexibility.
Sources: components/src/main/java/org/patternfly/component/button/Button.java82-93 components/src/main/java/org/patternfly/component/form/Checkbox.java62-66 components/src/main/java/org/patternfly/component/menu/MenuToggle.java72-80 components/src/main/java/org/patternfly/component/table/Table.java62-64 components/src/main/java/org/patternfly/component/table/Tr.java85-89 components/src/main/java/org/patternfly/component/table/Cell.java33-37
Refresh this wiki