3.5.2.4.4. 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().

Пример определения таймера в XML дескрипторе и использования листенеров в контроллере:

<timers>
    <timer id="helloTimer" delay="5000"/>
</timers>
@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 обработчик выполнения таймера
2 остановка таймера
3 запуск таймера при инициализации экрана

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

@Inject
private Notifications notifications;
@Inject
private Facets facets;

@Subscribe
protected void onInit(InitEvent event) {
    Timer helloTimer = facets.create(Timer.class);
    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 добавление таймера к экрану
2 установка параметров таймера
3 добавление обработчика выполнения
4 добавление слушателя остановки таймера
5 запуск таймера