Question

I have the main application class that does the following just fine:

   @Override
   public void start(Stage primaryStage) {
      try {
         FXMLLoader loader = new FXMLLoader(getClass().getResource(
               "RecordScreen.fxml"));
         Parent root = (Parent) loader.load();
         Scene newScene = new Scene(root);
         Stage newStage = new Stage();
         newStage.setScene(newScene);
         newStage.show();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

It launches a table view that displays people. I select a person, hit the edit button, and try to launch a window that will let me edit them.

   @FXML
   public void editPerson() {
      try {
         FXMLLoader loader = new FXMLLoader(getClass().getResource(
               "PersonEditor.fxml"));
         PersonEditorCtrl ctrl = loader.getController();
         ctrl.init(table.getSelectionModel().getSelectedItem());
         Parent root = (Parent) loader.load();
         Scene newScene = new Scene(root);
         Stage newStage = new Stage();
         newStage.setScene(newScene);
         newStage.show();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

The problem is, getController is returning null. I have been following this pattern for the past 2 weeks with no problems whatsoever. What am I doing wrong now? These untraceable bugs are aggravating!!!

Here are my two fxmls:

The screen with tableview:

<AnchorPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="application.RecordsCtrl">
  <!-- TODO Add Nodes -->
  <children>
    <VBox id="VBox" alignment="CENTER" spacing="0.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
      <children>
        <TableView fx:id="table" prefHeight="-1.0" prefWidth="-1.0">
          <columns>
            <TableColumn prefWidth="75.0" text="Name" fx:id="nameCol" />
            <TableColumn prefWidth="75.0" text="Age" fx:id="ageCol" />
          </columns>
        </TableView>
        <Button mnemonicParsing="false" onAction="#editPerson" text="Edit" />
      </children>
    </VBox>
  </children>
</AnchorPane>

The person editor:

<AnchorPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="application.PersonEditorCtrl">
  <!-- TODO Add Nodes -->
  <children>
    <VBox layoutX="0.0" layoutY="0.0" prefHeight="-1.0" prefWidth="-1.0">
      <children>
        <TextField fx:id="nameField" prefWidth="200.0" />
        <TextField fx:id="ageField" prefWidth="200.0" />
        <Button mnemonicParsing="false" text="Button" />
      </children>
    </VBox>
  </children>
</AnchorPane>
Was it helpful?

Solution

Change this

@FXML
   public void editPerson() {
      try {
         FXMLLoader loader = new FXMLLoader(getClass().getResource(
               "PersonEditor.fxml"));
         PersonEditorCtrl ctrl = loader.getController();
         ctrl.init(table.getSelectionModel().getSelectedItem());
         Parent root = (Parent) loader.load();
         Scene newScene = new Scene(root);
         Stage newStage = new Stage();
         newStage.setScene(newScene);
         newStage.show();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

To that:

@FXML
   public void editPerson() {
      try {
         FXMLLoader loader = new FXMLLoader(getClass().getResource(
               "PersonEditor.fxml"));
         Parent root = (Parent) loader.load();
         PersonEditorCtrl ctrl = loader.getController();
         ctrl.init(table.getSelectionModel().getSelectedItem());

         Scene newScene = new Scene(root);
         Stage newStage = new Stage();
         newStage.setScene(newScene);
         newStage.show();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

You first have to run loader.load() then you can get the Controller.

Patrick

OTHER TIPS

In your scene builder, you need to make sure that you have explicitly stated the fx:controller attribute.

To do this:

  1. Open your desired FXML file in Scenebuilder.
  2. Click on the controller drop down.
  3. Select the controller class.

If you do not specify the fx:controller it will return null.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top