当前位置: 首页 > 知识库问答 >
问题:

从模型类正确getter上的工厂错误

任昊阳
2023-03-14

Im试图从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; }
}

现在,当我尝试填充它给我这个错误:

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
    at javafx.base/com.sun.javafx.property.PropertyReference.get(PropertyReference.java:176)

关于SO的一些文章提到,getter和setter属性必须在get word之后以大写字母开头,但这并没有解决问题。

共有2个答案

祝灼光
2023-03-14

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

这里你可以看到一个缺点,那就是你没有真正看到你在运行应用程序之前犯了一个编码错误。因为PVF使用反射,如果你没有正确声明它们,它就找不到合适的字段。PVF期望属性-es,正如你在异常中看到的那样,需要一个属性引用,并且你的user类中没有一个字段被删除

可以这样使用,但必须重写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);
    }
}

现在,由于字段是属性,所以属性值工厂会找到它们,但是我不建议使用它,因为正如你所看到的,它会导致你在运行它之前甚至没有注意到的问题。

因此,与其说:

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命名约定。比如用户而不是用户和用户ID而不是用户ID等等...

龙俊良
2023-03-14

虽然违反java命名约定(遵循它们,永远!)和不恰当地使用财产价值工厂(如果没有令人信服的理由,不要使用它!)是通常的怀疑,但它们似乎不是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

实际上,该示例在非模块化环境中运行良好,但在模块化时失败。错误消息告诉我们该做什么:打开模块(或部分模块)进行反射访问。

模块信息打开完整模块或单个软件包:

 // complete
 open module JavaFXTest {
   exports ourpackage;
   ...
 }

 // parts
 module JavaFXTest {
   exports ourpackage;
   opens ourpackage.model;
 }
 类似资料:
  • 我正试图通过api创建一个新任务。 电话是: Curl-umy_token:https://app.asana.com/api/1.0/tasks-d"name=demo_task"-d"workspace=875236917006" 以下是回应: {“错误”:[{“消息”:“工作区:类型不正确”}]} 我哪里错了?

  • Intellij告诉我的参数类型不正确。我不熟悉这个错误和。 这个错误还表明: 检查参数@PathParam、@QueryParam等的类型。带批注的参数、字段或属性的类型必须是 > 成为主要类型 有一个接受单个字符串参数的构造函数 具有一个名为 valueOf 或 formString 的静态方法,该方法接受单个 String 参数(例如,请参阅 Integer.valueOf(String))

  • 我的Laravel 5.2应用程序具有以下结构: 用户:id名称。。。 文章: id标题正文user_id(fk) 注释:id主体用户id(fk)发布id(fk) 我想创建几个用户(20个),为每个用户创建随机数量的帖子,并为每个帖子创建随机数量的评论(即使是固定数量也可以)。 我可以创建用户并为每个帖子分配帖子,但我不能为每个帖子分配评论:我有: 我发现了一些东西,但不起作用: 注意:我在模型之

  • 问题内容: 在我的spring项目中,我的Dao类具有以下模板: 我的每个Dao类都具有以下结构: 这意味着当我调用方法findById,findByField,findAll时,我应该从Usuario,Usuario和List类型接收对象。 这两个拳头类的返回正确值,但最后一个不返回。当我运行此方法时(从我的服务类中): 我应该看到“ usuario”时收到“对象”作为响应。有人可以告诉我我在做

  • 问题内容: 我希望返回具有适当泛型的用户界面实例。我陷入下面的错误示例中: 绑定不匹配:BallUserInterfaceFactory类型的通用方法getBaseballUserInterface(BASEBALL)不适用于参数(BALL)。推断的类型BALL不能有效替代有界参数 我了解它不能保证BALL是棒球,因此getBaseballUserInterface方法调用上存在参数类型不匹配的情

  • 如何在模型工厂中定义外键。例如,如果我有一个Organizations表,其中包含国家/地区表的外键,那么在我的模型工厂中,我必须为国家/地区id定义一个虚拟值,如下所示: 在我的Organizations table seeder类中,我正在执行以下操作,但faker对象不存在-我是否需要在我的seeder类中创建一个新的faker对象? 数据库播种器类 定义模型工厂时定义外键的最佳方法是什么?