为了账号安全,请及时绑定邮箱和手机立即绑定

PropertyValueFactory 模型类中正确的 getter 错误

PropertyValueFactory 模型类中正确的 getter 错误

BIG阳 2023-02-23 10:26:27
我试图从 fxml 文件填充示例 javafx TableView。这是我的控制器方法:public class TestController implements Initializable {       @FXML private TableView<user> tableView;        @FXML private TableColumn<user, String> UserId;        @FXML private TableColumn<user, String> UserName;        public void initialize(URL location, ResourceBundle resources) {            UserId.setCellValueFactory(new PropertyValueFactory<user, String>("userId"));            UserName.setCellValueFactory(new PropertyValueFactory<user, String>("userName"));            tableView.getItems().setAll(parseUserList());        }        private List<user> parseUserList(){            List<user> l_u = new ArrayList<user>();            user u = new user();            u.setUserId(1);            u.setUserName("test1");            l_u.add(u);            u.setUserId(2);            u.setUserName("test2");            l_u.add(u);            u.setUserId(3);            u.setUserName("test3");            l_u.add(u);            return l_u;        }}和 fxml 文件:<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="369.0" prefWidth="505.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="viewmodel.TestController ">   <center>      <TableView fx:id="tableView" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">        <columns>          <TableColumn prefWidth="75.0" text="UserId" fx:id="UserId"/>          <TableColumn prefWidth="75.0" text="UserName" fx:id="UserName"/>        </columns>      </TableView>   </center></BorderPane>最后是我的模型:封装模型;public class user {    private int userId;    public int getUserId() { return this.userId; }    public void setUserId(int userId) { this.userId = userId; }    private String userName;    public String getUserName() { return this.userName; }    public void setUserName(String userName) { this.userName = userName; }}
查看完整描述

2 回答

?
收到一只叮咚

TA贡献1821条经验 获得超5个赞

虽然违反 Java 命名约定(始终遵循它们!)和 PropertyValueFactory 的不当使用(如果没有令人信服的理由,请不要使用它!)是常见的嫌疑人,但它们似乎不是 OP 问题中的原因。


错误消息表明问题发生在模块化上下文中:


Jun 28, 2019 12:17:35 PM javafx.scene.control.cell.PropertyValueFactory getCellDataReflectively

WARNING: Can not retrieve property 'userId' in PropertyValueFactory:   

    javafx.scene.control.cell.PropertyValueFactory@638db851 with provided class type: class model.user

java.lang.RuntimeException: java.lang.IllegalAccessException: 

    module javafx.base cannot access class model.user (in module JavaFXTest) 

    because module JavaFXTest does not open model to javafx.base

实际上,该示例在非模块化上下文中运行得很好,但在模块化时会失败。错误消息准确地告诉我们该怎么做:打开我们的模块(或其中的一部分)进行反射访问。


Module-info 打开完整的模块或单独的包:


 // complete

 open module JavaFXTest {

   exports ourpackage;

   ...

 }


 // parts

 module JavaFXTest {

   exports ourpackage;

   opens ourpackage.model;

 }


查看完整回答
反对 回复 2023-02-23
?
炎炎设计

TA贡献1808条经验 获得超4个赞

这是一个很好的例子来说明“为什么你应该使用Callback而不是PropertyValueFactory.”。目前我看不出有任何理由使用 PVF 而不是 Callback。


在这里您可以看到一个缺点,即您在运行该应用程序之前并没有真正看到您犯了编码错误。由于 PVF 使用反射,如果您没有正确声明它们,它就找不到合适的字段。PVF 期望Property-es 正如您在异常中看到的那样 a是必需的,并且您的班级PropertyRefference中指定的字段都不是esuserProperty


它可以这样使用,但你必须user像这样重写类:


public class User { // use java naming conventions 

    private IntegerProperty userId;


    public int getUserId() { return this.userId.get(); }

    public void setUserId(int userId) { this.userId.set(userId); }

    public IntegerProperty userIdProperty() { return this.userId; }


    private StringProperty userName;


    public String getUserName() { return this.userName.get(); }

    public void setUserName(String userName) { this.userName.set(userName); }

    public StringProperty userNameProperty() {return this.userName; }


    public User(int userId,String userName){

         this.userId = new SimpleIntegerProperty(userId);

         this.userName = new SimpleStringProperty(userName);

    }

}

现在,由于字段是属性,PropertyValueFactory 会找到它们,但我不建议使用它,因为如您所见,它可能会导致您在运行它之前甚至没有注意到的问题。


所以不是:


UserId.setCellValueFactory(new PropertyValueFactory<user, String>("userId"));

UserName.setCellValueFactory(new PropertyValueFactory<user, String>("userName"));

使用:


// use java naming conventions (`userId` instead of `UserId`)

userId.setCellValueFactory(data -> data.getValue().userIdProperty().asString()); 

// same here user naming convention

userName.setCellValueFactory(data -> data.getValue().userNameProperty());

我已经写过几次评论,但我会在这里再次提到它使用java 命名约定。像 User 而不是 user 和 userId 而不是 UserId 等等......


查看完整回答
反对 回复 2023-02-23
  • 2 回答
  • 0 关注
  • 201 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号