Reputation: 85
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 have two type of object B and C who inherit an object of type A.
A has a property a1
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
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