Search code examples
javasqlsqlitejavafxjavafx-8

Javafx SQLite Tableview not Populating even though printing data


Using Apache Netbeans IDE 11.3.Currently can not populate tableview even though i can print datas.

I am building a Operator GUI thing.Currently trying to populate tableview with Operator datas but can not do it.

Controller Class :

public class OperatorenController implements Initializable {

    DatabaseController db = new DatabaseController();
    private ObservableList<Operatoren> OperatorenList;

    @FXML
    private TableView<Operatoren> Operatorentable = new TableView<>();
    @FXML
    private TableColumn<Operatoren, Integer> id = new TableColumn<>();
    @FXML
    private TableColumn<Operatoren, String> name = new TableColumn<>();
    @FXML
    private TableColumn<Operatoren, String> nachname = new TableColumn<>();
    @FXML
    private TableColumn<Operatoren, String> firmname = new TableColumn<>();


    @FXML
    private void handleDisplayTables(ActionEvent event) throws NullPointerException {
        try {Connection conn = db.ConnectDB();
            String dbliste = "SELECT * FROM [operatoren]";
            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery(dbliste);
            OperatorenList = FXCollections.observableArrayList();

            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String nachname = rs.getString("nachname");
                String firmname = rs.getString("firmname");
                OperatorenList.add(new Operatoren(id, name, nachname,firmname));
                System.out.println(id + " " + name+" " + nachname+" " + firmname+" ");


            }
        } catch (Exception e) {
            System.out.println(e);
        }

        id.setCellValueFactory(new PropertyValueFactory<>("id"));
        name.setCellValueFactory(new PropertyValueFactory<>("name"));
        nachname.setCellValueFactory(new PropertyValueFactory<>("nachname"));
        firmname.setCellValueFactory(new PropertyValueFactory<>("firmname"));

        name.setCellValueFactory(cellData -> { return (new SimpleStringProperty(((Operatoren)cellData.getValue()).getName()));});
        nachname.setCellValueFactory(cellData -> { return (new SimpleStringProperty(((Operatoren)cellData.getValue()).getNachname()));});
        firmname.setCellValueFactory(cellData -> { return (new SimpleStringProperty(((Operatoren)cellData.getValue()).getFirmname()));});
        id.setCellValueFactory(cellData -> { return (new SimpleIntegerProperty(((Operatoren)cellData.getValue()).getId())).asObject();});

        Operatorentable.setItems(OperatorenList);
        Operatorentable.getColumns().addAll(id,name,nachname,firmname);
        Operatorentable.refresh();

    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {

     }
}

I can print data from Database so i don't think database is the problem here.

Operator java class

public class Operatoren {
    public SimpleStringProperty name,nachname,firmname;
    public SimpleIntegerProperty id;

public Operatoren(int id,String name,String nachname,String firmname){
    this.id = new SimpleIntegerProperty(id);
    this.name = new SimpleStringProperty(name);
    this.nachname = new SimpleStringProperty(nachname);
    this.firmname = new SimpleStringProperty(firmname);

}
    public static void main(String[] args) {

    }

    public String getName() {
        return name.get();
    }

    public SimpleStringProperty getNameProperty() {
        return name;
    }

    public String getNachname() {
        return nachname.get();
    }

    public SimpleStringProperty getNachnameProperty() {
        return nachname;
    }

    public String getFirmname() {
        return firmname.get();
    }

    public SimpleStringProperty getFirmnameProperty() {
        return firmname;
    }

    public int getId() {
        return id.get();
    }

    public SimpleIntegerProperty getIdProperty() {
        return id;
    }
}

Lastly here is FXML,I am using SceneBuilder :FXML IMAGE


