I am trying to make something like finance organiser in JavaFX save into database. I would like to retrieve data from database and store it in tableview after pressing button Incomes. At first there is no problem. Stage is changed and tableview will be filled. When I clicked Back button and again Incomes stage has been changed, NullPointerException has ocured in line db.selectIncome() in MainMenuController. I have no idea why it happens. Can anybody help me?
Main class package app;
import java.io.IOException;
import controller.MainMenuController;
import data.DataBase;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import utils.SQLConnection;
import utils.StageLoader;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(this.getClass().getResource("/fxml/MainMenu.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
MainMenuController mainMenuController = loader.getController();
mainMenuController.setStage(primaryStage);
SQLConnection.dataBaseConnection();
DataBase db = new DataBase();
StageLoader stageLoader = new StageLoader();
mainMenuController.setDataBase(db);
mainMenuController.setStageLoader(stageLoader);
}
public static void main(String[] args) {
launch(args);
}
}
MainMenuController
package controller;
import java.io.IOException;
import data.DataBase;
import javafx.fxml.FXML;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import utils.StageLoader;
public class MainMenuController {
public static final String INCOME_MENU_FXML = "/fxml/IncomeMenu.fxml";
private Stage stage;
private StageLoader stageLoader;
private DataBase db;
public void setStage(Stage stage) {
this.stage = stage;
}
public void setStageLoader(StageLoader stageLoader) {
this.stageLoader = stageLoader;
}
public void setDataBase(DataBase db) {
this.db = db;
}
@FXML
public void goToIncomeMenu() throws IOException {
stageLoader = new StageLoader();
stageLoader.loadStage(INCOME_MENU_FXML, stage);
IncomeMenuController incomeMenuController = stageLoader.getLoader().getController();
incomeMenuController.setStage(stage);
db.selectIncome();
incomeMenuController.getIncomeAmountColumn().setCellValueFactory(new PropertyValueFactory<>("amount"));;
incomeMenuController.getIncomeCategoryColumn().setCellValueFactory(new PropertyValueFactory<>("category"));
incomeMenuController.getIncomeDateColumn().setCellValueFactory(new PropertyValueFactory<>("stringDate"));
incomeMenuController.getIncomeTable().setItems(db.getBudget());
incomeMenuController.setStageLoader(stageLoader);
incomeMenuController.setDataBase(db);
}
@FXML
public void exitApplication() {
System.exit(0);
}
@FXML
public void initialize() {
}
}
IncomeMenuController
package controller;
import java.io.IOException;
import data.Budget;
import data.DataBase;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import utils.StageLoader;
public class IncomeMenuController {
public static final String ADD_INCOME_MENU_FXML = "/fxml/AddIncomeMenu.fxml";
public static final String MAIN_MENU_FXML = "/fxml/MainMenu.fxml";
private Stage stage;
private StageLoader stageLoader;
private Stage addIncomeStage;
private DataBase db;
public void setStageLoader(StageLoader stageLoader) {
this.stageLoader = stageLoader;
}
public void setStage(Stage stage) {
this.stage = stage;
}
public void setDataBase(DataBase db) {
this.db = db;
}
public TableView<Budget> getIncomeTable() {
return incomeTable;
}
public TableColumn<Budget, Double> getIncomeAmountColumn() {
return incomeAmountColumn;
}
public TableColumn<Budget, String> getIncomeCategoryColumn() {
return incomeCategoryColumn;
}
public TableColumn<Budget, String> getIncomeDateColumn() {
return incomeDateColumn;
}
@FXML
TableView<Budget> incomeTable;
@FXML
TableColumn<Budget, Double> incomeAmountColumn;
@FXML
TableColumn<Budget, String> incomeCategoryColumn;
@FXML
TableColumn<Budget, String> incomeDateColumn;
@FXML
public void goToAddIncomeMenu() throws IOException {
addIncomeStage = new Stage();
stageLoader.loadStage(ADD_INCOME_MENU_FXML, addIncomeStage);
AddIncomeMenuController addIncomeMenuController = stageLoader.getLoader().getController();
addIncomeMenuController.setStage(addIncomeStage);
addIncomeMenuController.setDataBase(db);
}
@FXML
public void goToMainMenu() throws IOException {
stageLoader.loadStage(MAIN_MENU_FXML, stage);
MainMenuController mainMenuController = stageLoader.getLoader().getController();
mainMenuController.setStage(stage);
mainMenuController.setStageLoader(stageLoader);
}
@FXML
public void load() {
}
@FXML
public void initialize() {
}
}
DataBase
package data;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TextField;
import utils.SQLConnection;
public class DataBase {
private String query;
private PreparedStatement prepStmt;
private ResultSet result;
private DateTimeFormatter formatter;
private DateTimeFormatter tableColumnFormatter;
private Income income;
private ObservableList<Budget> budget;
public ObservableList<Budget> getBudget() {
return budget;
}
public DataBase() {
formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
tableColumnFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
income = new Income();
budget = FXCollections.observableArrayList();
System.out.println("utworzono obiekt bazy danych");
}
public void addIncome(TextField amountField, TextField categoryField, DatePicker dateField) {
try {
query = "INSERT INTO Incomes(ID, Amount, Category, Date) VALUES (NULL, ?, ?, ?);";
prepStmt = SQLConnection.getConnection().prepareStatement(query);
prepStmt.setDouble(1, Double.parseDouble(amountField.getText()));
prepStmt.setString(2, categoryField.getText());
prepStmt.setString(3, dateField.getValue().format(formatter));
prepStmt.execute();
prepStmt.close();
} catch (SQLException e) {
System.err.println("Błąd podczas dodawania do bazy danych");
e.printStackTrace();
}
}
public void selectIncome() {
budget.clear();
try {
query = "SELECT * FROM Incomes;";
prepStmt = SQLConnection.getConnection().prepareStatement(query);
result = prepStmt.executeQuery();
while(result.next()) {
income.setAmount(result.getDouble("amount"));
income.setCategory(result.getString("category"));
income.setStringDate(result.getString("date"));
income.setDate(LocalDate.parse(income.getStringDate()));
income.setStringDate(income.getDate().format(tableColumnFormatter));
budget.add(new Income(income.getAmount(), income.getCategory(), income.getStringDate()));
}
for(Budget i: budget) {
System.out.println(i);
}
prepStmt.close();
result.close();
} catch (SQLException e) {
System.err.println("Błąd podczas pobierania danych z bazy");
}
}
}