我正在尝试将类似JavaFX中的财务管理器保存到数据库中。我想从数据库中检索数据,并在按下按钮后将其存储在tableview中。起初没有问题。阶段已更改,并且将填写tableview。当我单击Back按钮并再次更改Incomes阶段时,NullPointerException在MainMenuController中的db.selectIncome()行中出现。我不知道为什么会这样。有人能帮助我吗?
主要课程 包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() {
}
}
数据库
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");
}
}
}
答案 0 :(得分:0)
我想当您单击后退按钮时会执行此代码。
@FXML
public void goToMainMenu() throws IOException {
stageLoader.loadStage(MAIN_MENU_FXML, stage);
MainMenuController mainMenuController = stageLoader.getLoader().getController();
mainMenuController.setStage(stage);
mainMenuController.setStageLoader(stageLoader);
}
以前,您在控制器之间传递数据库对象,但这次没有。
mainMenuController.setDataBase(db);
由于db
尚未初始化,因此尝试db.selectIncome()
会引发NullPointerException
。
作为旁注,您应该尽可能避免创建新的Stage
对象。在您的情况下,切换Scene
或更改其内容就足够了,因为您只需更改窗口的外观 - 您不需要另一个窗口。 Here's其中一种方法。