Barmaley
Barmaley

Reputation: 16363

Stuck with JavaFX ListView

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

  1. Am I right (I would really pleasured to hear that I'm wrong)
  2. What do to? How to resolve situation and put/place/inflate in List/Table list of totally different objects/classes/entities?

Upvotes: 0

Views: 466

Answers (1)

Przemek Krysztofiak
Przemek Krysztofiak

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

Related Questions