检票口倒计时器不会自动更新

发布于 2024-11-29 07:22:21 字数 720 浏览 0 评论 0原文

我想在 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 方法,因此不能被重写。正确的做法是什么?

I would like to implement a countdown timer in Wicket. I have a clock class:

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

and here I attempt to update it every second:

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

This doesn't work because onTimer is a final method and therefore cannot be overridden. What is the correct approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

任性一次 2024-12-06 07:22:21

这里有两个问题。

  1. time 出现在生成的标签标记中的什么位置?该模型仅包含消息,因此即使时间发生变化,也不会产生任何影响。
  2. 正如您所提到的,onTimer() 是最终的,即使它不是最终的,也不能保证它每秒都会被精确地调用。

因此,正如 Wicket 中经常出现的那样,解决方案是将其颠倒过来,而不是将数据推送到输出中,而是让框架将其拉入。这就是您需要做的。

  1. 您不需要单独的 Clock 类,只需使用一个普通的 Label 即可,无需覆盖任何内容。
  2. 创建一个 IModel 子类,用于存储时钟应为零的时间戳。
  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 );
    }

}

您可能可以猜到其余的内容。

更新:还有一件事,有点明显但可能值得一提:在现实世界的应用程序中,请确保检查剩余时间不是负值。

There are two problems here.

  1. Where does time appear in the generated label markup? The model simply contains the message so even if time is changed, it won't make any difference.
  2. As you mentioned, onTimer() is final, and even if it wasn't, there's no guarantee that it would be invoked precisely every second.

So the solution, as so often in Wicket is to turn it upside down, instead of pushing data into your output, let the framework pull it in. This is what you need to do.

  1. You don't need a separate Clock class, use just a plain Label with nothing overridden.
  2. Create an IModel<String> subclass that stores the timestamp when the clock should be at zero.
  3. Make the getObject() method of the model return a string that contains the difference between the clock's zero time and the current time.
  4. Set an instance of this as the model of your Label and add the ajax timer behaviour too.
  5. Done.

Your model will be something like this:

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

}

You can probably guess the rest.

Update: just one more thing, kind of obvious but may be worth mentioning: in a real world application make sure you check that time left isn't negative.

幸福还没到 2024-12-06 07:22:21

另一个答案是最好的,但另一种选择是使用 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);
        }
    });

The other answer is best, but another alternative is to use an AbstractAjaxTimerBehavior, where the onTimer method is not final.

Look at the source code for the Wicket Stuff World Clock example and you'll see

    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);
        }
    });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文