Rakim
Rakim

Reputation: 1107

null pointer on javaFX element

I have the following code and when trying to set the text of the textArea of my fxml I get a null pointer exception. The window appears as it should but the controller is unable to identify the elements within it.

declaration:

public TextArea txtArea;

This is the controller method body:

Stage stage = new Stage();
FXMLLoader loader = new FXMLLoader();
AnchorPane page = loader.load(getClass().getResource("demo.fxml"));
loader.setController(this);
Scene scene = new Scene(page);
stage.setScene(scene);
stage.initOwner(primaryStage);
stage.initModality(Modality.WINDOW_MODAL);
stage.show();

txtArea.setText("something"); //this is where it crashes -> null pointer

FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane xmlns:fx="http://javafx.com/fxml/1" id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity"
            minHeight="-Infinity" minWidth="-Infinity" prefHeight="160.0" prefWidth="353.0"
            xmlns="http://javafx.com/javafx/2.2">
<children>
    <BorderPane prefHeight="-1.0" prefWidth="-1.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
        <center>
            <TextArea fx:id="txtArea" editable="false" focusTraversable="false" prefWidth="200.0" wrapText="true" />
        </center>
    </BorderPane>
</children>
</AnchorPane>

Upvotes: 0

Views: 1851

Answers (2)

James_D
James_D

Reputation: 209684

You have two errors in your code. First, you are calling

loader.setController(this);

after you call

loader.load();

This means there is no controller set on the FXMLLoader when it loads the FXML file, so it cannot initialize the controller fields. Switch the order of the calls.

Secondly, you are using the static FXMLLoader.load(URL) method. Since this is a static method, it won't know anything about the state of the FXMLLoader you created, including the controller. You need to set the location, and use the instance method FXMLLoader.load() with no parameters.

FXMLLoader loader = new FXMLLoader(getClass().getResource("demo.fxml"));
loader.setController(this);
AnchorPane page = loader.load();
Scene scene = new Scene(page);

I also strongly recommend making all fields private, not public. Annotate the fields with @FXML to allow injection:

@FXML
private TextArea txtArea ;

Upvotes: 1

Rakim
Rakim

Reputation: 1107

I am not sure why it worked but someone might be able to explain why. I just initialised the FXMLLoader with the .fxml file instead of creating a loader and passing in the load method the resource. I.e.

FXMLLoader loader = new FXMLLoader(getClass().getResource("demo.fxml"));
loader.setController(this);
AnchorPane page = loader.load();
Scene scene = new Scene(page);

Upvotes: 0

Related Questions