Issue
I'm not sure what is wrong with my code. I tried everything, and it doesn't work yet. The error is below:
Caused by: java.lang.NullPointerException: Cannot invoke "javafx.scene.control.TableColumn.setCellValueFactory(javafx.util.Callback)" because "this.InvestorIDColumn" is null at application.PagesController.initialize(PagesController.java:93)
The code is as follows
package application;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;
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.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
public class PagesController implements Initializable {
private static String dbUsername = "root"; // database username
private static String dbPassword = "Ameer12345!"; // database password
private static String URL = "127.0.0.1"; // server location
private static String port = "3306"; // port that mysql uses
private static String dbName = "univ3"; // database on mysql to connect to
private static Connection con;
private Stage stage;
private Scene scene;
private Parent root;
@FXML
private Button myButton;
@FXML
private TextField myTextField1;
@FXML
private TextField myTextField2;
@FXML
private Label myLabel;
int username;
@FXML
TableView<Investor> myInvestorTableView;
@FXML
TableColumn<Investor, String> InvestorNameColumn;
@FXML
TableColumn<Investor, Integer> InvestorIDColumn;
@FXML
TableColumn<Investor, String> InvestorPNumberColumn;
@FXML
TableColumn<Investor, String> InvestorEmailColumn;
public void switchToMainPage(ActionEvent event) throws IOException, ClassNotFoundException, SQLException {
try {
username = Integer.parseInt(myTextField1.getText());
if (username == 112) {
Parent root = FXMLLoader.load(getClass().getResource("MainPage.fxml"));
stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
scene = new Scene(root);
stage.setScene(scene);
stage.show();
} else
myLabel.setText("wrong username or password ");
} catch (Exception e) {
System.out.println("wrong username or password " + e);
}
}
public void switchToLoginPage(ActionEvent event) throws IOException, ClassNotFoundException, SQLException {
Parent root = FXMLLoader.load(getClass().getResource("Login.fxml"));
stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
@Override
public void initialize(java.net.URL arg0, ResourceBundle arg1) {
InvestorIDColumn.setCellValueFactory(new PropertyValueFactory<Investor, Integer>("investor_id"));
InvestorPNumberColumn.setCellValueFactory(new PropertyValueFactory<Investor, String>("investor_PNumber"));
InvestorNameColumn.setCellValueFactory(new PropertyValueFactory<Investor, String>("investor_name"));
InvestorEmailColumn.setCellValueFactory(new PropertyValueFactory<Investor, String>("investor_Email"));
try {
myInvestorTableView.setItems(getInvestor());
} catch (ClassNotFoundException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public ObservableList<Investor> getInvestor() throws ClassNotFoundException, SQLException {
ObservableList<Investor> Investors = FXCollections.observableArrayList();
DBConn a = new DBConn(URL, port, dbName, dbUsername, dbPassword);
con = a.connectDB();
System.out.println("Connection established");
String SQLtxt = "select * from investor";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(SQLtxt);
while (rs.next()) {
int ID = Integer.parseInt(rs.getString(1));
String name = rs.getString(3);
String Pnumber = rs.getString(2);
;
String Email = rs.getString(4);
Investors.add(new Investor(name, ID, Email, Pnumber));
}
rs.close();
stmt.close();
con.close();
System.out.println("Connection closed");
return Investors;
}
}
And here is my class:
package application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
public class Investor {
private SimpleStringProperty investor_name;
private SimpleIntegerProperty investor_id;
private SimpleStringProperty investor_Email;
private SimpleStringProperty investor_PNumber;
public Investor(String investor_name, int investor_id, String investor_Email, String investor_PNumber) {
this.investor_name = new SimpleStringProperty(investor_name);
this.investor_id = new SimpleIntegerProperty(investor_id);
this.investor_Email = new SimpleStringProperty(investor_Email);
this.investor_PNumber = new SimpleStringProperty(investor_PNumber);
}
public SimpleStringProperty getInvestor_name() {
return investor_name;
}
public SimpleIntegerProperty getInvestor_id() {
return investor_id;
}
public SimpleStringProperty getInvestor_Email() {
return investor_Email;
}
public SimpleStringProperty getInvestor_PNumber() {
return investor_PNumber;
}
}
Here is the FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.PagesController">
<children>
<Button layoutX="531.0" layoutY="361.0" mnemonicParsing="false" onAction="#switchToLoginPage" text="log out" textFill="#bf2626" />
<MenuBar prefHeight="28.0" prefWidth="576.0" AnchorPane.bottomAnchor="372.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Delete" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
<TableView fx:id="myInvestorTableView" layoutY="28.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="172.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="28.0">
<columns>
<TableColumn fx:id="InvestorIDColumn" prefWidth="155.0" text="InvestorIDColumn" />
<TableColumn fx:id="InvestorPNumberColumn" prefWidth="145.0" text="InvestorPNumberColumn" />
<TableColumn fx:id="InvestorNameColumn" prefWidth="132.0" text="InvestorNameColumn" />
<TableColumn fx:id="InvestorEmailColumn" prefWidth="158.0" text="InvestorEmailColumn" />
</columns>
</TableView>
</children>
</AnchorPane>
Solution
This is the line which throws your error:
InvestorIDColumn.setCellValueFactory(new PropertyValueFactory<Investor, Integer>("investor_id"));
This data member is declared as
@FXML
TableColumn<Investor, Integer> InvestorIDColumn;
but seemingly it does not have a value (yet) when your initialize
method is being called. To solve this issue you will need to either initialize this data member (if a null
state is invalid), or you can check whether it's null
and only call setCellValueFactory
if it's not null
.
Maybe the investor id column is empty for some records in your XML.
Answered By - Lajos Arpad
Answer Checked By - Clifford M. (JavaFixing Volunteer)