JavaFX,SQL,在更改阶段

时间:2017-01-22 22:48:56

标签: java sql javafx nullpointerexception

我正在尝试将类似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");
        }

    }
}

1 个答案:

答案 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其中一种方法。