By default when we just add given facet it applies and saves settings for all available components on the screen. We can configure facet to save only specific components using attribute auto=false:
Note, that settingsEnabled attrbitue does not work for controller (screen) that extends Screen class. This property works only for Legacy screens.
Screen controller API
ScreenSettingsFacet provides hooks for the screen settings lifecycle:
setApplySettingsDelegate() (on AfterShowEvent)
setApplyDataLoadingSettingsDelegate() (on BeforeShowEvent)
setSaveSettingsDelegate() (on AfterDetachEvent)
Example of install delegate for appling settings
```
@Inject
private ScreenSettingsFacet settingsFacet;
@Install(to = "settingsFacet", subject = "applySettingsDelegate")
private void applySettings(ScreenSettingsFacet.SettingsContext settings) {
settings.getBoolean("myPanel", "visible")
.ifPresent(myPanel::setVisible);
// apply for others
settingsFacet.applySettings(settings);
}
```
Example if window contains lazy tab
```
@Inject
private ScreenSettingsFacet settingsFacet;
@Install(to = "settingsFacet", subject = "applySettingsDelegate")
private void onApplySettings(ScreenSettingsFacet.SettingsContext context) {
if (getWindow().equals(context.getSource())) {
// if source is window
settingsFacet.applySettings(context.getScreenSettings());
} else {
// if source is lazy tab (accordion or tabSheet)
settingsFacet.applySettings(context.getComponents(), context.getScreenSettings());
}
}
```
ScreenSettings class
ScreenSettings - a base interface for putting and getting component settings. The default implementation is ScreenSettingsJson which uses JSON for storing settings. ScreenSettingsJson is a prototype bean so it can be easily replaced by another implementation.
ScreenSettings has methods for putting and getting base primitive types: String, Integer, Long, Double, Boolean
ComponentSettings as settings class for a component
There are components that have settings that can be applied for the component and stored. To make settings more clear it is possible to create some settings class (POJO). This class provides properties that can be applied for the component and easy to store.
Just implement ComponentSettings interface:
GroupBoxSettings example
```
public class GroupBoxSettings implements ComponentSettings {
protected String id;
protected Boolean expanded;
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
public Boolean getExpanded() {
return expanded;
}
public void setExpanded(Boolean expanded) {
this.expanded = expanded;
}
}
```
ComponentSettingsBinder as settings worker
Since we have ComponentSettings implementation we should bind it to the corresponding component. To achieve this we should create bean implementation of ComponentSettingsBinder.
It will provide:
getComponentClass();
getSettingsClass();
GroupBoxSettingsWorker example
```
@org.springframework.stereotype.Component(GroupBoxSettingsWorker.NAME)
public class GroupBoxSettingsWorker implements ComponentSettingsWorker {
public static final String NAME = "jmix_GroupBoxSettingsWorker";
@Override
public Class extends Component> getComponentClass() {
return WebGroupBox.class;
}
@Override
public Class extends ComponentSettings> getSettingsClass() {
return GroupBoxSettings.class;
}
@Override
public void applySettings(Component component, SettingsWrapper wrapper) {
...
}
@Override
public boolean saveSettings(Component component, SettingsWrapper wrapper) {
...
return true // or false it should depends from changes
}
@Override
public ComponentSettings getSettings(Component component) {
...
return settings;
}
}
```
Description
Description in the ticket: jmix-framework/jmix#226
Coordinates
Add-on added to the
starter-standard
:io.jmix.starter.standard:jmix-starter-standard
Add-on coordinates:
io.jmix.starter.ui.persistence:jmix-starter-ui-persistence
Screen descriptor API
The base API for screen components settings is placed into
ScreenSettingsFacet
. In the screen descriptor, we should add the following schema:And now we able to add screen settings facet:
By default when we just add given facet it applies and saves settings for all available components on the screen. We can configure facet to save only specific components using attribute
auto=false
:Note, that
settingsEnabled
attrbitue does not work for controller (screen) that extendsScreen
class. This property works only for Legacy screens.Screen controller API
ScreenSettingsFacet provides hooks for the screen settings lifecycle:
setApplySettingsDelegate()
(onAfterShowEvent
)setApplyDataLoadingSettingsDelegate()
(onBeforeShowEvent
)setSaveSettingsDelegate()
(onAfterDetachEvent
)Example of install delegate for appling settings
``` @Inject private ScreenSettingsFacet settingsFacet; @Install(to = "settingsFacet", subject = "applySettingsDelegate") private void applySettings(ScreenSettingsFacet.SettingsContext settings) { settings.getBoolean("myPanel", "visible") .ifPresent(myPanel::setVisible); // apply for others settingsFacet.applySettings(settings); } ```Example if window contains lazy tab
``` @Inject private ScreenSettingsFacet settingsFacet; @Install(to = "settingsFacet", subject = "applySettingsDelegate") private void onApplySettings(ScreenSettingsFacet.SettingsContext context) { if (getWindow().equals(context.getSource())) { // if source is window settingsFacet.applySettings(context.getScreenSettings()); } else { // if source is lazy tab (accordion or tabSheet) settingsFacet.applySettings(context.getComponents(), context.getScreenSettings()); } } ```ScreenSettings class
ScreenSettings
- a base interface for putting and getting component settings. The default implementation isScreenSettingsJson
which uses JSON for storing settings.ScreenSettingsJson
is a prototype bean so it can be easily replaced by another implementation.ScreenSettings has methods for putting and getting base primitive types: String, Integer, Long, Double, Boolean
ScreenSettings put(String componentId, String property, String value)
Optional<String> getString(String componentId, String property);
It also supports the whole POJO of settings for a specific component:
ComponentSettings as settings class for a component
There are components that have settings that can be applied for the component and stored. To make settings more clear it is possible to create some settings class (POJO). This class provides properties that can be applied for the component and easy to store. Just implement
ComponentSettings
interface:GroupBoxSettings example
``` public class GroupBoxSettings implements ComponentSettings { protected String id; protected Boolean expanded; @Override public String getId() { return id; } @Override public void setId(String id) { this.id = id; } public Boolean getExpanded() { return expanded; } public void setExpanded(Boolean expanded) { this.expanded = expanded; } } ```ComponentSettingsBinder as settings worker
Since we have ComponentSettings implementation we should bind it to the corresponding component. To achieve this we should create bean implementation of
ComponentSettingsBinder
. It will provide:getComponentClass();
getSettingsClass();
GroupBoxSettingsWorker example
``` @org.springframework.stereotype.Component(GroupBoxSettingsWorker.NAME) public class GroupBoxSettingsWorker implements ComponentSettingsWorker { public static final String NAME = "jmix_GroupBoxSettingsWorker"; @Override public Class extends Component> getComponentClass() { return WebGroupBox.class; } @Override public Class extends ComponentSettings> getSettingsClass() { return GroupBoxSettings.class; } @Override public void applySettings(Component component, SettingsWrapper wrapper) { ... } @Override public boolean saveSettings(Component component, SettingsWrapper wrapper) { ... return true // or false it should depends from changes } @Override public ComponentSettings getSettings(Component component) { ... return settings; } } ```