Skip to content

Commit ddb7ff2

Browse files
committed
Add composer
1 parent 1d977f1 commit ddb7ff2

15 files changed

+311
-143
lines changed

README.md

Lines changed: 111 additions & 40 deletions
Large diffs are not rendered by default.

mvvm4fx-core/src/main/java/com/techsenger/mvvm4fx/core/AbstractComponentMediator.java renamed to mvvm4fx-core/src/main/java/com/techsenger/mvvm4fx/core/AbstractChildComposer.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,13 @@
2020
*
2121
* @author Pavel Castornii
2222
*/
23-
public abstract class AbstractComponentMediator<T extends ParentView<?>> implements ComponentMediator {
23+
public abstract class AbstractChildComposer<T extends ChildView<?>> extends AbstractParentComposer<T> {
2424

25-
private final T view;
25+
protected abstract class ViewModelComposer extends AbstractParentComposer.ViewModelComposer {
2626

27-
public AbstractComponentMediator(T view) {
28-
this.view = view;
2927
}
3028

31-
protected final T getView() {
32-
return view;
29+
public AbstractChildComposer(T view) {
30+
super(view);
3331
}
3432
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2024-2025 Pavel Castornii.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.techsenger.mvvm4fx.core;
18+
19+
/**
20+
*
21+
* @author Pavel Castornii
22+
*/
23+
public abstract class AbstractComponentComposer<T extends ComponentView<?>> implements ComponentComposer<T> {
24+
25+
protected abstract class ViewModelComposer implements ComponentViewModel.Composer {
26+
27+
}
28+
29+
private final T view;
30+
31+
private final ComponentViewModel.Composer viewModelComposer;
32+
33+
public AbstractComponentComposer(T view) {
34+
this.view = view;
35+
this.viewModelComposer = createViewModelComposer();
36+
}
37+
38+
@Override
39+
public ParentViewModel.Composer getViewModelComposer() {
40+
return viewModelComposer;
41+
}
42+
43+
@Override
44+
public void initialize() {
45+
46+
}
47+
48+
@Override
49+
public void deinitialize() {
50+
51+
}
52+
53+
protected final T getView() {
54+
return view;
55+
}
56+
57+
protected abstract ComponentViewModel.Composer createViewModelComposer();
58+
}

mvvm4fx-core/src/main/java/com/techsenger/mvvm4fx/core/AbstractComponentView.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,15 @@ public abstract class AbstractComponentView<T extends AbstractComponentViewModel
2929

3030
private T viewModel;
3131

32+
private ComponentView.Composer composer;
33+
3234
public AbstractComponentView(T viewModel) {
3335
this.viewModel = viewModel;
36+
var composer = createComposer();
37+
this.composer = composer;
38+
if (this.composer != null) {
39+
viewModel.setComposer(composer.getViewModelComposer());
40+
}
3441
}
3542

3643
@Override
@@ -86,6 +93,29 @@ public final void deinitialize() {
8693
}
8794
}
8895

96+
public ComponentView.Composer getComposer() {
97+
return composer;
98+
}
99+
100+
public void setComposer(ComponentView.Composer composer) {
101+
this.composer = composer;
102+
}
103+
104+
/**
105+
* Creates a new {@link ComponentComposer} instance for this component.
106+
*
107+
* <p>This method is invoked during the component's construction phase and allows subclasses to provide a custom
108+
* composer implementation. However, this method should be used only if the component is the owner of the composer.
109+
* Otherwise the component setter should be used.
110+
*
111+
* <p>The default implementation returns {@code null}, meaning the component does not create a composer by default.
112+
*
113+
* @return a newly created {@link ComponentComposer}, or {@code null} if none is required
114+
*/
115+
protected ComponentComposer<?> createComposer() {
116+
return null;
117+
}
118+
89119
/**
90120
* Returns the component descriptor for convenient access. This is a shortcut method that delegates to the
91121
* underlying ViewModel's descriptor.

mvvm4fx-core/src/main/java/com/techsenger/mvvm4fx/core/AbstractComponentViewModel.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public abstract class AbstractComponentViewModel implements ComponentViewModel {
3737

3838
private ComponentHistory<?> history;
3939

40+
private ComponentViewModel.Composer composer;
41+
4042
public AbstractComponentViewModel() {
4143
this.descriptor = createDescriptor();
4244
this.descriptor.stateProperty().addListener((ov, oldV, newV) -> {
@@ -111,6 +113,14 @@ public void setHistoryProvider(HistoryProvider historyProvider) {
111113
this.historyProvider = historyProvider;
112114
}
113115

116+
public Composer getComposer() {
117+
return composer;
118+
}
119+
120+
public void setComposer(Composer composer) {
121+
this.composer = composer;
122+
}
123+
114124
protected void postHistoryRestore() {
115125

116126
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2024-2025 Pavel Castornii.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.techsenger.mvvm4fx.core;
18+
19+
/**
20+
*
21+
* @author Pavel Castornii
22+
*/
23+
public abstract class AbstractParentComposer<T extends ParentView<?>> extends AbstractComponentComposer<T> {
24+
25+
protected abstract class ViewModelComposer extends AbstractComponentComposer.ViewModelComposer {
26+
27+
}
28+
29+
public AbstractParentComposer(T view) {
30+
super(view);
31+
}
32+
33+
}

mvvm4fx-core/src/main/java/com/techsenger/mvvm4fx/core/AbstractParentView.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ public abstract class AbstractParentView<T extends AbstractParentViewModel> exte
3535

3636
public AbstractParentView(T viewModel) {
3737
super(viewModel);
38-
viewModel.setMediator(createMediator());
3938
childrenSynchronizer = new ListSynchronizer<ChildView<?>, ChildViewModel>(children,
4039
viewModel.getModifiableChildren(), (v) -> v.getViewModel());
4140
}
@@ -67,21 +66,6 @@ List<ParentView<?>> getChildren(ParentView<?> parent) {
6766
};
6867
}
6968

70-
/**
71-
* Creates a new {@link ComponentMediator} instance for this component.
72-
*
73-
* <p>This method is invoked during the component's construction phase and allows subclasses to provide a custom
74-
* mediator implementation that defines how the {@code ComponentViewModel} interacts with its {@code ComponentView}.
75-
* The created mediator is then automatically assigned to the ViewModel.
76-
*
77-
* <p>The default implementation returns {@code null}, meaning the component does not use a mediator by default.
78-
*
79-
* @return a newly created {@code ComponentMediator}, or {@code null} if none is required
80-
*/
81-
protected ComponentMediator createMediator() {
82-
return null;
83-
}
84-
8569
@Override
8670
protected void addListeners(T viewModel) {
8771
super.addListeners(viewModel);
@@ -97,6 +81,5 @@ protected void addListeners(T viewModel) {
9781
}
9882
}
9983
});
100-
10184
}
10285
}

