0

I'm trying to store an Array containing Car objects in a .dat file and then read them and display on a TableView. It works for the most part but one specific Boolean field "isAvailable" from my Car class refuses to show and gives me an error like this:

WARNING: Can not retrieve property 'isAvailable' in PropertyValueFactory: javafx.scene.control.cell.PropertyValueFactory@7e09765f with provided class type: class model.rental.car.Car
java.lang.IllegalStateException: Cannot read from unreadable property isAvailable

My Car class:

public class Car implements Serializable {

    private String plateNo;
    private String model;
    private CarType type;
    private Boolean isAvailable;

    public Car(String plateNo, String model, CarType type, Boolean isAvailable) {
        this.plateNo = plateNo;
        this.model = model;
        this.type = type;
        this.isAvailable = isAvailable;
    }

Initializing values for the TableView:

    public void initialize(URL arg0, ResourceBundle arg1) {
        platNoCol.setCellValueFactory(new PropertyValueFactory<Car, String>("plateNo"));
        modelCol.setCellValueFactory(new PropertyValueFactory<Car, String>("model"));
        typeCol.setCellValueFactory(new PropertyValueFactory<Car, CarType>("type"));
        availabilityCol.setCellValueFactory(new PropertyValueFactory<Car, Boolean>("isAvailable"));
        
        carTableView.setItems(carList);
    }

"carList" above is an ObservableList. I get this by getting a List object from the dat file storing a Car[] Array in this way:

public static List<Car> loadCarDB(String fileName) {
        List<Car> carList = new ArrayList<Car>();
        try {
            ObjectInputStream in = new ObjectInputStream(new FileInputStream("carDB.dat"));
            carList = Arrays.asList((Car[]) in.readObject());
            in.close();
        } catch (FileNotFoundException e) {
            System.out.println("Car database file not found.");
        } catch (EOFException e) {
        } catch (IOException e) {
            System.out.println("Error when processing car database.\n" + e);
        } catch (ClassNotFoundException e) {
            System.out.println("No car data in database.");
        }
        return carList;
    }

And then converting it to an ObservableList like this:

ObservableList<Car> carList = FXCollections.observableArrayList(model.FileProcessing.loadCarDB("../carDB.dat"));

Main reason I've done most of the things in the way I have is because those are the instructions given for this project. What is the right way to display boolean values in a TableView?

Gotem
  • 53
  • 7
  • 1
    Don't you need method `public Boolean getIsAvailable() {return isAvailable}` in class `Car`? – Abra Nov 16 '20 at 12:41
  • 1
    @Abra oh wow that worked. I didn't know that was necessary. I did have a method for returning `isAvailable` but for more readability I named the method also as `isAvailable()`. I've added another method called `getIsAvailable()` now and it works. Thanks! – Gotem Nov 16 '20 at 13:01
  • time to work through a tutorial on how to use TableView ;) BTW: if you have control about the data class api, best is to expose the properties (vs. using PropertyValueFactory which is error-prone due to typos) – kleopatra Nov 16 '20 at 13:18
  • Haha yeah that would be nice, was a struggle trying to find easy to follow guides about this online. Also sadly I don't have control over that so I gotta use PropertyValueFactory but I'll try it if I end up doing some time-pass project using FX :) – Gotem Nov 16 '20 at 15:07

1 Answers1

0

Thanks to @Abra for helping me fix this.

Adding the public Boolean getIsAvailable() {return isAvailable} method in the car class fixed the issue. I had my method returning the isAvailable field also named as isAvailable for simplicity but I didn't know that using a TableView like this looked for a getter method.

Gotem
  • 53
  • 7
  • 1
    Alternatively, try changing the name of method `isAvailable()` to `isIsAvailable()` – Abra Nov 16 '20 at 13:07