beastlyCoder
beastlyCoder

Reputation: 2401

initialize() method JavaFx NullPointer

I am having some issues as to why the compiler is throwing me a NullPointerException, when I'm trying to display my database information.

Here is my controller where my code contains the initialize() method:

    package main;
    import java.net.URL;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.ResourceBundle;

    import javax.swing.JComponent;
    import javax.swing.JOptionPane;

    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.fxml.FXMLLoader;
    import javafx.fxml.Initializable;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.control.ChoiceBox;
    import javafx.scene.control.RadioButton;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.TextArea;
    import javafx.scene.control.TextField;
    import javafx.scene.control.ToggleGroup;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.stage.Stage;

    public class MainWindowController implements Initializable
    {

        public TextField itemType;
        public TextField itemColor;
        public TextField busNum;
        public TextArea txtArea;

        public static TableView<Details> tableView;
        public static TableColumn<Details, String> itemTypeCol;
        public static TableColumn<Details, String> itemColorCol;    
        public static TableColumn<Details, String> description;

        public static ObservableList<Details> data;

        @Override
        public void initialize(URL location, ResourceBundle resources)
        {
            try
            {
                Connection conn = CreatingDerbyDJB.dbConnection();
                data = FXCollections.observableArrayList();

                ResultSet rs = conn.createStatement().executeQuery("select * from Items");
                while(rs.next())
                {
                    data.add(new Details(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4)));
                }
            }catch(SQLException ex)     
            {
                System.err.println("Error"  + ex);
            }
            itemTypeCol.setCellValueFactory(new PropertyValueFactory<Details, String>("ItemType"));
            itemColorCol.setCellValueFactory(new PropertyValueFactory<Details, String>("ItemColor"));

            description.setCellValueFactory(new PropertyValueFactory<Details, String>("Description"));

            tableView.setItems(data);
        }
}

Here is my details class which contains the details of the database: package main;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

    public class Details 
    {
        private final StringProperty itemType;
        private final StringProperty itemColor;
        private final StringProperty description;
        private final StringProperty busNum;

        public Details(String itemType, String busNum, String itemColor,String description)
        {
            this.itemType = new SimpleStringProperty(itemType);
            this.itemColor = new SimpleStringProperty(itemColor);
            this.busNum = new SimpleStringProperty(busNum);
            this.description = new SimpleStringProperty(description);

        }

        public String getItemType()
        {
            return itemType.get();
        }

        public void setItemType(String paramItemType)
        {
            itemType.set(paramItemType);
        }

        public String getColor()
        {
            return itemColor.get();
        }

        public void setColor(String paramColor)
        {
            itemColor.set(paramColor);
        }


        public String getDescription()
        {
            return description.get();
        }

        public void setDiscription(String paramDescription)
        {
            description.set(paramDescription);
        }

        public String getBus()
        {
            return busNum.get();
        }
        public void setBus(String paramBus)
        {
            busNum.set(paramBus);
        }


    }

I am trying to get every column of the database to display, except for the bus number in my program, but it still needs to be entered by the user.

Upvotes: 0

Views: 2772

Answers (2)

t0mppa
t0mppa

Reputation: 4078

Problem is on these lines on your initialize(...) method:

itemTypeCol.setCellValueFactory(new PropertyValueFactory<Details, String>("ItemType"));
itemColorCol.setCellValueFactory(new PropertyValueFactory<Details, String>("ItemColor"));

description.setCellValueFactory(new PropertyValueFactory<Details, String>("Description"));

tableView.setItems(data);

All these four variables are uninitialized and thus null. You cannot call a setter method on a null object, but need to initialize the objects first. You could just initialize them all with new keyword, but as @jewelsea kindly points out, this is not a very good practice for an FX application.

It's better to use @FXML annotation to inject the dependencies based on FXML configuration. For this, you should also remove the static keywords from the variables.

You should have to have something like the following in your FXML file:

<TableView fx:id="tableView">
  <columns>
    <TableColumn text="ItemType" fx:id="itemTypeCol" />
    <TableColumn text="ItemColor" fx:id="itemColorCol" />
    <TableColumn text="Description" fx:id="description" />
  </columns>
</TableView>

and then you can this do in your controller:

@FXML // fx:id="tableView"
public TableView<Details> tableView;
@FXML // fx:id="itemTypeCol"
public TableColumn<Details, String> itemTypeCol;
@FXML // fx:id="itemColorCol"
public TableColumn<Details, String> itemColorCol;
@FXML // fx:id="description"
public TableColumn<Details, String> description;

This way the JavaFX framework will instantiate all of the above, that you have described in the markup and then inject those components for you into your controller.

Upvotes: 3

jewelsea
jewelsea

Reputation: 159546

There are a bunch of issues with your posted code:

  1. Don't use javax.swing components in JavaFX code.
  2. Don't use static references in FXML controllers
  3. Use @FXML to inject instances of objects with matching fx:ids.
  4. The first letter of the string argument to the PropertyValueFactory should be lower case.

When you post FXML related questions, you should also include the FXML in the question.

There are probably other issues with your implementation as well.

Upvotes: 1

Related Questions