模块 javafx.base 无法访问 class application.customer(在模块 FCR 中),因为模块 FCR 未打开 javafx.base 的应用程序

module javafx.base cannot access class application.customer (in module FCR) because module FCR does not open application to javafx.base

我正在尝试在 javafx 的 tableView 中显示数据。

尽管我使用了 SimpleStringProperty 和 SimpleIntegerProperty,但每次单击“检查客户”按钮时,我都会收到此错误:

Caused by: java.lang.IllegalAccessException: module javafx.base cannot access class application.customer (in module FCR) because module FCR does not open application to javafx.base

at javafx.base/com.sun.javafx.property.MethodHelper.invoke(MethodHelper.java:69)
at javafx.base/com.sun.javafx.property.PropertyReference.getProperty(PropertyReference.java:197)
... 98 more

这是客户的代码:

public class customer {

private final IntegerProperty ID;
private final StringProperty  firstName;
private final StringProperty  lastName;
private final StringProperty  carPlate;
private final IntegerProperty telephoneNum;

public customer(int ID,String firstName, String lastName, String carPlate, int telephoneNum) {
    this.ID = new SimpleIntegerProperty();
    this.firstName = new SimpleStringProperty();
    this.lastName = new SimpleStringProperty();
    this.carPlate = new SimpleStringProperty();
    this.telephoneNum = new SimpleIntegerProperty();

    setID(ID);
    setfirstName(firstName);
    setlastName(lastName);
    setcarPlate(carPlate);
    settelephoneNum(telephoneNum);
}

public final StringProperty firstNameProperty() {
    return firstName;
}

public final String getfirstName() {
    return firstName.get();
}

public final void setfirstName(String fname) {
    firstName.set(fname);
}

public final IntegerProperty IDProperty() {
    return ID;
}

public final int getID() {
    return ID.get();
}

public final void setID(int iD) {
    ID.set(iD);
}

public final StringProperty lastNameProperty() {
    return lastName;
}

public final String getlastName() {
    return lastName.get();
}

public final void setlastName(String lname) {
    lastName.set(getfirstName());;
}

public final IntegerProperty telephoneNumProperty() {
    return telephoneNum;
}

public final int gettelephoneNum() {
    return telephoneNum.get();
}

public final void settelephoneNum(int tnum) {
    telephoneNum.set(tnum);;
}

public final StringProperty carPlateProperty() {
    return carPlate;
}

public final String getcarPlate() {
    return carPlate.get();
}

public final void setcarPlate(String platenum) {
    carPlate.set(platenum);
}

这是控制器:

public class checkCustomers {

private customersData q = Main.q;

@FXML
private TableView table;


@FXML
private TableColumn firstName;
@FXML
private TableColumn lastName;
@FXML
private TableColumn carPlate;
@FXML
private TableColumn telephoneNumber;


@FXML
public void initialize() {
    
System.out.println(1);

firstName.setCellValueFactory(new PropertyValueFactory<customer, String>("firstName"));
lastName.setCellValueFactory(new PropertyValueFactory<customer, String>("lastName"));
carPlate.setCellValueFactory(new PropertyValueFactory<customer, String>("carPlate"));
telephoneNumber.setCellValueFactory(new PropertyValueFactory<customer, Integer>("telephoneNumber"));
table.setItems(FXCollections.observableArrayList(q.getAllCustomers()));
}

模块-info.java代码为:

module FCR {
    requires javafx.controls;
    requires javafx.fxml;
    requires java.sql;
    requires javafx.base;

    opens application to javafx.graphics, javafx.fxml;
}

我想我应该在模块信息中添加一些东西有人可以帮忙吗?

打开你的包裹javafx.base

PropertyValueFactoryclass使用反射获取命名属性。您必须授予 class 的模块 (javafx.base) 对您的代码的必要访问权,以便此反射起作用。

变化:

opens application to javafx.graphics, javafx.fxml;

收件人:

opens application to javafx.graphics, javafx.fxml, javafx.base;

使用 Lambda 表达式

另一种选择是不使用 PropertyValueFactory。 class 很可能是因为 JavaFX 在 Java 8 中添加 lambda 表达式之前发布的。它使声明值工厂不那么冗长,但它有两个问题:

  1. 它使用反射。
    • 不一定不好,但尽量避免反射。
  2. 没有编译时安全。
    • 如果模型 class 中不存在所需的方法,或者方法 return 类型错误,那么您只能在 运行 中找到相关信息-时间。

使用 lambda 表达式可以避免这两个问题。例如:

lastNameCol.setCellValueFactory(data -> data.getValue().lastNameProperty());

不要使用原始类型

查看 What is a raw type and why shouldn't we use it? 问答。您正在使用 TableViewTableColumn 的原始类型。不要那样做;声明类型参数。