JavaFX Properties in TableView
Asked Answered
H

3

31

I am teaching myself how to work with JavaFX properties within the TableView and am having trouble with some property types. I have an object Person that contains two properties

public class Person {

    private final StringProperty firstName;
    private final IntegerProperty age;

    public Person(String firstName, Integer age) {
        this.firstName = new SimpleStringProperty(firstName);
        this.age = new SimpleIntegerProperty(age);
    }


    public Integer getAge() {
        return age.get();
    }

    public void setAge(Integer age) {
        this.age.set(age);
    }

    public IntegerProperty ageProperty() {
        return age;
    }

    public String getFirstName() {
        return firstName.get();
    }

    public void setFirstName(String firstName) {
        this.firstName.set(firstName);
    }

    public StringProperty firstNameProperty() {
        return firstName;
    }

}

Once created by goal is to use this object in a TableView. I've created the two table columns like this.

TableColumn<Person, String> firstNameColumn = new TableColumn<Person, String>("First Name");
TableColumn<Person, Integer> ageColumn = new TableColumn<Person, Integer>("Age");

I then want to set the cell value factory using Lambda expressions. This is where the problem arises. The StringProperty firstName works just fine. However, the IntegerProperty gives me the error message "Type mismatch: cannot convert from IntegerProperty to ObservableValue<Integer>"

firstNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());
ageColumn.setCellValueFactory(cellData -> cellData.getValue().ageProperty());

Can anyone shed some light on what is going wrong with the ageColumn.setCellValueFactory(...)? Any help would be greatly appreciated.

Thanks!

Heavily answered 22/7, 2014 at 14:7 Comment(0)
M
70

One somewhat strange part of the property API is that IntegerProperty implements ObservableValue<Number>, not ObservableValue<Integer>. So, somewhat counterintuitively, you need

TableColumn<Person, Number> ageColumn = new TableColumn<Person, Number>("Age");

As an aside, and I'm not sure if this causes problems, but it's more usual to use int instead of Integer for the return type for the get method and the parameter type for the set method in your model class. These match the types for IntegerProperty.get() and IntegerProperty.set(...), so it just avoids some implicit auto (un)boxing.

Mcelroy answered 22/7, 2014 at 14:41 Comment(0)
T
9

you can use .asObject Method to make your code work
it doesn't need you to change the TableColumn Paramater to Number

ageColumn.setCellValueFactory(cellData -> cellData.getValue().ageProperty().asObject());

idk which one is better code,
change the parameter to Number or use asObject Method

related Link

Toplevel answered 21/11, 2014 at 13:58 Comment(1)
maybe if you return it as an Object it will print the toString method, and take the value as a string, I think that is the default behaviourEponymous
C
3

For String type :

firstNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());

When you want to use IntegerProperty or DoubleProperty, the setCellValueFactory(...) must have an additional asObject():

ageColumn.setCellValueFactory(cellData -> cellData.getValue().ageProperty().asObject());

This is necessary because of a bad design decision of JavaFX.

Source and credits

Christiniachristis answered 30/10, 2016 at 7:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.