I have a JavaFX program that launches a task performed by a separate class. I would like to output the status of that task's progress to a Label
element in the UI. I cannot get this to work. Here is my code:
Main.java:
public class Main extends Application {
public void start(Stage primaryStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("ui.fxml"));
primaryStage.setTitle("Data collector");
primaryStage.setScene(new Scene(root, 400, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller.java:
The label I want to update is created by delcaring globally @FXML public Label label = new Label();
. Creates a new thread via new Thread(new Task<Void>() { ... }).start();
to run the collect_data
method from TaskRun
. The TaskRun
class is stated below:
TaskRun.java:
class TaskRun {
private Controller ui;
TaskRun() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("ui.fxml"));
ui = loader.getController();
}
void collect_data() {
for (int i = 0; i < 100; i++) {
// do stuff...
send_progress_to_ui(((float) i / (float)) * 100);
}
}
void send_progress_to_ui(float percent) {
new Thread(new Task<Void>() {
@Override
protected Void call() throws Exception {
Platform.runLater(() -> ui.label.setText(Float.toString(percent_complete) + "%"));
return null;
}
}).start();
}
}
I get a NullPointerException
on the line with the Platform.runLater(...)
.
So obviously, this method is not going to work. How do I update the UI through this non-controller class TaskRun
?