Reputation: 16363
I'm trying to rewrite my Android based app into JavaFX and stuck with one problem.
Brief explanation of problem looks like following:
1) I have hierarchy of classes with root abstract class Field
and number of child classes like FieldCat
, FieldZebra
, FieldDog
and so on - each of these classes has its own unique enough structure and visual representation (in form of FXML's)
2) There's ListView
which should show list of objects which belongs to Field
hierarchy - stored in ObservableList<Field> listItems
3) And now I need to inflate each of my FieldWhatever
objects as separate row in ListView
Statement
I can't do it with JavaFX ListView
control(?!)
Proof
The only way to create ListView
element is to supply CellFactory
:
public class FieldsListCellFactory<T extends Field> implements Callback<ListView<T>, ListCell<T>> {
@Override
public ListCell<T> call(ListView<T> listView) {
//blah-blah
}
}
Factory receives single parameter ListView
itself, so it can generate the same ListCell
for all elements of ListView
- in other words I can't populate different UI elements depending on underlying FieldWhatever
object.
For the very beginning I couldn't even believe to it - how it's possible? In Android I could inflate any kind of complexity UI's depending on object type/hierarchy and so on, but in JavaFX - impossible? Believe me - I spent hours trying to fix it - useless.
Questions
Upvotes: 0
Views: 466
Reputation: 924
Ad 1 You are wrong.
Ad 2 Here's the code:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
public class ListViewApp extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
ListView<Animal> listview = new ListView<>(FXCollections.observableArrayList(new Dog(1, "John"), new Cat(2, "Fluffy")));
listview.setCellFactory(param -> new ListCell<Animal>() {
@Override
protected void updateItem(Animal animal, boolean empty) {
super.updateItem(animal, empty);
if (animal != null) {
setText(animal.getText());
}
}
});
stage.setScene(new Scene(listview));
stage.show();
}
}
class Animal {
protected final int id;
public Animal(int id) {
this.id = id;
}
protected String getText() {
return "";
}
}
class Dog extends Animal {
private final String owner;
public Dog(int id, String owner) {
super(id);
this.owner = owner;
}
@Override
protected String getText() {
return "DOG id=" + id + ", owner=" + owner;
}
}
class Cat extends Animal {
private final String name;
public Cat(int id, String name) {
super(id);
this.name = name;
}
@Override
protected String getText() {
return "CAT id=" + id + ", name=" + name;
}
}
Upvotes: 2