Handling Portlet Phases
The Portlet specification deals with requests and responses. Portlets receive render requests, action requests, resource requests, and more. This request-centric approach is not immediately compatible with the types of applications you build with Vaadin – modern, dynamic applications. In order to operate seamlessly in the portlet environment, Vaadin Portlet support offers the means to hook into these state changes, as well as shorthands to perform portlet tasks in a more idiomatic Vaadin way.
Portlet Requests and Phases
The portlet model operates on phases which do not mesh naturally with Vaadin. Normally, the phase request contains data that the user might be interested in, but since it makes little sense for a Vaadin Portlet to handle such requests, listeners were introduced. In this section, we take a look at different listeners, which allow Vaadin Portlets to hook into the different phases while operating within the UI thread of their Vaadin application.
The Portlet View
As described in Creating Vaadin Portlets, the Vaadin Portlet consists of two parts: a class extending VaadinPortlet
(or VaadinLiferayPortlet
for Liferay) and a portlet view class extending Vaadin Component
.
The portlet view is the Vaadin component defining the UI of your portlet.
Any Component
subclass can be used as the base class for the portlet view.
The portlet view is instantiated automatically from the actual type parameter passed to subclass of VaadinPortlet
(or VaadinLiferayPortlet
for Liferay).
This means that the portlet view class must have a default (no-arguments) constructor.
When a Vaadin Portlet is rendered the first time, a new view instance is created, and each portlet instance on a portal page gets its own view instance for each browser window in which the page is open.
The server-side instances are preserved when the page is refreshed, for example due to a portal-triggered render event or when manually reloaded in the browser by the user.
This means that the client side gets automatically repopulated with the state
(similar to how views in servlet-based Vaadin applications behave when annotated with @PreserveOnRefresh
).
Listeners
Vaadin Portlet support offers various listeners which allow you to implement a view component to react to updates from the portal.
To add a listener, your view should first implement PortletView
.
Then in PortletView.onPortletViewContextInit()
, you have access to PortletViewContext
, which allows you to add the listeners you need.
The available listeners are:
-
PortletModeListener
-
WindowStateListener
-
PortletEventListener
(part of the Inter-Portlet Communication)
Next, we will have a look at the listeners that enable the view component to react to changes to the portlet’s state.
PortletModeListener
Portlets can operate in different modes.
The standard modes in the portlet specification are View
, Edit
, and Help
.
Users of the portlet can change these modes using the controls on the portlet window, or through the portlet API.
React to changes to the portlet mode by adding a PortletModeListener
to the PortletViewContext
class:
public class MyPortletView extends Div implements PortletView {
@Override
public void onPortletViewContextInit(PortletViewContext context) {
context.addPortletModeChangeListener(event -> showHelpText(event.isHelpMode()));
}
}
The type of event
object is PortletModeEvent
, which contains information such as the portlet mode, the previous portlet mode, and helpful shorthands for accessing the most commonly needed properties.
WindowStateListener
A portlet window have different sizes, or window states.
The standard states in the portlet specification are Normal
, Maximized
, and Minimized
.
Users of the portlet can change these states using the controls on the portlet window, or through the portlet API.
React to changes to the window states by adding a WindowStateListener
to the PortletViewContext
class:
public class MyPortletView extends Div implements PortletView {
@Override
public void onPortletViewContextInit(PortletViewContext context) {
context.addWindowStateChangeListener(event -> showDetailsField(event.isMaximized()));
}
}
The type of event
object is WindowStateEvent
, which contains information about the window state and helpful shorthands for accessing the most commonly needed properties.
Changing the Portlet States from Java
In addition to handling the different state changes originating from the client side, you can also invoke the same changes from the Java code.
This is done by using the API provided by the VaadinPortlet
, or calling the same methods on your own portlet class extending VaadinPortlet
.
You can change the portlet mode of the portlet by calling:
// for the current portlet that is processing requests
context.setPortletMode(PortletMode.EDIT);
Similarly, the portlet window state can be changed by calling:
// for the current portlet that is processing requests
context.setWindowState(WindowState.MAXIMIZED);
Warning
| Portlet state and mode change do not work with Liferay, because of an issue in Liferay Portal. Use Liferay’s native context menu to trigger Portlet state and mode change. |
Example of a Vaadin Portlet Reacting to and Changing States
This is a full example, with two classes, MyPortlet
(a portlet class), extending VaadinPortlet
, and MyView
, extending Div
(a view class).
The view class implements PortletView
.
MyView
reacts to status changes by updating the text of a Paragraph
, informing the user whether the portlet mode or the window state changed.
The example also shows how the developer can change portlet mode and window state from the Java code.
The view contains two buttons.
One, with the text "Maximize", changes the window state of the portlet to MAXIMIZED
; the other, with the text "Show help", sets the portlet mode to HELP
.
public class MyPortlet extends VaadinPortlet<MyView> {
}
public class MyView extends Div implements PortletView {
private Paragraph stateInformation;
@Override
public void onPortletViewContextInit(PortletViewContext context) {
context.addWindowStateChangeListener(event -> stateInformation
.setText("Window state changed to " + event.getWindowState()));
context.addPortletModeChangeListener(event -> stateInformation
.setText("Portlet mode changed to " + event.getPortletMode()));
stateInformation = new Paragraph("Use the portlet controls or the "
+ "buttons below to change the portlet's state!");
Button maximizeButton = new Button("Maximize", event -> context.setWindowState(WindowState.MAXIMIZED));
Button helpButton = new Button("Show help", event -> context.setPortletMode(PortletMode.HELP));
add(stateInformation, maximizeButton, helpButton);
}
}
Using Handler Interfaces
There is another way to listen to changes in window state and portlet mode.
In this scheme, instead of PortletView
, your view should implement the WindowStateHandler
and/or PortletModeHandler
interfaces.
The following example shows how to react to changes to window state using the WindowStateHandler
interface, and changes to portlet mode using the PortletModeHandler
interface.
public class MyView extends Div
implements PortletModeHandler, WindowStateHandler {
private Paragraph stateInformation = new Paragraph();
public MyView() {
add(stateInformation);
}
@Override
public void portletModeChange(PortletModeEvent event) {
stateInformation
.setText("Portlet mode changed to " + event.getPortletMode());
}
@Override
public void windowStateChange(WindowStateEvent event) {
stateInformation
.setText("Window state changed to " + event.getWindowState());
}
}
Rendering in Minimized Window State
Normally, portlets do not render anything when they are minimized.
But, in your Vaadin portlets, you can render a minimal output when your portlet is minimized.
The shouldRenderMinimized()
method in VaadinPortlet
determines whether the portlet supports rendering in a minimized state or not.
It returns false
by default, which means no rendering when minimized.
If you want rendering when the portlet is minimized, you need to override this method in your portlet class and return true
instead.
public class MyPortlet extends VaadinPortlet<MyView> {
@Override
protected boolean shouldRenderMinimized() {
return true;
}
}
In your view class, you can add a WindowStateListener
to your PortletViewContext
where you can decide what to render in different window states.
For example, in the following view, minimizedLayout
is rendered when the portlet is minimized.
Otherwise, normalLayout
is rendered.
public class MyView extends Div implements PortletView {
private VerticalLayout normalLayout = new VerticalLayout();
private VerticalLayout minimizedLayout = new VerticalLayout();
@Override
public void onPortletViewContextInit(PortletViewContext context) {
context.addWindowStateChangeListener(this::handleWindowStateChanged);
// Initialize layouts here
minimizedLayout.setVisible(false);
add(normalLayout, minimizedLayout);
}
private void handleWindowStateChanged(WindowStateEvent event) {
boolean isMinimized = WindowState.MINIMIZED.equals(event.getWindowState());
minimizedLayout.setVisible(isMinimized);
normalLayout.setVisible(!isMinimized);
}
}
978850F8-8EBE-4502-A302-7C777CD6280E