已成功填充TableView,但在多次查询后发生NPE-JavaFX

时间:2018-07-24 11:17:56

标签: java intellij-idea javafx

我正在使用intellij想法在javafx中填充表格视图。我只有一个表格视图和一个文本字段,每次我键入内容时,它都会运行一段更新表格的代码。它可以工作一段时间,但是在某个时候会生成NullPointerException,该异常会阻止表继续更新。我想捕获此异常,但是它是由不在我的主程序包中的一些代码生成的。问题是:表已成功填充,但是经过多次更新后才生成NPE。

这是我的控制器代码

Controller.java

package MainPackage;

import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;

import java.net.URL;
import java.sql.*;
import java.util.ResourceBundle;


public class Controller implements Initializable
{
    @FXML
    public TextField textField;

    @FXML
    public TableView tableViewPazienti;

    Connection connection;

    // DATA INSIDE THE TABLE
    public ObservableList<Paziente> data;

    TableViewTools tableViewTools;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        SqliteConnection conn = new SqliteConnection();
        connection = conn.connector();

        tableViewTools = new TableViewTools(connection);
        textField.textProperty().addListener(e -> updateP());

        tableViewPazienti.getColumns().addAll(tableViewTools.buildColumns("P"));
        tableViewPazienti.setItems(tableViewTools.buildData("P"));
    }
    private void updateP() {
        tableViewPazienti.getItems().clear();
        tableViewPazienti.getColumns().clear();


        tableViewPazienti.getColumns().addAll(tableViewTools.buildColumns("P"));
        tableViewPazienti.setItems(tableViewTools.buildData("P", textField.getText()));
    }
}

这是我的TableViewTools类,在其中生成数据和列

TableViewTools.java

