Can someone please help me make a countdown timer in JavaFX? I need the time to be taken from a label (the time is set by a slider) and I want to see the minutes and seconds remaining every second. The countdown should start when a button is pressed. I searched Stack Overflow and I tried to do it with ChatGPT, but I still have problems with it.
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.*;
public class MainController implements Initializable{
@FXML
private Button button;
@FXML
private Slider slider;
@FXML
private Label timerLabel;
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
//the initial value of the label is set with the slider
slider.valueProperty().addListener((ObservableValue<? extends Number> num, Number oldVal, Number newVal) -> {
Integer value = Integer.valueOf(String.format("%.0f", newVal));
timeLabel.setText(String.valueOf(value));
});
}
//the action of the button
@FXML
private void start(){
//i tried another way and still does not work
timer = seconds;
Timer timerA = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
if(timer >0){
timeLabel.setText(String.valueOf(timer));
timer--;
}
if(timer == -1){
timeLabel.setText(String.valueOf(timer));
timerA.cancel();
}
}
};
timerA.schedule(task,0,1000);
}
}
The message “timeline might not be initialized” means that you are trying to use
timelinebefore it has been constructed. You are callingtimeline.stop()inside an event handler which is being passed to the Timeline constructor; since the constructor hasn’t completed yet, the compiler cannot guaranteetimelinehas actually had a value assigned to it when your event handler runs. In other words,timelinemight be initialized.One way to address this is to add the KeyFrame separately. That way, the Timeline constructor has completely finished:
Another way would be to declare
timelineas a private field, rather than as a local variable. This works because, once the enclosing class has finished its own constructor, every field is guaranteed to be initialized. (If your code never assigned a value to a field, that field would automatically be initialized to null.)