0

I have an ObservableList<Person>, where a Person has firstName and lastName properties (in the appropriate JavaFX way), and I want to make a ListView that will display the names of the people and reflect changes in both the list and the properties of the individual Person objects in the list. How is this best done? There are two issues:

  1. We need to make the ListView observe the two name properties so it can refresh changes. One way to do this is explained in this answer (see also this answer). However, this solution requires passing an "extractor" to the constructor of the ObservableList, and my list already exists (as part of a larger data model). One would think there would be a way to wrap the existing ObservableList to add an extractor, but I don't see it in the API. (Well, there is this method, but it treats the list being wrapped as simply a List and not an ObservableList, so updates to the original list aren't reported. There is also this method that creates a "synchronized" wrapper of an ObservableList, but it doesn't include an extractor parameter.) Perhaps I should just implement a method to do this wrapping myself?

  2. We need to render the Person items in the ListView. I know how to do this using a custom ListCell class, but I'm hoping there might be an easier way since I'm only displaying strings. Relying on Person.toString is not the right thing to do, since I may have other views of Person that require different conversions of Person to String. Is there any way to pass a ListView<Person> a Callback<Person,String> (or something equivalent) to convert the items to strings?

So, in the end, I do have a way to do what I want: write my own wrapper in 1 and use a custom cell factory in 2. I just feel like this requires more work on my part than it should for what I'd think is a relatively common situation. Is there an easier way I'm missing?

Community
  • 1
  • 1
Winnie
  • 25
  • 2
  • See http://stackoverflow.com/questions/34602457/add-extractor-to-existing-observablelist – James_D Jan 18 '16 at 02:18
  • @James_D: thanks! I somehow didn't get to that page in my searching. I've just started with JavaFX today, and it's been a bit frustrating trying to find this kind of information... – Winnie Jan 18 '16 at 02:23

1 Answers1

0

This is already answered in the comments to Add extractor to existing ObservableList.

Create a new observable list with an extractor, and bidirectionally bind the content to your existing list. Something along the lines of

ListView<Person> listView = new ListView<>();
ObservableList<Person> personList = FXCollections.observableList(person -> 
    new Observable[] {person.firstNameProperty(), person.lastNameProperty()});
Bindings.bindContentBidirectional(model.getPersonList(), personList);
listView.setItems(personList);
Community
  • 1
  • 1
James_D
  • 201,275
  • 16
  • 291
  • 322