-1

I'm creating an application for a cookbook and I'm trying to display recipes from a database into a ListView. When I call setItems() on the ListView I get a Null Pointer Exception. I'm not super familiar with JavaFX so I can't figure out how to prevent it here. I made sure that the ListView has an fx:id , my fxml files specify the controller, and I tried some other things that fixed other people's problems with this. My guess is that the problem has to do with the fact that I'm loading the FXML from MainMenu_Controller and then trying to add the items to the ListView from the ViewRecipes_Controller but I have not been able to figure it out.

Main Class:

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("/Cookbook_MainMenu.fxml"));
            Scene scene = new Scene(root);
            scene.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());
            primaryStage.setTitle("Cookbook");
            primaryStage.setScene(scene);
            primaryStage.show();
            DatabaseConnection db = new DatabaseConnection();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

MainMenu_Controller:

public class MainMenu_Controller {

    //controls when user clicks view recipes
    @FXML
    protected void viewRecipesBtnClick(ActionEvent event){
        try {
            Parent root = FXMLLoader.load(getClass().getResource("/Cookbook_ViewRecipes.fxml"));
            Scene scene = new Scene(root);
            scene.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());
            Stage primaryStage = new Stage();
            primaryStage.setTitle("View Recipes");
            primaryStage.setScene(scene);
            primaryStage.show();
            //close previous window
            ((Node)(event.getSource())).getScene().getWindow().hide();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    //controls when user clicks add recipe
    @FXML
    protected void addRecipeBtnClick(ActionEvent event){
        try {
            Parent root = FXMLLoader.load(getClass().getResource("/Cookbook_MainMenu.fxml"));
            Scene scene = new Scene(root);
            scene.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());
            Stage primaryStage = new Stage();
            primaryStage.setTitle("Add Recipe");
            primaryStage.setScene(scene);
            primaryStage.show();
            //close previous window
            ((Node)(event.getSource())).getScene().getWindow().hide();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

ViewRecipes_Controller:

public class ViewRecipes_Controller {

    @FXML
    private ListView recipeListView;

    public ViewRecipes_Controller() {
        DatabaseConnection db = new DatabaseConnection();
        ObservableList<String> names = FXCollections.observableArrayList();
        names = db.getRecipeName();
        recipeListView.setItems(names);     //error occurs here
    }

    //controls when user clicks back to menu
    @FXML
    protected void backToMenuBtnClick(ActionEvent event){
        try {
            Parent root = FXMLLoader.load(getClass().getResource("/Cookbook_MainMenu.fxml"));
            Scene scene = new Scene(root);
            scene.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());
            Stage primaryStage = new Stage();
            primaryStage.setTitle("Cookbook");
            primaryStage.setScene(scene);
            primaryStage.show();
            //close previous window
            ((Node)(event.getSource())).getScene().getWindow().hide();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

Cookbook_MainMenu.fxml:

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="261.0" prefWidth="600.0" stylesheets="@application/styles.css" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainMenu_Controller">
   <children>
      <Label layoutX="173.0" layoutY="20.0" styleClass="titleLbl" text="Cookbook">
         <font>
            <Font name="Ink Free" size="68.0" />
         </font>
      </Label>
      <Button fx:id="viewRecipeBtn" layoutX="136.0" layoutY="188.0" mnemonicParsing="false" onAction="#viewRecipesBtnClick" styleClass="btnDefault" text="View Recipes">
         <font>
            <Font name="ELEGANCE" size="12.0" />
         </font>
      </Button>
      <Button fx:id="addRecipeBtn" layoutX="380.0" layoutY="188.0" mnemonicParsing="false" onAction="#addRecipeBtnClick" styleClass="btnDefault" text="Add Recipe" />
   </children>
</AnchorPane>

Cookbook_ViewRecipes.fxml:

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="416.0" prefWidth="301.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.ViewRecipes_Controller">
   <children>
      <Label layoutX="54.0" styleClass="titleLbl" text="Recipes">
         <font>
            <Font name="Ink Free" size="62.0" />
         </font>
      </Label>
      <Button fx:id="backToMenuBtn" layoutX="51.0" layoutY="355.0" mnemonicParsing="false" onAction="#backToMenuBtnClick" styleClass="btnDefault" text="Back to Menu" />
      <ListView fx:id="recipeListView" layoutX="51.0" layoutY="116.0" prefHeight="200.0" prefWidth="200.0" styleClass="recipeList" />
      <Button fx:id="getDetailsBtn" layoutX="177.0" layoutY="355.0" mnemonicParsing="false" styleClass="btnDefault" text="Get Details" />
   </children>
</AnchorPane>
Aaron
  • 3
  • 1
  • Call recipeListView.setItems(names); at initialize() method. Better refer to https://stackoverflow.com/questions/34785417/javafx-fxml-controller-constructor-vs-initialize-method – Miller Cy Chan May 28 '19 at 02:03

1 Answers1

-1

Best solution I can give you without having more insight into what's going on here is to make sure recipeListView is not null before proceeding to access the object:

public ViewRecipes_Controller() {
    DatabaseConnection db = new DatabaseConnection();
    ObservableList<String> names = FXCollections.observableArrayList();
    names = db.getRecipeName();
    if (recipeListView != null) {
        recipeListView.setItems(names);     //error occurs here
    }
    else {
        System.out.println("Unable to set items, recipeListView is null")
    }   
}

If you would like to find out why the object is null then you should run a debugging session with breakpoints and analyze your code flow.

Matthew
  • 1,905
  • 3
  • 19
  • 26