4.5.2.3.3. Timer

Таймер − это невизуальный компонент, позволяющий выполнять некоторый код контроллера экрана через определенные промежутки времени. Срабатывание таймера происходит в потоке обработки событий пользовательского интерфейса, что позволяет обновлять экран без каких-либо ограничений. Таймер прекращает работу при закрытии экрана, для которого он был создан.

Компонент реализован для блоков Web Client и Desktop Client. Для веб клиента реализация таймеров основана на опросе сервера из веб-браузера, для десктоп клиента - на javax.swing.Timer.

Основной способ создания таймеров - декларативно в XML-дескрипторе экрана в элементе timers, располагающемся между элементами dsContext и layout.

Для описания таймера используется элемент timer.

  • Атрибут delay является обязательным атрибутом, в нем задается интервал срабатывания таймера в миллисекундах.

  • autostart - необязательный атрибут, при установке которого в true таймер стартует сразу после открытия экрана. По умолчанию false, что означает что для старта таймера необходимо вызвать его метод start().

  • repeating − необязательный атрибут, включает многократное срабатывание таймера. Если значение атрибута равно true, то таймер выполняется циклически, через равные промежутки времени, заданные в атрибуте delay. В противном случае таймер выполняется один раз через delay миллисекунд после старта таймера.

  • onTimer − необязательный атрибут, содержащий имя метода, вызываемого при срабатывании таймера. Метод-обработчик должен быть определен в контроллере экрана с модификатором public и иметь один параметр типа com.haulmont.cuba.gui.components.Timer.

Пример использования таймера для периодического обновления содержимого таблицы:

<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();
}

Таймер можно инжектировать в поле контроллера, либо получить методом Window.getTimer(). Управлять активностью таймера можно с помощью его методов start() и stop(). Для уже активного таймера вызов start() игнорируется. После остановки таймера методом stop() его можно снова запустить методом start().

Задать обработчик событий от таймера можно с помощью реализации интерфейса Timer.TimerListener:

<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();
}

Таймер можно также создавать в коде контроллера приложения следующим образом:

@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);
}