Documentation

Documentation versions (currently viewingVaadin 23)

You are viewing documentation for Vaadin 23. View latest documentation

Handling Portlet Phases

Introduces the API to use to interact with the Portlet phases and Portlet requests

The Portlet specification deals with requests and responses. Portlets receive render requests, action requests, resource requests, and more. This request-centric approach isn’t immediately compatible with the types of applications you build with Vaadin – modern, dynamic applications. To operate seamlessly in the portlet environment, Vaadin Portlet support offers both 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 don’t mesh with Vaadin. Normally, a 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. This section takes a look at different listeners that 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 the 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 is 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 that allow a view component to be implemented 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:

Next, have a look at the listeners which 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 can 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 the event object is WindowStateEvent, which contains the information about the window state and helpful shorthands for accessing the most commonly needed properties.

Listeners Invocation Order

Sometimes, you may want to have a component class with several listeners. Vaadin Portlet supports calls to each listener only once per portlet request and in the following order.

  1. PortletModeListener

  2. WindowStateListener

  3. EventListener

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 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's processing requests
context.setPortletMode(PortletMode.EDIT);

Similarly, portlet window state can be changed by calling:

// for the current portlet that's processing requests
context.setWindowState(WindowState.MAXIMIZED);
Warning
Portlet state and mode change don’t work with Liferay, because of an issue in Liferay Portal. Use Liferay’s native context menu to trigger Portlet mode and state 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 (or VaadinLiferayPortlet for Liferay) and MyView extending Div (a view class). The view class implements PortletView.

MyView reacts to the 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, and 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

Another way to listen to changes in window state and portlet mode, instead of PortletView, is to implement the WindowStateHandler and/or the PortletModeHandler interface in your view. The following example shows how to react to changes to window state using 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 don’t 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 minimized state or not. It returns false by default which means no rendering when minimized. You need to override it 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);
    }
}

0F7FAF85-17BE-4D5B-B16E-64BACA38C2FA