1

My problem is: I want to change something from the .fxml but whatever I do, nothing changes. This is just a simply example.

I went trough the whole internet but none of the solutions worked for me. Here I want to change the text of the label, by calling the corresponding method from the main class.

Calling the same method (here setLabel()) when clicking a Button, with an event handler in the controller class, everything works fine, but a soon as I try to modify something from another class nothing works.

Main class:

package sample; import javafx.application.Application; import javafx.application.Platform; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class Main extends Application { @Override public void start(Stage primaryStage) throws Exception{ Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); primaryStage.setTitle("Hello World"); primaryStage.setScene(new Scene(root, 300, 275)); primaryStage.show(); Controller controller = new Controller(); Platform.runLater(()->controller.setLabel()); } 

FXML Code:

<BorderPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller"> <center> <Label fx:id="label" text="This" BorderPane.alignment="CENTER" /> </center> </BorderPane> 

Controller class: package sample;

import javafx.fxml.FXML; import javafx.scene.control.Label; public class Controller { @FXML private Label label=new Label(); public void setLabel(){ label.setText("Test"); } } 

2 Answers 2

1

There are actually two problems with your code.

1) In the start method of your Application you load sample.fxml using an FXMLLoader, which is correct. But creating a new controller like Controller controller = new Controller(); is incorrect, as you should get the controller from the FXMLLoader itself using getController method, and also you should not use the static load function of FXMLLoader, but you should create an instance of it.

FXMLLoader loader = new FXMLLoader(); Parent root = loader.load(getClass().getResource("sample.fxml")); Controller controller = loader.getController(); 

When you call load on an FXMLLoader it will load the object hierarchy from the FXML file and it will also create a controller (referenced in the FXML file).

2) In Controller you inject the Label from FXML file, but you re-create it. When the FXMLLoader injects a control to your controller based on the fx:id it also ensures initialization. If you create a new Label it will not point to the Label instance created by the loader.

This

@FXML private Label label= new Label(); 

should be replaced with

@FXML private Label label; 
Sign up to request clarification or add additional context in comments.

1 Comment

thank you , this was much more helpful than everything else i found. :)
0

That is pretty simple... You can change the the label text from your Main class either by adding a getter method in your Controller class for the required label and then get it in the Main class using the controller object (loader.getController()) and update its text. Or call the setter method inside the Controller class using controller object in Main. As DVagra said, use loader.getController() to get the controller object. (where loader is the object of FXMLoader).

Moreover you do not need Platform.runLater() to update the gui controls. As you're already running on the FX thread.

Anyway, here is what you need.

Main Class

package sample; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class Main extends Application { @Override public void start(Stage primaryStage) throws Exception{ FXMLLoader loader = new FXMLLoader(); loader.setLocation(Main.class.getResource("sample.fxml")); Parent root = loader.load(); primaryStage.setTitle("Hello World"); primaryStage.setScene(new Scene(root, 300, 275)); primaryStage.show(); Controller controller = loader.getController(); controller.setLabel("Test"); // Or // controller.getLabel().setText("Test"); } public static void main(String[] args) { launch(args); } } 

Controller Class

package sample; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Label; import java.net.URL; import java.util.ResourceBundle; public class Controller implements Initializable{ @FXML Label label; //setter public void setLabel(String labelText){ label.setText(labelText); } //getter for label public Label getLabel() { return label; } @Override public void initialize(URL location, ResourceBundle resources) { } } 

Sample.fxml

<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.Label?> <?import javafx.scene.layout.BorderPane?> <BorderPane xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller"> <center> <Label fx:id="label" text="This" BorderPane.alignment="CENTER" /> </center> </BorderPane> 

3 Comments

in my "real" project , i´m not able to call the setter method. i always gives me a null pointer execption. i seems like the controller is not initialized with ... = loader.getController();
How are you getting the loader object? Kindly post the code snippet.
i called the method a bit too soon, now everything works, thank you once more, i was stuck with this problem for a few days

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.