<AnchorPane id="AnchorPane" prefHeight="600.0" prefWidth="800.0" style="-fx-background-color: #313455;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="inf202.OperatorenController">
   <children>
      <Button layoutX="140.0" layoutY="235.0" mnemonicParsing="false" onAction="#personEkle" prefHeight="25.0" prefWidth="109.0" style="-fx-background-color: #f5f5f5;" text="Person ekle" />
      <Button layoutX="136.0" layoutY="354.0" mnemonicParsing="false" onAction="#personSil" prefHeight="25.0" prefWidth="109.0" style="-fx-background-color: #f5f5f5;" text="person sil" />
      <Button layoutX="136.0" layoutY="443.0" mnemonicParsing="false" onAction="#personList" prefHeight="25.0" prefWidth="109.0" style="-fx-background-color: #f5f5f5;" text="person listele" />
      <Button layoutX="136.0" layoutY="400.0" mnemonicParsing="false" onAction="#handleDisplayTables" prefHeight="25.0" prefWidth="109.0" style="-fx-background-color: #f5f5f5;" text="Person duzenle" />
      <Text fill="#948f8f" layoutX="122.0" layoutY="87.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Go Back">
         <font>
            <Font name="System Bold" size="18.0" />
         </font>
      </Text>
      <Line endX="84.0" endY="11.0" layoutX="25.0" layoutY="57.0" startX="68.0" startY="23.0" stroke="#948f8f" strokeWidth="2.0" />
      <Line endX="-85.0" endY="12.0" fill="#868686" layoutX="195.0" layoutY="81.0" startX="-103.4141845703125" startY="0.414215087890625" stroke="#948f8f" strokeWidth="2.0" />
      <Button layoutX="86.0" layoutY="68.0" mnemonicParsing="false" onAction="#Operatoren" opacity="0.0" prefHeight="25.0" prefWidth="109.0" text="Button" />
      <TextField layoutX="121.0" layoutY="126.0" />
      <TextField layoutX="121.0" layoutY="165.0" />
      <TextField layoutX="121.0" layoutY="200.0" />
      <Text fill="#948f8f" layoutX="61.0" layoutY="145.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Name">
         <font>
            <Font name="System Bold" size="18.0" />
         </font>
      </Text>
      <Text fill="#948f8f" layoutX="20.0" layoutY="184.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Nachname">
         <font>
            <Font name="System Bold" size="18.0" />
         </font>
      </Text>
      <Text fill="#948f8f" layoutX="21.0" layoutY="220.0" strokeType="OUTSIDE" strokeWidth="0.0" text="FirmName">
         <font>
            <Font name="System Bold" size="18.0" />
         </font>
      </Text>
      <TextField layoutX="121.0" layoutY="316.0" />
      <Text fill="#948f8f" layoutX="77.0" layoutY="335.0" strokeType="OUTSIDE" strokeWidth="0.0" text="ID">
         <font>
            <Font name="System Bold" size="18.0" />
         </font>
      </Text>
      <Line endX="22.0" endY="249.0" layoutX="350.0" layoutY="49.0" startX="-323.0" startY="249.0" />
      <Line endX="-100.5" endY="231.5" layoutX="473.0" layoutY="67.0" startX="-100.5" startY="-50.0" />
      <Line endX="-102.25" endY="-188.79290771484375" layoutX="475.0" layoutY="488.0" startX="-102.25" startY="99.0" />
      <TextArea layoutX="28.0" layoutY="507.0" prefHeight="69.0" prefWidth="325.0" />
      <Text fill="#948f8f" layoutX="152.0" layoutY="494.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Ergebnis" wrappingWidth="77.1845703125">
         <font>
            <Font name="System Bold" size="18.0" />
         </font>
      </Text>
      <TableView layoutX="389.0" layoutY="35.0" prefHeight="543.0" prefWidth="379.0">
         <columns>
            <TableColumn prefWidth="75.0" text="ID" />
            <TableColumn prefWidth="75.0" text="Name" />
            <TableColumn prefWidth="75.0" text="Nachname" />
            <TableColumn prefWidth="75.0" text="Firmname" />
         </columns>
      </TableView>
   </children>
</AnchorPane>