package MainPackage;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.PropertyValueFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TableViewTools
{
    Connection connection;

    public TableViewTools(Connection connection){
        this.connection = connection;
    }


    // THIS METHOD RETURNS ALL THE COLUMNS OF THE CHOSEN TABLE FROM THE DATABASE
    public ObservableList<TableColumn> buildColumns(String tableName) {

        ObservableList<TableColumn> observableList = FXCollections.observableArrayList();

        String SQL = "select * from " + tableName;
        PreparedStatement preparedStatement = null;
        ResultSet rs = null;
        try {
            preparedStatement = connection.prepareStatement(SQL);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        try {
            rs = preparedStatement.executeQuery();
            // FOR EVERY COLUMNS EXTRACTED FROM THE DATABASE...
            for(int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
                // ...I GET THE COLUMN NAME...
                String columnName = rs.getMetaData().getColumnName(i);
                // ...I CREATE A NEW TABLE COLUMN...
                TableColumn tempColumn = new TableColumn(columnName);
                // ...AND IF THE TABLE NAME EQUALS TO "P"... (in future it can be something different)
                if(tableName.equals("P")){
                    // ...I SET THE CELL VALUE FACTORY TO STORE THE DATA...
                    tempColumn.setCellValueFactory(
                            new PropertyValueFactory<Paziente,String>(columnName)
                    );
                }
                // ...AND FINALLY I ADD THE COLUMN TO THE TABLE.
                observableList.add(tempColumn);
            }
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
        return observableList;
    }


    // THIS METHOD EXTRACTS ALL THE ROWS FROM THE DATABASE AND CREATE A Paziente OBJECT
    // FOR EVERY ROW EXTRACTED
    @SuppressWarnings("Duplicates")
    public ObservableList buildData(String tableName){
        ObservableList data = FXCollections.observableArrayList();

        String SQL = "select * from " + tableName;

        PreparedStatement preparedStatement = null;
        ResultSet rs = null;
        try {
            preparedStatement = connection.prepareStatement(SQL);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        try {
            rs = preparedStatement.executeQuery();
            while(rs.next()) {
                if(tableName == "P"){
                    data.add(new Paziente(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5), rs.getString(6), rs.getString(7), rs.getString(8)));
                }
            }
        }
        catch (SQLException e){
            e.printStackTrace();
        }
        return data;
    }
    // SAME THING AS BEFORE BUT WITH A DIFFERENT QUERY
    @SuppressWarnings("Duplicates")
    public ObservableList buildData(String tableName, String textFieldContent){
        ObservableList data = FXCollections.observableArrayList();

        String[] nameSurname = this.makeNameAndSurname(textFieldContent);
        String SQL = "SELECT * FROM " + tableName +" WHERE Nome LIKE ? AND Cognome LIKE ? OR Nome LIKE ? AND Cognome LIKE ?";

        PreparedStatement preparedStatement = null;
        ResultSet rs = null;
        try {
            preparedStatement = connection.prepareStatement(SQL);
            preparedStatement.setString(1, nameSurname[0]);
            preparedStatement.setString(2, nameSurname[1]);
            preparedStatement.setString(3, nameSurname[1]);
            preparedStatement.setString(4, nameSurname[0]);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        try {
            rs = preparedStatement.executeQuery();
            while(rs.next()) {
                if(tableName == "P"){
                    data.add(new Paziente(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5), rs.getString(6), rs.getString(7), rs.getString(8)));
                }
            }
        }
        catch (SQLException e){
            e.printStackTrace();
        }
        return data;
    }

    // THIS METHOD GET A STRING LIKE "Name Surname", DO STRANGE THINGS TO MAKE IT LIKE "%N%a%m%e% %S%u%r%n%a%m%e%"
    // THEN RETURNS AN ARRAY OF STRING MADE OF String[0] = %N%a%m%e% and String[1] = %S%u%r%n%a%m%e%
    // IT SHOULDN'T BE RELEVANT TO THE RESOLUTION OF THE PROBLEM
    public String[] makeNameAndSurname(String textFieldContent){
        String nome, cognome;
        String textField = textFieldContent;
        textField = textField.trim();
        textField = textField.replaceAll("\\s+", " ");
        String[] nameAndSurname = textField.split("");

        String newTextField = "%";
        for(int i = 0; i < nameAndSurname.length; i++) {
            newTextField += nameAndSurname[i];
            newTextField += "%";
        }

        String arr[] = newTextField.split(" ");
        if(arr.length >= 2){
            nome = arr[0];
            cognome = arr[1];
        }
        else{
            nome = arr[0];
            cognome = "%";
        }
        String[] tmp = new String[2];
        tmp[0] = nome;
        tmp[1] = cognome;
        return tmp;
    }
}

最后,这是我的Paziente课

Paziente.java

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

public class Paziente {
    private StringProperty ID;
    private StringProperty Nome;
    private StringProperty Cognome;
    private StringProperty Eta;
    private StringProperty Indirizzo;
    private StringProperty Referente;
    private StringProperty Telefono;
    private StringProperty DataIngresso;

    public Paziente(String ID, String Nome, String Cognome, String Eta, String Indirizzo, String Referente, String Telefono, String DataIngresso){
        this.ID = new SimpleStringProperty(ID);
        this.Nome = new SimpleStringProperty(Nome);
        this.Cognome = new SimpleStringProperty(Cognome);
        this.Eta = new SimpleStringProperty(Eta);
        this.Indirizzo = new SimpleStringProperty(Indirizzo);
        this.Referente = new SimpleStringProperty(Referente);
        this.Telefono = new SimpleStringProperty(Telefono);
        this.DataIngresso = new SimpleStringProperty(DataIngresso);
    }

    public String getID() {
        return ID.get();
    }

    public StringProperty IDProperty() {
        return ID;
    }

    public void setID(String ID) {
        this.ID.set(ID);
    }

    public String getNome() {
        return Nome.get();
    }

    public StringProperty nomeProperty() {
        return Nome;
    }

    public void setNome(String nome) {
        this.Nome.set(nome);
    }

    public String getCognome() {
        return Cognome.get();
    }

    public StringProperty cognomeProperty() {
        return Cognome;
    }

    public void setCognome(String cognome) {
        this.Cognome.set(cognome);
    }

    public String getEta() {
        return Eta.get();
    }

    public StringProperty etaProperty() {
        return Eta;
    }

    public void setEta(String eta) {
        this.Eta.set(eta);
    }

    public String getIndirizzo() {
        return Indirizzo.get();
    }

    public StringProperty indirizzoProperty() {
        return Indirizzo;
    }

    public void setIndirizzo(String indirizzo) {
        this.Indirizzo.set(indirizzo);
    }

    public String getReferente() {
        return Referente.get();
    }

    public StringProperty referenteProperty() {
        return Referente;
    }

    public void setReferente(String referente) {
        this.Referente.set(referente);
    }

    public String getTelefono() {
        return Telefono.get();
    }

    public StringProperty telefonoProperty() {
        return Telefono;
    }

    public void setTelefono(String telefono) {
        this.Telefono.set(telefono);
    }

    public String getDataIngresso() {
        return DataIngresso.get();
    }

    public StringProperty dataIngressoProperty() {
        return DataIngresso;
    }

    public void setDataIngresso(String dataIngresso) {
        this.DataIngresso.set(dataIngresso);
    }
}

这是我的fxml

MainUI.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="700.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainPackage.Controller">
   <children>
      <MenuBar layoutX="137.0" layoutY="30.0" AnchorPane.bottomAnchor="675.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>
      <TextField fx:id="textField" layoutX="14.0" layoutY="56.0" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="56.0" />
      <TableView fx:id="tableViewPazienti" layoutX="14.0" layoutY="105.0" prefHeight="577.0" prefWidth="1172.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="109.0" />
   </children>
</AnchorPane>

这是完整的堆栈跟踪

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at javafx.controls/javafx.scene.control.skin.TableCellSkin.tableColumnProperty(TableCellSkin.java:97)
at javafx.controls/javafx.scene.control.skin.TableCellSkinBase.getTableColumn(TableCellSkinBase.java:123)
at javafx.controls/javafx.scene.control.skin.TableCellSkinBase.dispose(TableCellSkinBase.java:136)
at javafx.controls/javafx.scene.control.skin.TableCellSkin.dispose(TableCellSkin.java:88)
at javafx.controls/javafx.scene.control.Control$2.invalidated(Control.java:267)
at javafx.base/javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.base/javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147)
at javafx.graphics/javafx.css.StyleableObjectProperty.set(StyleableObjectProperty.java:82)
at javafx.controls/javafx.scene.control.Control$2.set(Control.java:250)
at javafx.controls/javafx.scene.control.Control$2.set(Control.java:233)
at javafx.controls/javafx.scene.control.Control.setSkin(Control.java:230)
at javafx.controls/javafx.scene.control.skin.TableRowSkinBase.recreateCells(TableRowSkinBase.java:715)
at javafx.controls/javafx.scene.control.skin.TableRowSkinBase.updateCells(TableRowSkinBase.java:505)
at javafx.controls/javafx.scene.control.skin.TableRowSkinBase.checkState(TableRowSkinBase.java:649)
at javafx.controls/javafx.scene.control.skin.TableRowSkinBase.computePrefHeight(TableRowSkinBase.java:588)
at javafx.controls/javafx.scene.control.Control.computePrefHeight(Control.java:570)
at javafx.graphics/javafx.scene.Parent.prefHeight(Parent.java:1044)
at javafx.graphics/javafx.scene.layout.Region.prefHeight(Region.java:1561)
at javafx.controls/javafx.scene.control.skin.VirtualFlow.resizeCellSize(VirtualFlow.java:1863)
at javafx.controls/javafx.scene.control.skin.VirtualFlow.addLeadingCells(VirtualFlow.java:1948)
at javafx.controls/javafx.scene.control.skin.VirtualFlow.layoutChildren(VirtualFlow.java:1250)
at javafx.controls/javafx.scene.control.skin.VirtualFlow$5.invalidated(VirtualFlow.java:837)
at javafx.base/javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)
at javafx.base/javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:148)
at javafx.controls/javafx.scene.control.skin.VirtualFlow.setCellCount(VirtualFlow.java:855)
at javafx.controls/javafx.scene.control.skin.TableViewSkinBase.updateItemCount(TableViewSkinBase.java:549)
at javafx.controls/javafx.scene.control.skin.VirtualContainerBase.checkState(VirtualContainerBase.java:170)
at javafx.controls/javafx.scene.control.skin.VirtualContainerBase.layoutChildren(VirtualContainerBase.java:145)
at javafx.controls/javafx.scene.control.skin.TableViewSkinBase.layoutChildren(TableViewSkinBase.java:407)
at javafx.controls/javafx.scene.control.Control.layoutChildren(Control.java:601)
at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1211)
at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1218)
at javafx.graphics/javafx.scene.Scene.doLayoutPass(Scene.java:590)
at javafx.graphics/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2507)
at javafx.graphics/com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:410)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:409)
at javafx.graphics/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:436)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:518)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:498)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:491)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:319)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175)
at java.base/java.lang.Thread.run(Thread.java:844)

0 个答案:

没有答案