RFR: 8091429: ObservableList<E>#setAll(int from, int to, Collection<? extends E> col)
Nir Lisker
nlisker at openjdk.org
Wed Oct 15 09:09:19 UTC 2025
On Wed, 15 Oct 2025 03:40:24 GMT, John Hendrikx <jhendrikx at openjdk.org> wrote:
> This PR implements two new default methods on `ObservableList` to be able to replace elements at a given position or within a specified range.
>
> Justification for this change is to allow an `ObservableList` to be bulk modified resulting in a single `ListChangeListener` call back. In this way the callbacks don't observe the list changing its size from S to S-X back to S again(*). Currently the only way to bulk replace a range of items is to remove X items then add X items, resulting in two listener callbacks in between which the size of the list can be observed to change.
>
> The other alternative is to call `set` individually for each item, which results in many change notifications.
>
> With the addition of this PR, and the changes in `ModifiableObservableListBase`, replacing a range of items becomes a single change callback.
>
> (*) The list may indeed change size still as plain `List` does not have `setAll` operations; size listeners may observe this, but it will no longer be observable from a `ListChangeListener` due to multiple separate callbacks.
How about doing this through the SubList view? JavaFX's implementation already has a `SubObservableList` inner class that propagates changes on it to the list's listeners:
ObservableList<Integer> list = FXCollections.observableArrayList();
list.addAll(0, 1, 2, 3, 4, 5, 6);
list.addListener((ListChangeListener<Integer>) c -> System.out.println(c));
List<Integer> subList = list.subList(2, 4);
System.out.println(list);
System.out.println(subList);
subList.clear(); // equivalent to list.remove(2, 4);
prints
[0, 1, 2, 3, 4, 5, 6]
[2, 3]
{ [2, 3] removed at 2 }
The issue is that it's a `List` and not an `ObservableList`, so it doesn't have JavaFX's additional bulk operation methods. However, "just" having `ObservableList#subList` return an `ObservableList` will allow to make all range operations easily:
ObservableList<Integer> list = FXCollections.observableArrayList();
list.addAll(0, 1, 2, 3, 4, 5, 6);
list.addListener((ListChangeListener<Integer>) c -> System.out.println(c));
ObservableList<Integer> subList = list.subList(2, 4); // suggestion
subList.setAll(7, 8);
I think that this would be more flexible/composable and result in a smaller API surface (current bulk methods would also be made redundant technically).
-------------
PR Comment: https://git.openjdk.org/jfx/pull/1937#issuecomment-3405348899
More information about the openjfx-dev
mailing list