0

I am trying to display data in tableView in javafx.

Even though I have used SimpleStringProperty and SimpleIntegerProperty, every time I click "Check Customers" button, I get this error:

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

This is the code of customer:

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);
}

And here is the controller:

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()));
}

The module-info.java code is:

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

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

I think I should add something in the module-info can anyone please help?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
hassanezz
  • 3
  • 3
  • Why not include `opens application to javafx.graphics, javafx.fxml, javafx.base;` ? Or maybe `export application` though it isn't clear what application is. – matt Aug 12 '21 at 20:49
  • It worked! Thank you so much!!!! – hassanezz Aug 12 '21 at 21:04

1 Answers1

2

Open Your Package to javafx.base

The PropertyValueFactory class uses reflection to get the named property. You have to grant that class's module (javafx.base) the necessary access to your code in order for this reflection to work.

Change:

opens application to javafx.graphics, javafx.fxml;

To:

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

Use a Lambda Expression

The other option is to not use PropertyValueFactory. That class was most likely created because JavaFX was released before lambda expressions were added in Java 8. It made declaring value factories less verbose, but it has two problems:

  1. It uses reflection.
    • Not necessarily bad, but reflection should be avoided if possible.
  2. There's no compile-time safety.
    • If the needed methods don't exist in the model class, or if the methods return the wrong type, then you'll only find out about it at run-time.

Using a lambda expression avoids both those problems. For example:

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

Don't Use Raw Types

Check out the What is a raw type and why shouldn't we use it? Q&A. You're using the raw type of TableView and TableColumn. Don't do that; declare the type arguments.

Slaw
  • 37,820
  • 8
  • 53
  • 80