mvvm4fx-core/src/main/java/com/techsenger/mvvm4fx/core/AbstractParentViewModel.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,10 @@ public abstract class AbstractParentViewModel extends AbstractComponentViewModel
3131
private final ObservableList<ChildViewModel> children =
3232
FXCollections.unmodifiableObservableList(modifiableChildren);
3333

34-
private ComponentMediator mediator;
35-
3634
public AbstractParentViewModel() {
3735
super();
3836
}
3937

40-
@Override
41-
public ComponentMediator getMediator() {
42-
return this.mediator;
43-
}
44-
4538
@Override
4639
public ObservableList<ChildViewModel> getChildren() {
4740
return children;
@@ -69,10 +62,6 @@ List<ParentViewModel> getChildren(ParentViewModel parent) {
6962
};
7063
}
7164

72-
public void setMediator(ComponentMediator mediator) {
73-
this.mediator = mediator;
74-
}
75-
7665
ObservableList<ChildViewModel> getModifiableChildren() {
7766
return modifiableChildren;
7867
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2024-2025 Pavel Castornii.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.techsenger.mvvm4fx.core;
18+
19+
/**
20+
*
21+
* @author Pavel Castornii
22+
*/
23+
public interface ComponentComposer<T extends ComponentView<?>> extends ComponentView.Composer {
24+
25+
ComponentViewModel.Composer getViewModelComposer();
26+
}

mvvm4fx-core/src/main/java/com/techsenger/mvvm4fx/core/ComponentHistory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
* Represents a serializable snapshot of a component's {@code ViewModel} state. A history object stores only the
2323
* information that must persist between component sessions and excludes all transient or runtime aspects.
2424
*
25-
* <p>The {@code ViewModel} itself may contain both persistent and non-persistent values. It also defines default values
26-
* for all of its properties, regardless of whether they are stored in the history or used only at runtime. The
25+
* <p>The {@code ViewModel} itself may contain both persistent and non-persistent values. It also defines default
26+
* values for all of its properties, regardless of whether they are stored in the history or used only at runtime. The
2727
* {@code ViewModel} owns the meaning of those defaults, while the history is responsible solely for persisting and
2828
* restoring the subset of states that are marked as persistent.
2929
*

0 commit comments

Comments
 (0)