0

I'm writing some code where I interact (Change text) with FXML elements from the start method. However, I find that when I call the method from my controller class I get a NullPointerException. I've found that the issue has something to do with threads, but I have been able to get anything to work. I have included some sample code that generates the same problem.

Main class:

public class Main extends Application {
    Controller C = new Controller();

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        Scene scene = new Scene(root, 300, 275);
        stage.setTitle("FXML Welcome");
        stage.setScene(scene);
        stage.show();
        C.handleSubmitButtonAction();//Error happens here.
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Controller class:

public class Controller{
    @FXML public Text actiontarget;

    @FXML protected void handleSubmitButtonAction() {
        actiontarget.setText("Sign in button pressed");
    }
}

FXML code:

<GridPane fx:id="GridPane" fx:controller="sample.Controller" xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
    <children>
        <Text text="Welcome" GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.columnSpan="2"/>
        <Label text="User Name:" GridPane.columnIndex="0" GridPane.rowIndex="1"/>
        <TextField GridPane.columnIndex="1" GridPane.rowIndex="1"/>
        <Label text="Password:" GridPane.columnIndex="0" GridPane.rowIndex="2"/>
        <PasswordField fx:id="passwordField" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
        <HBox spacing="10" alignment="bottom_right" GridPane.columnIndex="1" GridPane.rowIndex="4">
            <Button text="Sign In" onAction="#handleSubmitButtonAction"/>
        </HBox>
        <Text fx:id="actiontarget" GridPane.columnIndex="1" GridPane.rowIndex="6"/>
    </children>
</GridPane>

1 Answer 1

2

The FXMLLoader creates a instance of the controller itself, if you specify the controller class using the fx:controller attribute in the fxml.

To get access to that instance, you need to create a FXMLLoader instance and use getController() after loading the fxml. Otherwise the controller instance where the values are injected is different to the one you create yourself and store in the C field:

FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"))
Parent root = loader.load();
C = loader.getController();
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.