4.5.2.3.3. Timer

Timer is a non-visual component allowing certain screen controller code to be run at specified time intervals. The timer works in a thread that handles user interface events, which allows screen to be refreshed without any limitations. Timer stops working when a screen it was created for gets closed.

The component is implemented for the Web Client and the Desktop Client. For the web client, timer implementation is based on interrogation server from web-browser, for the desktop client it based on javax.swing.Timer.

The main approach for creating the timers is by declaring them in a screen XML-descriptor – in the timers, element which is located between dsContext and layout elements.

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 a screen gets opened. By default the value is false, which means that timer should be started by invoking its start() method.

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

  • onTimer – optional attribute containing a name of a method called when the timer fires. The handling method should be defined in a screen controller with a public modifier and have one com.haulmont.cuba.gui.components.Timer type parameter.

An example of using a timer to refresh table content periodically:

<window ...
  <dsContext>
      <collectionDatasource id="bookInstanceDs" ...
  </dsContext>
  <timers>
      <timer delay="3000" autostart="true" repeating="true" onTimer="refreshData"/>
  </timers>
  <layout ...
@Inject
private CollectionDatasource bookInstanceDs;

public void refreshData(Timer timer) {
    bookInstanceDs.refresh();
}

Timer can be injected into a controller field, or acquired using the Window.getTimer() method. Timer activity 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().

An event handler can be set for a timer using the implementation of a Timer.TimerListener interface:

<timers>
    <timer id="helloTimer" delay="5000"/>
</timers>
@Inject
private Timer helloTimer;

@Override
public void init(Map<String, Object> params) {
    helloTimer.addTimerListener(new Timer.TimerListener() {
        @Override
        public void onTimer(Timer timer) {
            showNotification("Hello", NotificationType.HUMANIZED);
        }

        @Override
        public void onStopTimer(Timer timer) {
            showNotification("Timer is stopped", NotificationType.HUMANIZED);
        }
    });

    helloTimer.start();
}
Timer can be also created in the application controller code:
@Inject
private ComponentsFactory componentsFactory;

@Override
public void init(Map<String, Object> params) {
    Timer helloTimer = componentsFactory.createTimer();
    helloTimer.setDelay(5000);
    helloTimer.setRepeating(true);
    helloTimer.addTimerListener(new Timer.TimerListener() {
        @Override
        public void onTimer(Timer timer) {
            showNotification("Hello", NotificationType.HUMANIZED);
        }

        @Override
        public void onStopTimer(Timer timer) {
            showNotification("Timer is stopped", NotificationType.HUMANIZED);
        }
    });
    helloTimer.start();

    addTimer(helloTimer);
}