Skip to content

Commit e5e5434

Browse files
committed
Add generic type to HistoryProvider and clear it after getting history
1 parent d54c7fd commit e5e5434

File tree

3 files changed

+21
-8
lines changed

3 files changed

+21
-8
lines changed

README.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,18 @@ demonstrate.
130130

131131
### Component Structure <a name="component-structure"></a>
132132

133-
A component, as a rule, consists of the following classes: `Component` (with an inner `Mediator` implementation),
133+
A component, as a rule, consists of the following classes: `Component` (with an inner `Mediator` implementation),
134134
`ComponentView`, `ComponentViewModel`, and `ComponentMediator`:
135135

136136
<img width="1016" height="457" alt="PatternFX" src="https://github.com/user-attachments/assets/28ea5b5f-7f86-4dc6-bc74-6c4ed3c1abd7" />
137137

138138
A natural question might arise: why is there no `Model` in the component, given that
139139
the pattern is called MVVM? Firstly, a component is a building block for constructing a user interface, which might
140140
not be related to the application's business logic at all. Secondly, the `Model` exists independently of the UI and
141-
should have no knowledge of the component's existence. Thirdly, MVVM is fundamentally about the separation of
141+
should have no knowledge of the component's existence. Thirdly, MVVM is fundamentally about the separation of
142142
responsibilities rather than the mandatory presence of all three layers in every element. In other words, a component
143-
does not violate MVVM principles simply because it lacks a `Model`; it remains compliant as long as the `View` and
144-
`ViewModel` maintain a clear separation of concerns and communicate exclusively through data binding and observable
143+
does not violate MVVM principles simply because it lacks a `Model`; it remains compliant as long as the `View` and
144+
`ViewModel` maintain a clear separation of concerns and communicate exclusively through data binding and observable
145145
properties.
146146

147147
The `ComponentView` and `ComponentViewModel` classes correspond to the `View` and `ViewModel` in the MVVM pattern and
@@ -216,6 +216,15 @@ restored from the `ComponentHistory` to the `ComponentViewModel`. Conversely, wh
216216
`DEINITIALIZED`, data from the `ComponentViewModel` is saved back to the `ComponentHistory`. The volume of state
217217
information that is restored and persisted is defined by the `HistoryPolicy` enum.
218218

219+
In addition to the four main classes, a component may include a `ComponentHistory`, which preserves the component’s
220+
state across its lifecycle. In the default implementation, the `ComponentHistory` instance is lazily provided via a
221+
`HistoryProvider` that is set before initialization. During the `preInitialize()` phase, the provider’s `provide()`
222+
method is called to obtain the history. After the history is obtained, the provider is cleared (set to null), and the
223+
component uses the history. State restoration occurs in the `preInitialize()` phase via the
224+
`AbstractComponentViewModel#restoreHistory()` method. State saving occurs in the `postDeinitialize()` phase via the
225+
`AbstractComponentViewModel#saveHistory()` method. The volume and type of state information that is restored and
226+
persisted are determined by the `HistoryPolicy` enum.
227+
219228
### Component Lifecycle<a name="component-lifecycle"></a>
220229

221230
Each component features `Component#initialize()` and `Component#deinitialize()` methods,

patternfx-core/src/main/java/com/techsenger/patternfx/core/AbstractComponent.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public void deinitialize() {
131131

132132
private final ObjectProperty<ComponentGroup> group = new SimpleObjectProperty<>();
133133

134-
private HistoryProvider historyProvider;
134+
private HistoryProvider<?> historyProvider;
135135

136136
private ComponentHistory<?> history;
137137

@@ -265,6 +265,7 @@ protected void preInitialize() {
265265
this.view.getViewModel().setMediator(mediator);
266266
if (this.historyProvider != null) {
267267
this.history = this.historyProvider.provide();
268+
this.historyProvider = null;
268269
}
269270
this.view.getViewModel().restoreHistory();
270271
}
@@ -288,7 +289,7 @@ protected void postDeinitialize() {
288289
}
289290
}
290291

291-
protected void setHistoryProvider(HistoryProvider historyProvider) {
292+
protected void setHistoryProvider(HistoryProvider<? extends ComponentHistory<?>> historyProvider) {
292293
this.historyProvider = historyProvider;
293294
}
294295

patternfx-core/src/main/java/com/techsenger/patternfx/core/HistoryProvider.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717
package com.techsenger.patternfx.core;
1818

1919
/**
20+
* Provides a history instance for a component. This method is called during the {@code preInitialize()} phase. After
21+
* the history is obtained, the component uses the returned history, and the provider is cleared (set to null).
2022
*
23+
* @param <T> the type of {@link ComponentHistory} provided
2124
* @author Pavel Castornii
2225
*/
2326
@FunctionalInterface
24-
public interface HistoryProvider {
27+
public interface HistoryProvider<T extends ComponentHistory<?>> {
2528

26-
ComponentHistory<?> provide();
29+
T provide();
2730
}

0 commit comments

Comments
 (0)