Ernio
Ernio

Reputation: 978

ObservableMap with extractor for values?

Short: I am looking for a way to update contents of ListView based on changes made to Map and values inside the map.

Situation:

There is "source" LinkedHashMap<String, Data> on logical side of application.

On GUI part there is a ListView such as:

// Gui list.
ListView<Data> list = new ListView<>();

// Observable map wrapping logical map
ObservableMap<String, Data> items = FXCollections.observableMap(logic.getLogicalMap());
// This listener will cause gui list to also change logical list
items.addListener((MapChangeListener<String, Data>) change ->
{
    list.getItems().removeAll(change.getValueRemoved());
    if (change.wasAdded())
    {
        list.getItems().add(change.getValueAdded());
    }
});
// Show values of map in ListView.
list.getItems().setAll(items.values());

list.setCellFactory(new Callback<ListView<Data>, ListCell<Data>>()
{
    @Override
    public ListCell<Data> call(ListView<Data> list)
    {
        return new DataCell();
    }
});
// Basically cells that update when map is updated.
private static class DataCell extends ListCell<Data>
{
    @Override
    public void updateItem(Data item, boolean empty)
    {
        super.updateItem(item, empty);

        if (item != null)
        {
            this.setText(item.toString());
        }
        else
        {
            this.setText("");
        }
    }
}

Now: Everything is cool until I want cells to display changes made to Data contained in Map#values().

I ran into Extractors, but apparently they are only for ObservableLists. So now: How do I notify ObservableMap (which then notifies ListView) of updates happening on "cellular" (values) level?

Upvotes: 2

Views: 828

Answers (1)

Ernio
Ernio

Reputation: 978

Refractoring Data to be JavaBean (was POJO) and using (in DataCell#updateItem):

this.textProperty().bind(Bindings.concat(item.propertyOne(), " / ", item.propertyTwo()));

Solves my problems.

Upvotes: 1

Related Questions