RFR: 8279640: ListView with null SelectionModel/FocusModel throws NPE
John Hendrikx
jhendrikx at openjdk.java.net
Tue Jan 11 09:05:32 UTC 2022
On Sat, 8 Jan 2022 00:17:36 GMT, Marius Hanl <mhanl at openjdk.org> wrote:
> This PR fixes a bunch of NPEs when a null `SelectionModel` or `FocusModel` is set on a `ListView`.
>
> The following NPEs are fixed (all are also covered by exactly one test case):
> NPEs with null selection model:
> - Mouse click on a `ListCell`
> - SPACE key press
> - KP_UP (arrow up) key press
> - HOME key press
> - END key press
> - BACK_SLASH + CTRL key press
>
> NPEs with null focus model:
> - SPACE key press
> - Select an items: getSelectionModel().select(1)
> - Clear-Select an item and add one after: listView.getSelectionModel().clearAndSelect(1); listView.getItems().add("3");
> We had a similar discussion on #557. We came to the conclusion that we allow null as a selection or focusmodel and don't set a noop selection model or something of this kind.
Even earlier though in https://github.com/javafxports/openjdk-jfx/issues/569 a `NONE` model was suggested. And I still think that makes much more sense, because in effect the "behavior" of the `NONE` model is now spread out over dozens of places in the code (as the `null` checks are what is defining the behavior) instead of in a single place.
> The biggest problem with this is the following example: I as a developer set the selection model to null via `setSelectionModel(null)`. Now if the code silently set the selection model to an empty noop selection model, we won't get null when calling `getSelectionModel()`, which a developer would expect.
This is an example from `ListView` which already does something custom because the property is lazily instantiated:
public final MultipleSelectionModel<T> getSelectionModel() {
return selectionModel == null ? null : selectionModel.get();
}
Just write that as:
public final MultipleSelectionModel<T> getSelectionModel() {
return selectionModel == null ? null :
selectionModel.get() == NONE_SELECTION_MODEL ? null : selectionModel.get();
}
`NONE_SELECTION_MODEL` is stateless so only a single instance is needed.
> Also from a look of the code, even if we use a noop focus model, we would still the focus because of the `anchor` stuff, which is set in the `ListViewBehaviour`. If we do a null check and fast return like now, they won't be set -> there are not visible. So it might not even fix our problem but makes even more.
A check can also be done to see if something matches the `NONE` model, just like you can check for `null`, so you can still fast return in special cases.
The chosen approach works as well of course.
-------------
PR: https://git.openjdk.java.net/jfx/pull/711
More information about the openjfx-dev
mailing list