View Events
This section describes the view lifecycle events that can be handled in controllers. To gain a general understanding of the sequence of events, see the diagrams at the end of the section.
To generate a view event handler stub in Jmix Studio, select the root Alternatively, execute the Generate Handler action available in the top panel of the view class and through the Code → Generate menu (Alt+Insert / Cmd+N). |
InitEvent
InitEvent
is the first event in the view opening process. The view and all its declaratively defined components are created, and dependency injection is completed. Some visual components are not fully initialized, for example, buttons are not linked with actions. In this event listener, you can create and/or initialize visual and data components.
@ViewComponent
private JmixComboBox<String> timeZoneField;
@Subscribe
public void onInit(final InitEvent event) {
timeZoneField.setItems(List.of(TimeZone.getAvailableIDs()));
}
The event is triggered only once after the view is created. This means that if the navigation to the view occurs for the first time, the event triggers. However, if navigation is performed to a view that is currently open, for example, by clicking on the same menu item multiple times, the event will not be triggered because the view instance has already been created. |
BeforeShowEvent
BeforeShowEvent
is the second event (after View.InitEvent
) in the view opening process. All components have completed their internal initialization procedures. Data loaders have been triggered by the automatically configured DataLoadCoordinator facet. Security policies are applied to UI components. In this event listener, you can load data, check permissions and modify UI components. For example:
@ViewComponent
private CollectionLoader<User> usersDl;
@Subscribe
public void onBeforeShow(final BeforeShowEvent event) {
usersDl.load();
}
Consequent navigation to a view that is currently open, leads to triggering For example, the user navigates to a view for the first time, the view instance is created and
|
ReadyEvent
ReadyEvent
is the last event (after View.BeforeShowEvent
) in the view opening process. In this event listener, you can make final configuration of the view according to loaded data and show notifications or dialogs.
@Autowired
private Notifications notifications;
@Subscribe
public void onReady(final ReadyEvent event) {
notifications.show("Just opened");
}
Consequent navigation to a view that is currently open, leads to triggering For example, the user navigates to a view for the first time, the view instance is created and
|
AttachEvent
AttachEvent
is fired after a view is attached to the UI.
@Subscribe
public void onAttachEvent(final AttachEvent event) {
log.debug("View is attached");
}
This event is fired by Vaadin, since a view is a UI component too. |
BeforeCloseEvent
BeforeCloseEvent
is the first event in the view closing process. The view is still displayed and fully functional. In this event listener, you can check any conditions and prevent closing using the preventClose()
method of the event.
@Subscribe
public void onBeforeClose(BeforeCloseEvent event) {
if (!isLicenseAgreementAccepted()) {
CloseAction action = event.getCloseAction();
if (action instanceof NavigateCloseAction navigateCloseAction) {
BeforeLeaveEvent beforeLeaveEvent = navigateCloseAction.getBeforeLeaveEvent();
beforeLeaveEvent.postpone();
}
event.preventClose();
}
}
If you prevent closing the view, in case of navigation you need to postpone it too. Check the type of action and if it’s NavigateCloseAction , then obtain Vaadin’s BeforeLeaveEvent and call its postpone() method.
|
AfterCloseEvent
AfterCloseEvent
is the second event (after View.BeforeCloseEvent
) in the view closing process. In this event listener, you can show notifications or dialogs after closing the view, for example:
@Autowired
private Notifications notifications;
@Subscribe
public void onAfterClose(final AfterCloseEvent event) {
notifications.show("View is closed");
}
DetachEvent
DetachEvent
is fired before a view is detached from the UI. This event listener can be used for releasing resources acquired by the view.
@Subscribe
public void onDetachEvent(final DetachEvent event) {
log.debug("View is detached");
}
This event is fired by Vaadin, since a view is a UI component too. |
QueryParametersChangeEvent
QueryParametersChangeEvent
informs which query parameters a view was opened with. It is sent after InitEvent
if the view was opened by navigation.
@ViewComponent
private Span messageLabel;
public void setMessage(String message) {
messageLabel.setText(message);
}
@Subscribe
public void onQueryParametersChange(final QueryParametersChangeEvent event) {
event.getQueryParameters()
.getSingleParameter("message")
.ifPresent(this::setMessage);
}
InitEntityEvent
InitEntityEvent
is fired in views inherited from StandardDetailView before the new entity instance is set to the edited entity container.
Use this event listener to initialize default values in the new entity instance, for example:
@Subscribe
public void onInitEntity(final InitEntityEvent<User> event) {
User user = event.getEntity();
user.setOnboardingStatus(OnboardingStatus.NOT_STARTED);
}
ValidationEvent
ValidationEvent
is fired in views inherited from StandardDetailView
when the view is validated on saving the view DataContext. Use this event listener to perform additional validation of the view.
@Subscribe
public void onValidation(final ValidationEvent event) {
if (entityStates.isNew(getEditedEntity())
&& !Objects.equals(passwordField.getValue(), confirmPasswordField.getValue())) {
event.getErrors().add("Passwords do not match");
}
}
BeforeSaveEvent
BeforeSaveEvent
is fired in views inherited from StandardDetailView
before saving the view DataContext
. Use this event listener to prevent saving, alter entity attribute values before saving or/and interact with the user before save.
@ViewComponent
private JmixPasswordField passwordField;
@ViewComponent
private JmixPasswordField confirmPasswordField;
@Autowired
private EntityStates entityStates;
@Autowired
private PasswordEncoder passwordEncoder;
@Subscribe
public void onBeforeSave(final BeforeSaveEvent event) {
if (entityStates.isNew(getEditedEntity())) {
if (!Objects.equals(passwordField.getValue(), confirmPasswordField.getValue())) {
notifications.create("Passwords do not match")
.withType(Notifications.Type.WARNING)
.show();
event.preventSave(); (1)
}
getEditedEntity().setPassword(passwordEncoder.encode(passwordField.getValue())); (2)
}
}
1 | Interrupt the saving process if passwords do not match. |
2 | Set encoded password to the entity. |
AfterSaveEvent
AfterSaveEvent
is fired in views inherited from StandardDetailView
after saving the view DataContext
. Use this event listener to notify users after save, for example:
@Autowired
private Notifications notifications;
@Subscribe
public void onAfterSave(final AfterSaveEvent event) {
notifications.create("Entity saved successfully")
.withType(Notifications.Type.SUCCESS)
.withPosition(Notification.Position.TOP_END)
.show();
}
Diagrams
Closing Entity Detail View
The following diagram shows the process of saving changes and closing a detail view by the detail_saveClose action: