Customizing JavaFX ListView

I’ve started to create a TileMap Editor for my JavaFX game engine. In this editor I’ve got a ListView that displays the Layers. Each Layer is represented by it’s name and a CheckBox is displayed next to it, so you can choose if you want to show or hide the layer:

The Layer List of my TileMapEditor

But simply adding the TileMapLayer objects into a ObservableList and displaying them with a ListView will result in this:

Displaying a TileMapLayer in a ListView with default rendering

In order to display the CheckBox, we need to do this:

layerList = FXCollections.observableArrayList(tileMap.getLayers());
        listView = new ListView<TileMapLayer>();
        listView.setItems(layerList);
        if (!layerList.isEmpty()) {
            listView.getSelectionModel().select(layerList.get(0));
        }
        Callback<TileMapLayer, ObservableValue<Boolean>> getProperty = new Callback<TileMapLayer, ObservableValue<Boolean>>() {
            @Override
            public BooleanProperty call(TileMapLayer layer) {

                return layer.getVisibleProperty();

            }
        };
        Callback<ListView<TileMapLayer>, ListCell<TileMapLayer>> forListView = CheckBoxListCell.forListView(getProperty);

        listView.setCellFactory(forListView);

Resulting in this:

Using a CheckBoxListCell to display the Layers

Now we only need to show some more meaningful text. You can do that by adding a StringConverter. Fortunately the factory method takes a StringConverter as it’s second argument:

layerList = FXCollections.observableArrayList(tileMap.getLayers());
        listView = new ListView<TileMapLayer>();
        listView.setItems(layerList);
        if (!layerList.isEmpty()) {
            listView.getSelectionModel().select(layerList.get(0));
        }
        Callback<TileMapLayer, ObservableValue<Boolean>> getProperty = new Callback<TileMapLayer, ObservableValue<Boolean>>() {
            @Override
            public BooleanProperty call(TileMapLayer layer) {

                return layer.getVisibleProperty();

            }
        };
        StringConverter stringConverter = new StringConverter<TileMapLayer>() {
            @Override
            public String toString(TileMapLayer t) {
                return t.getName();
            }

            @Override
            public TileMapLayer fromString(String string) {
                for (TileMapLayer tileMapLayer : layerList) {
                    if (string.equals(tileMapLayer.getName())) {
                        return tileMapLayer;
                    }
                }
                return null;
            }
        };
        Callback<ListView<TileMapLayer>, ListCell<TileMapLayer>> forListView = CheckBoxListCell.forListView(getProperty, stringConverter);

        listView.setCellFactory(forListView);

That’s it, now the TileMapLayer will be displayed as desired:

 

And here’s a video of the Application in action:

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>