I'm trying to create a clock which monitors the runtime of a program through using a dynamic UI label which changes every second. I've tried using the following code but keep getting a null pointer exception. This exception stems from the "clock" label which seems to be null on the JavaFX application thread, despite having declared it within the controller class. I also implemented Platform.runlater to make sure that the label updates would be running on the JavaFX thread as that is where the label has been declared, however, it is still throwing this exception. Any pointers as to why this is happening?
Controller:
package GUI;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.Timer;
import java.util.TimerTask;
public class Controller implements Initializable {
int secondspassed = 0;
int minutespassed = 0;
int hourspassed = 0;
@FXML
private Label XPTrackerlabel;
@FXML
private ProgressBar XPTracker;
@FXML
private ComboBox Minelocation;
@FXML
private Label clock;
Timer timer = new Timer();
TimerTask ticktime = new TimerTask(){
public void run(){
secondspassed++;
if (secondspassed == 60){ secondspassed = 0; minutespassed++;}
else if (minutespassed == 60){ minutespassed = 0; hourspassed++;}
Platform.runLater(() -> clock.setText(hourspassed + ":" + minutespassed + ":" + secondspassed));
}
};
public void start() {
timer.scheduleAtFixedRate(ticktime, 1000, 1000);
}
public void PressButton(ActionEvent event){
Controller startclock = new Controller();
startclock.start();
System.out.println("Hello World");
}
@Override
public void initialize(URL url, ResourceBundle rb) {
Minelocation.getItems().addAll("North", "South", "North-East");
XPTracker.setProgress(0.5);
double XP = XPTracker.getProgress() * 100;
XPTrackerlabel.setText(XP + "%");
clock.setText(hourspassed + ":" + minutespassed + ":" + secondspassed);
}
}
FXML File:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane fx:id="UI" alignment="center" hgap="10" minHeight="300.0" minWidth="300.0" vgap="10" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="GUI.Controller">
<columnConstraints>
<ColumnConstraints />
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
</rowConstraints>
<children>
<Button fx:id="start_btn" mnemonicParsing="false" onAction="#PressButton" stylesheets="@Style.css" text="Start" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="7" GridPane.valignment="CENTER" GridPane.vgrow="NEVER" />
<ComboBox fx:id="Minelocation" prefWidth="150.0" promptText="Select Area" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="CENTER" />
<ProgressBar fx:id="XPTracker" prefWidth="200.0" progress="0.0" GridPane.columnIndex="1" GridPane.rowIndex="11" />
<Label fx:id="XPTrackerlabel" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="11" GridPane.valignment="CENTER" />
<Label fx:id="clock" GridPane.columnIndex="1" GridPane.halignment="CENTER" />
</children>
</GridPane>
Error:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at GUI.Controller$1.lambda$run$0(Controller.java:38)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Unknown Source)