Solution

  • Never initialize fields that are annotated @FXML.

    The reason you get null pointer exceptions if you remove the initialization in the controller is because you forgot to put fx:ids on the elements in the FXML file.

    The TableView to which you are passing the data is the one defined in the controller, not the one defined in the FXML file (and displayed in the scene). Similarly, the TableColumns on which you are setting the cell value factories are the ones you created in the controller, not the ones you defined in the FXML file. Consequently, the table columns defined in the FXML file have no cell value factories, and therefore no way to display any data.

    So replace

    @FXML
    private TableView<Operatoren> Operatorentable = new TableView<>();
    @FXML
    private TableColumn<Operatoren, Integer> id = new TableColumn<>();
    @FXML
    private TableColumn<Operatoren, String> name = new TableColumn<>();
    @FXML
    private TableColumn<Operatoren, String> nachname = new TableColumn<>();
    @FXML
    private TableColumn<Operatoren, String> firmname = new TableColumn<>();
    

    with

    @FXML
    private TableView<Operatoren> Operatorentable ;
    @FXML
    private TableColumn<Operatoren, Integer> id ;
    @FXML
    private TableColumn<Operatoren, String> name ;
    @FXML
    private TableColumn<Operatoren, String> nachname ;
    @FXML
    private TableColumn<Operatoren, String> firmname ;
    

    and in the FXML file add the fx:id attributes:

      <TableView fx:id="Operatorentable" layoutX="389.0" layoutY="35.0" prefHeight="543.0" prefWidth="379.0">
         <columns>
            <TableColumn fx:id="id" prefWidth="75.0" text="ID" />
            <TableColumn fx:id="name" prefWidth="75.0" text="Name" />
            <TableColumn fx:id="nachname" prefWidth="75.0" text="Nachname" />
            <TableColumn fx:id="firmname" prefWidth="75.0" text="Firmname" />
         </columns>
      </TableView>
    

    Note that your method naming in the model class is non-standard: for a property prop, the get method should be getProp(), set method should be setProp(), and the property accessor method should be propProperty(), not getPropProperty(). This can make things not work correctly if you use the PropertyValueFactory class (which I don't actually recommend).

    public class Operatoren {
        public SimpleStringProperty name,nachname,firmname;
        public SimpleIntegerProperty id;
    
    public Operatoren(int id,String name,String nachname,String firmname){
        this.id = new SimpleIntegerProperty(id);
        this.name = new SimpleStringProperty(name);
        this.nachname = new SimpleStringProperty(nachname);
        this.firmname = new SimpleStringProperty(firmname);
    
    }
        public static void main(String[] args) {
    
        }
    
        public String getName() {
            return name.get();
        }
    
        public SimpleStringProperty nameProperty() {
            return name;
        }
    
        public String getNachname() {
            return nachname.get();
        }
    
        public SimpleStringProperty nachnameProperty() {
            return nachname;
        }
    
        public String getFirmname() {
            return firmname.get();
        }
    
        public SimpleStringProperty firmnameProperty() {
            return firmname;
        }
    
        public int getId() {
            return id.get();
        }
    
        public SimpleIntegerProperty idProperty() {
            return id;
        }
    }
    

    There's also no point in setting the cell value factories, and replacing them immediately with essentially equivalent ones, and you should do this in the initialization, not in an event handler. And finally, since you have JavaFX properties defined in your model class, there's no need to create new properties for the cell factories, just reference the existing ones:

    @FXML
    private void handleDisplayTables(ActionEvent event) throws NullPointerException {
        try {Connection conn = db.ConnectDB();
            String dbliste = "SELECT * FROM [operatoren]";
            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery(dbliste);
            OperatorenList = FXCollections.observableArrayList();
    
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String nachname = rs.getString("nachname");
                String firmname = rs.getString("firmname");
                OperatorenList.add(new Operatoren(id, name, nachname,firmname));
                System.out.println(id + " " + name+" " + nachname+" " + firmname+" ");
    
    
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    
    
        Operatorentable.setItems(OperatorenList);
    
    }
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        name.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
        nachname.setCellValueFactory(cellData -> cellData.getValue().nachnameProperty());
        firmname.setCellValueFactory(cellData -> cellData.getValue().firmnameProperty());
        id.setCellValueFactory(cellData -> cellData.getValue().idProperty().asObject());
    
    
     }