3.5.4.1. Timer

Timer is a non-visual component designed to run some screen controller code at specified time intervals. The timer works in a thread that handles user interface events, therefore it can update screen components. Timer stops working when a screen it was created for is closed.

The main approach for creating timers is by declaring them in the facets element of the screen XML descriptor.

Timers are described using the timer element.

  • delay is a required attribute; it defines timer interval in milliseconds.

  • autostart – an optional attribute; when it is set to true, timer starts immediately after the screen is opened. By default, the value is false, which means that the timer will start only when its start() method is invoked.

  • repeating – an optional attribute, turns on repeated executions of the timer. If the attribute is set to true, the timer runs in cycles at equal intervals defined in the delay attribute. Otherwise, the timer runs only once – delay milliseconds after the timer start.

To execute some code on timer, subscribe to its TimerActionEvent in the screen controller.

An example of defining a timer and subscribing to it in the controller:

<window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd" ...>
    <facets>
        <timer id="myTimer" delay="3000" autostart="true" repeating="true"/>
    </facets>
@Inject
private Notifications notifications;

@Subscribe("myTimer")
private void onTimer(Timer.TimerActionEvent event) {
    notifications.create(Notifications.NotificationType.TRAY)
        .withCaption("on timer")
        .show();
}

A timer can be injected into a controller field, or acquired using the getWindow().getFacet() method. Timer execution can be controlled using the timer’s start() and stop() methods. For an already active timer, start() invocation will be ignored. After stopping the timer using stop() method, it can be started again with start().

Example of defining a timer in an XML descriptor and using timer listeners in a controller:

<window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd" ...>
    <facets>
        <timer id="helloTimer" delay="5000"/>
    <facets>
@Inject
private Timer helloTimer;
@Inject
private Notifications notifications;

@Subscribe("helloTimer")
protected void onHelloTimerTimerAction(Timer.TimerActionEvent event) { (1)
    notifications.create()
            .withCaption("Hello")
            .show();
}

@Subscribe("helloTimer")
protected void onHelloTimerTimerStop(Timer.TimerStopEvent event) { (2)
    notifications.create()
            .withCaption("Timer is stopped")
            .show();
}

@Subscribe
protected void onInit(InitEvent event) { (3)
    helloTimer.start();
}
1 timer execution handler
2 timer stop event
3 start the timer

A timer can be created in a controller, in this case it should be added to the screen implicitly using the addFacet() method, for example:

@Inject
private Notifications notifications;
@Inject
private UiComponents uiComponents;

@Subscribe
protected void onInit(InitEvent event) {
    Timer helloTimer = uiComponents.create(Timer.NAME);
    getWindow().addFacet(helloTimer); (1)
    helloTimer.setId("helloTimer"); (2)
    helloTimer.setDelay(5000);
    helloTimer.setRepeating(true);

    helloTimer.addTimerActionListener(e -> { (3)
        notifications.create()
                .withCaption("Hello")
                .show();
    });

    helloTimer.addTimerStopListener(e -> { (4)
        notifications.create()
                .withCaption("Timer is stopped")
                .show();
    });

    helloTimer.start(); (5)
}
1 add timer to the screen
2 set timer parameters
3 add execution handler
4 add stop listener
5 start the timer