Таймер обратного отсчета калитки не обновляется - PullRequest
1 голос
/ 12 августа 2011

Я хотел бы реализовать таймер обратного отсчета в Wicket. У меня есть класс часов:

public class Clock extends Label{
    private static int time;
    public Clock(int mytime,String id,String message){
    super(id,message);
        time=mytime;
        this.setDefaultModelObject(message);
    }

    public int getTimeLeft(){
        return time;
    }

    public void decrement(){
        time--;
    }
}

и здесь я пытаюсь обновлять его каждую секунду:

clock.add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(1)){
    protected void onTimer(AjaxRequestTarget target){
        clock.decrement();
        target.addComponent(clock);
    }           
});

Это не работает, потому что onTimer является методом final и поэтому не может быть переопределен. Какой правильный подход?

Ответы [ 2 ]

4 голосов
/ 12 августа 2011

Здесь есть две проблемы.

  1. Где появляется time в сгенерированной разметке метки? Модель просто содержит сообщение, поэтому, даже если time изменено, это не будет иметь никакого значения.
  2. Как вы упомянули, onTimer() является окончательным, и даже если это не так, нет гарантии, что он будет вызываться именно каждую секунду.

Таким образом, решение, как это часто бывает в Wicket, состоит в том, чтобы перевернуть его с ног на голову, вместо того, чтобы вставлять данные в ваш вывод, и позволить фреймворку это сделать.

  1. Вам не нужен отдельный класс Clock, используйте только простой Label без переопределения.
  2. Создание подкласса IModel<String>, в котором хранится метка времени, когда часы должны быть равны нулю.
  3. Заставьте метод getObject() модели вернуть строку, содержащую разницу между нулевым временем часов и текущим временем.
  4. Установите экземпляр этого как модель вашего Label и добавьте поведение таймера ajax.
  5. Готово.

Ваша модель будет примерно такой:

public class ClockModel implements IModel<String> {
    private long zeroTime;

    public ClockModel( int timeInSecs ) {
        this.zeroTime = System.currentTimeMillis() + (timeInSecs * 1000 );
    }

    public String getObject() {
        return String.valueOf( ( zeroTime - System.currentTimeMillis() ) / 1000 );
    }

}

Остальное вы, наверное, догадаетесь.

Обновление: Еще одна вещь, вроде очевидная, но, возможно, стоит упомянуть: в реальном приложении убедитесь, что оставшееся время не отрицательно.

0 голосов
/ 12 августа 2011

Другой ответ лучше, но другой альтернативой является использование AbstractAjaxTimerBehavior, где метод onTimer не является окончательным.

Посмотрите на исходный код примера Wicket Stuff World Clock , и вы увидите

    add(new AbstractAjaxTimerBehavior(Duration.seconds(1))
    {
        /**
         * @see org.apache.wicket.ajax.AbstractAjaxTimerBehavior#onTimer(org.apache.wicket.ajax.AjaxRequestTarget)
         */
        protected void onTimer(AjaxRequestTarget target)
        {
            target.addComponent(la);
            target.addComponent(ny);
            target.addComponent(moscow);
            target.addComponent(prague);
            target.addComponent(london);
        }
    });
...