Meriemi
Meriemi

Reputation: 85

How to display objects inherited in JavaFX TableView

Hy all !

I looking for days on how to display in a Tableview attribute objects that inherit from a parent object.

Let me explain :

I want to show a1, b1 c1 in a TableView, and i have a list of objects which can be of type A, B or C.

Currently I declare my tableView like this:

TableView<A> table;

ListProperty<A> list = new SimpleListProperty<>();

TableColumn<A, a1> column_a1 = new TableColumn<A, a1>("a1 property");
column_a1.setCellValueFactory(new PropertyValueFactory<A, a1>("a1"));

TableColumn<B, b1> column_b1 = new TableColumn<B, b1>("b1 property");
column_b1.setCellValueFactory(new PropertyValueFactory<B, a1>("b1"));

TableColumn<C, c1> column_c1 = new TableColumn<C, c1>("c1 property");
column_c1.setCellValueFactory(new PropertyValueFactory<C, c1>("c1"));

table.getColumns().add((TableColumn<A, a1>) column_a1);
table.getColumns().add((TableColumn<B, b1>) column_b1);
table.getColumns().add((TableColumn<C, c1>) column_c1);

table.setItems((ObservableList<A>) list);

In this configuration, for each row of the table just one column must be non-empty .

But I get an error when adding columns to the table.

I stated my table: TableView table But apparently I can not add columns B and C as these types inherit A.

My question is : How to view object attributes inheriting the declared type for the table in JavaFX ?

I of course thought to declare my tableView as: TableView table, but this does not satisfy me.

Is there another way ?

EDIT : Solution in comment work but i have another problem. In my case, the property of B and C class have the same name. So when i set the PropertyValueFactory i write :

TableView<A> table;

TableColumn<A, a1> column_a1 = new TableColumn<A, a1>("a1 property");
column_a1.setCellValueFactory(new PropertyValueFactory<A, a1>("a1"));

TableColumn<B, b1> column_b1 = new TableColumn<A, b1>("b1 property");
column_b1.setCellValueFactory(new PropertyValueFactory<A, b1>("sameNameOfProperty"));

TableColumn<C, c1> column_c1 = new TableColumn<A, c1>("c1 property");
column_c1.setCellValueFactory(new PropertyValueFactory<A, c1>("sameNameOfProperty"));

table.getColumns().add((TableColumn<A, a1>) column_a1);
table.getColumns().add((TableColumn<A, b1>) column_b1);
table.getColumns().add((TableColumn<A, c1>) column_c1);

table.setItems((ObservableList<A>) list)

Due to this same name of property if i declare all columns and properties with the type parameter A, when i add a B or C object in TableView, the two column b1 and c1 are set for each row of B or C object.

Upvotes: 2

Views: 1906

Answers (1)

Meriemi
Meriemi

Reputation: 85

I found the answer with an implementation of a ObservableValue for both b1 and c1 attributes. This gives something like this:

TableView<A> table;

TableColumn<A, a1> column_a1 = new TableColumn<A, a1>("a1 property");
column_a1.setCellValueFactory(new PropertyValueFactory<A, a1>("a1"));

TableColumn<A, b1> column_b1 = new TableColumn<A, b1>("b1 property");

column_b1.setCellValueFactory(new Callback<CellDataFeatures<A, b1>, ObservableValue<b1>>() {
    public ObservableValue<b1> call(CellDataFeatures<A, b1> p) {
        if(p.getValue() instanceof B){
            return new ObservableValue<B.b1>() {
                @Override
                public void removeListener(InvalidationListener arg0) {}
                @Override
                public void addListener(InvalidationListener arg0) {}
                @Override
                public void removeListener(ChangeListener<? super b1> listener) {}

                @Override
                public b1 getValue() {
                    return ((B)p.getValue()).getSameNameOfProperty();
                }

                @Override
                public void addListener(ChangeListener<? super b1> listener) {}
                };
            }
        return null;
        }
    });

TableColumn<A, c1> column_c1 = new TableColumn<A, c1>("c1 property");

column_c1.setCellValueFactory(new Callback<CellDataFeatures<A, c1>, ObservableValue<c1>>() {
    public ObservableValue<c1> call(CellDataFeatures<A, c1> p) {
        if(p.getValue() instanceof C){
            return new ObservableValue<C.c1>() {
                @Override
                public void removeListener(InvalidationListener arg0) {}
                @Override
                public void addListener(InvalidationListener arg0) {}
                @Override
                public void removeListener(ChangeListener<? super c1> listener) {}

                @Override
                public c1 getValue() {
                    return ((C)p.getValue()).getSameNameOfProperty();
                }

                @Override
                public void addListener(ChangeListener<? super c1> listener) {}
            };
        }
        return null;
        }
   });
table.getColumns().add((TableColumn<A, a1>) column_a1);
table.getColumns().add((TableColumn<A, b1>) column_b1);
table.getColumns().add((TableColumn<A, c1>) column_c1);

table.setItems((ObservableList<A>) list);

Thus, the addition of a type of object a, b ​​or c only filled the corresponding column. It remains for me to check the entry of information by the type but that's another story.

Thank you for your answers !

Upvotes: 2

Related Questions