I am trying to display a synchronized clock in my Java FX GUI with the function given below.
This also includes a timer function which runs if Timer=true
private Calendar cal;
private int minute;
private int hour;
private int second;
private String am_pm;
private boolean Timer;
private Integer tseconds;
private void startClock() {
Timeline clock = new Timeline(new KeyFrame(Duration.millis(Calendar.getInstance().get(Calendar.MILLISECOND)), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
cal = Calendar.getInstance();
second = cal.get(Calendar.SECOND);
minute = cal.get(Calendar.MINUTE);
hour = cal.get(Calendar.HOUR);
am_pm = (cal.get(Calendar.AM_PM) == 0) ? "AM" : "PM";
time.setText(String.format("%02d : %02d : %02d %s", hour, minute, second, am_pm));
if (Timer) {
if (tseconds == 0) {
Timer = false;
//timer.setText("Time Out");
} else {
//timer.setText(tseconds.toString());
tseconds--;
}
}
}
}), new KeyFrame(Duration.millis(Calendar.getInstance().get(Calendar.MILLISECOND))));
clock.setCycleCount(Animation.INDEFINITE);
clock.play();
}
I tested this few times and found that many a times the clock updates at a variable speed.
Look for the solution below.
Solved the issue.
I was setting the duration as the current milliseconds instead of milliseconds remaining for the next second.
Only the first KeyFrame should have the duration (1000-current millisecond) as the KeyFrame will run for a duration which is equal to the milliseconds left in the current second.
The following KeyFrames will be running at an interval of 1 second.
private void startClock() {
Timeline clock = new Timeline(new KeyFrame(Duration.millis(1000 - Calendar.getInstance().get(Calendar.MILLISECOND)), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
cal = Calendar.getInstance();
second = cal.get(Calendar.SECOND);
minute = cal.get(Calendar.MINUTE);
hour = cal.get(Calendar.HOUR);
am_pm = (cal.get(Calendar.AM_PM) == 0) ? "AM" : "PM";
time.setText(String.format("%02d : %02d : %02d %s", hour, minute, second, am_pm));
if (Timer) {
if (tseconds == 0) {
Timer = false;
//timer.setText("Time Out");
} else {
//timer.setText(tseconds.toString());
tseconds--;
}
}
}
}), new KeyFrame(Duration.seconds(1)));
clock.setCycleCount(Animation.INDEFINITE);
clock.play();
}