Can't fill Table with items with javafx

2019-09-07 12:09发布

问题:

I'm not so good at javafx and also in English^^. I programmed a TableView but I don't know why it doesn't fill the Table with the Items I created. Perhaps it fills the Table, but I don't see them. I hope somebody could help me here out. Here is the Code:

        private final TableView<VerzeichnisDaten> table = new TableView();

        private final ObservableList<VerzeichnisDaten> data = FXCollections.observableArrayList();

        TableColumn titleCol = new TableColumn("Titel");
        TableColumn lastNameCol = new TableColumn("Nachname");
        TableColumn firstNameCol = new TableColumn("Vorname");
        TableColumn TelCol = new TableColumn("Telefon");
        TableColumn FaxCol = new TableColumn("Fax");
        TableColumn EmailCol = new TableColumn("E-Mail");

// here is a loop which wait for a mouse click on an item            
// item will be saved in abteilung

        try {
        VD.mitarbeiter(abteilung);
        } catch (SQLException ex) {
        /* exception */);
        }

        centerPane.getChildren().clear();
        table.getColumns().clear();
        data.clear();

        for(int j = 0;j < VD.count_mi;j++) {
        data.add(new VerzeichnisDaten(VD.title_speicher[j], VD.lname_speicher[j], VD.fname_speicher[j], VD.tel_speicher[j], VD.fax_speicher[j],VD.email_speicher[j] ));
        }

        titleCol.setMinWidth(100);
        titleCol.setCellValueFactory (new PropertyValueFactory<VerzeichnisDaten, String>("Titel"));
        lastNameCol.setMinWidth(100);
        lastNameCol.setCellValueFactory (new PropertyValueFactory<VerzeichnisDaten, String>("Nachname"));
        firstNameCol.setMinWidth(100);
        firstNameCol.setCellValueFactory (new PropertyValueFactory<VerzeichnisDaten, String>("Vorname"));
        TelCol.setMinWidth(100);
        TelCol.setCellValueFactory (new PropertyValueFactory<VerzeichnisDaten, String>("Telefon"));
        FaxCol.setMinWidth(100);
        FaxCol.setCellValueFactory (new PropertyValueFactory<VerzeichnisDaten, String>("Fax"));
        EmailCol.setMinWidth(100);
        EmailCol.setCellValueFactory (new PropertyValueFactory<VerzeichnisDaten, String>("E-Mail"));

        table.setItems(data);
        table.getColumns().addAll(titleCol,lastNameCol,firstNameCol,TelCol,FaxCol,EmailCol);
        centerPane.getChildren().addAll(table);

    mainPane.setCenter(centerPane);                                                              
    }
    primaryStage.setScene(new Scene(mainPane, 855, 400));
    primaryStage.show();

Here is the Class VerzeichnisDaten:

String[] title_speicher, lname_speicher, fname_speicher, tel_speicher, fax_speicher, email_speicher;


SimpleStringProperty title, lastName, firstName, Tel, Fax, Email;

public VerzeichnisDaten (String title, String lname, String fname, String tel, String fax, String email) {

this.title = new SimpleStringProperty(title);
this.lastName = new SimpleStringProperty(lname);
this.firstName = new SimpleStringProperty(fname);
this.Tel = new SimpleStringProperty(tel);
this.Fax = new SimpleStringProperty(fax);
this.Email = new SimpleStringProperty(email);       
}

// Setter and Getter are now implemented, only not shown

this code belongs to VerzeichnisDaten. above them was more code but is not relevant now.

void mitarbeiter (String Abteilung) throws SQLException {

// more code ...

stmt = conn.createStatement();
rset = stmt.executeQuery(sql_mi_stmt);
i = 0;
while (rset.next()){
      title_speicher[i] = rset.getString("title");
lname_speicher[i] = rset.getString("lname");
      fname_speicher[i] = rset.getString("fname");
      tel_speicher[i] = rset.getString("tel");
      fax_speicher[i] = rset.getString("fax");
      email_speicher[i] = rset.getString("email");

    i = i + 1; 
}
stmt.close();    
}

回答1:

The string that you supply to the PropertyValueFactory, e.g. as here:

new PropertyValueFactory<VerzeichnisDaten, String>("Titel")

must match the variable name of the property in your data class.

That is, if you have:

class Person {
     StringProperty firstNameProperty;  // note: must end in "Property", per convention
     StringProperty lastNameProperty;
}

the respective property value factories would be:

new PropertyValueFactory<Person, String>("firstName")  // property name sans "Property" postfix
new PropertyValueFactory<Person, String>("lastName")

In your code, you 1) have property names that do not end with "Property", i.e. you have:

SimpleStringProperty title, lastName, firstName, Tel, Fax, Email;

and 2) you have used the names of the columns headers instead of the property names in your property value factories.

And thus you have discovered the joys of string-based, or type-unsafe in general, programming: the compiler is happy, but nothing works.

The PropertyValueFactory supplied with JavaFX is at best a hack, and more generally a bad practice. If you look at its Javadoc, you see exactly what it does: it provides a simpler way of creating a value factory instead of having to deal with the ugly Callback SAM, by using reflection and special naming conventions (the latter to which you were victim) to find the right property value.

With Java 8's lambda syntax you can write those value factories in a much simpler way and I would disadvice the usage of PropertyValueFactory.