JavaFXTableView没有显示数据,getter setter有问题吗?

JavaFXTableView没有显示数据,getter setter有问题吗?,java,javafx,arraylist,tableview,getter-setter,Java,Javafx,Arraylist,Tableview,Getter Setter,我正在尝试将数据填充到我的tableview中,一切看起来都很好,但它仍然没有显示数据。 这是代码。一切似乎都很好,但tableview没有显示任何内容。连眨眼都不眨 public class MainPage implements Initializable { @FXML private AnchorPane root; @FXML private Button main_LogOut;

我正在尝试将数据填充到我的tableview中,一切看起来都很好,但它仍然没有显示数据。 这是代码。一切似乎都很好,但tableview没有显示任何内容。连眨眼都不眨



public class MainPage implements Initializable {
    
    
    

    @FXML
    private AnchorPane root;
    
      @FXML
        private Button main_LogOut;

        @FXML
        private ComboBox<?> main_Clients;

        @FXML
        private ComboBox<?> main_Users;

        @FXML
        private TableView<customerDetails> table;

        @FXML
        private TableColumn<customerDetails, String> clientId;
        

        @FXML
        private TableColumn<customerDetails, String> clientName;

        @FXML
        private TableColumn<customerDetails, String> clientEmail;

        @FXML
        private TableColumn<customerDetails, String> clientRequirement;

    
    @SuppressWarnings("unchecked")
    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
        // TODO Auto-generated method stub
        clientId.setCellValueFactory(new PropertyValueFactory<customerDetails,String> ("Id"));
        clientName.setCellValueFactory(new PropertyValueFactory<customerDetails, String>("name"));
        clientEmail.setCellValueFactory(new PropertyValueFactory<customerDetails, String>("email"));
        clientRequirement.setCellValueFactory(new PropertyValueFactory<customerDetails, String>("Requirements"));
        table=new TableView<customerDetails>();
        table.setItems(getClients());
        table.getColumns().addAll(clientId,clientName,clientEmail,clientRequirement);
            
        
    }
    
    @FXML
    void loadScene(ActionEvent event) throws IOException
    {
        AnchorPane pane=FXMLLoader.load(getClass().getResource("/lists/MainPage.fxml"));
        root.getChildren().setAll(pane);
        
    }
    
    public ObservableList<customerDetails> getClients() 
    {
        
        ObservableList<customerDetails> cd=FXCollections.observableArrayList();
        customerDetails details=new customerDetails("moin123","moeen","789987","asdf","email","developer","abcd","adsadasdf","78987");
        cd.add(details);
        return cd;
        
        
    }

知道这里出了什么问题吗?

不要使用PropertyValueFactory

正如你所看到的,它依赖于反射。这意味着您必须非常小心地指定正确的字符串,因为编译器无法为您验证它

一个更好的方法是避免反射,这样编译器就可以验证您是否拼写正确

看一看。请注意,对于每个get方法,都有一个相应的方法返回JavaFX属性本身?这是JavaFX中大多数类中的一种模式

例如,有
getBlendMode()
blendModeProperty()
方法
getClip()
clipProperty()
方法
getLayoutX()
LayoutProperty()
方法

您的数据类需要遵循相同的约定:

private final StringProperty idProperty = new SimpleStringProperty();
private final StringProperty nameProperty = new SimpleStringProperty();

public String getId() {
    return idProperty.get();
}

public void setId(String id) {
    idProperty.set(id);
}

public StringProperty idProperty() {
    return idProperty;
}

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

public void setName(String name) {
    nameProperty.set(name);
}

public StringProperty nameProperty() {
    return nameProperty;
}

// etc.
为什么要这样做?因为现在可以将属性直接传递给每列的setCellValueFactory方法:

clientId.setCellValueFactory(f -> f.getValue().idProperty());
clientName.setCellValueFactory(f -> f.getValue().nameProperty());
// etc.
请注意,上面的代码中没有
字符。由于使用了实际的方法,编译器可以确保您没有犯任何错误。(避免反射还有其他好处,如性能)

然而…正如塞德里克指出的,这意味着您的类将无法真正序列化。尝试将其写入ObjectOutputStream将导致NotSerializableException,因为JavaFX属性本身不可序列化。我不清楚您是否真的打算序列化customerDetails实例;如果是这样,还需要做更多的工作才能做到这一点


至于你原来的代码出了什么问题

在代码中创建新的TableView 加载MainPage.fxml时,
table
字段将被更改,以使其指向在该.fxml文件中定义的TableView。这就是您在窗口中看到的TableView

但您的代码会执行以下操作:

table=new TableView<customerDetails>();
table=newtableview();
通过这样做,您创建了一个在窗口中根本不可见的不同的TableView。您正在设置一个从来没有人看到的TableView项目

解决方案:完全删除上面的代码行

不正确的属性名称 传递给PropertyValueFactory的字符串必须是bean属性名。Java bean也称为POJO或普通旧Java对象

Java bean规范将bean属性定义为get方法。bean的名称定义为get方法的名称,没有
get
前缀,和下一个小写字母。

由于customerDetails类有一个
getId
方法,因此相应的bean属性的名称是
id
。请注意,一旦删除了“get”,则首字母是小写的。这一点至关重要。bean属性区分大小写

当您的代码执行新属性ValueFactory(“Id”)时,您正在传递一个不存在的属性。customerDetails类没有名为“Id”的属性,因此值工厂不可能返回任何数据。但是,该类有名为“Id”的属性。大小写重要:“Id”正确,“Id”不正确


编译器编译代码,但不执行它。因此编译器不知道字符串与customerDetails中任何bean属性的名称不匹配。这就是为什么反射是危险的。使用编译器可以验证的代码更安全、更健壮。

您需要遵循命名约定。这可能会解决问题你的问题。我不确定它是否会,但这正是代码跳出的地方。另外:不要实例化注入的字段实例化字段?准确地实例化,针对拼写错误。如果你不理解该注释,请阅读java语言基础教程和如何使用FXMLOP的教程。OP肯定会遇到不同的问题使用您的想法。
公共类customerDetails实现可序列化
。该小写字母不起作用。我使用了您所说的正确命名方法,但仍然没有结果…..很好的解释:)这里问题的一部分,不过-另一部分是OP填充的表不是scenegraph中的表。@kleopatra Ah yes,这当然是一个基本问题。答案已更新。正如Sedrick正确指出的那样,也已更新以解决序列化问题。感谢编辑,完美:)
table=new TableView<customerDetails>();