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?
There are two problems here.
timeappear in the generated label markup? The model simply contains the message so even iftimeis changed, it won’t make any difference.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.
Clockclass, use just a plainLabelwith nothing overridden.IModel<String>subclass that stores the timestamp when the clock should be at zero.getObject()method of the model return a string that contains the difference between the clock’s zero time and the current time.Labeland add the ajax timer behaviour too.Your model will be something like this:
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.