JDK-8095648 : ListView may not return the selected item (Regression)
  • Type: Bug
  • Component: javafx
  • Sub-Component: controls
  • Affected Version: 8u20
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-06-20
  • Updated: 2016-06-07
  • Resolved: 2014-08-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8u40Fixed
Related Reports
Blocks :  
Relates :  
Description
When a ListView is embedded in a CustomMenuItem, when one select a ListView item, the selectedItem may be null.
The use case is Scene Builder. The same SB code running on FX8 GA is working fine.
See the related SB issue (DTL-6742) for details.
Comments
Changeset: http://hg.openjdk.java.net/openjfx/8u-dev/rt/rev/4756dd1cca2c Unit tests: javafx.scene.control.ListViewTest.test_rt_37632() javafx.scene.control.TableViewTest.test_rt_37632() javafx.scene.control.TreeTableViewTest.test_rt_37632() javafx.scene.control.TreeViewTest.test_rt_37632()
29-08-2014

To me this seems to be an obvious issue that we push to 8u40. Thanks David for creating a test application that we can use to fix the bug (and develop unit tests from).
23-06-2014

This doesn't seem like something we would want to address for 8u20 (too late), but we need to follow-up on Jonathan's observation about the NPE.
20-06-2014

I ran David's simple test case and it behaves the same in FX 8 and 8u20. In either release, following the above instructions produces the following output: selectedIndex = -1 selectedIndices = [0]
20-06-2014

Code to reproduce. Type a character in the TextField then click on "C" in the resulting list. Notice that getSelectedIndex() and getSelectedIndices() do not return the same value: @Override public void start(Stage stage) { final ObservableList<String> listOne = FXCollections.observableArrayList("A", "B", "C"); final ObservableList<String> listTwo = FXCollections.observableArrayList("C"); final ListView<String> listView = new ListView<>(); listView.setItems(listOne); listView.onMouseClickedProperty().setValue(e -> { System.err.println("selectedIndex = " + listView.getSelectionModel().getSelectedIndex()); System.err.println("selectedIndices = " + listView.getSelectionModel().getSelectedIndices()); }); listView.getSelectionModel().selectFirst(); TextField textField = new TextField(); textField.onKeyReleasedProperty().setValue(e -> listView.setItems(listTwo)); final Label label = new Label(); label.textProperty().bind(listView.selectionModelProperty().getValue().selectedItemProperty()); VBox root = new VBox(10, label, textField, listView); Scene scene = new Scene(root, 800, 600); stage.setScene(scene); stage.show(); }
20-06-2014

The problem arises from calling suggestedLv.setItems(FXCollections.observableArrayList(suggestedItems)) from AutoSuggestEditor#showPopup. When this is called, the current selected item is '-fx-alignment'. The new list is being set to '-fx-text-fill.' Since the new list does not contain the current selection, the selected item becomes null. Should the selection model default to the first item in the list in this case? A good workaround for SB is: diff -r 6f456400c44c apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/editors/AutoSuggestEditor.java --- a/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/editors/AutoSuggestEditor.java Thu Jun 19 15:56:59 2014 -0400 +++ b/apps/scenebuilder/SceneBuilderKit/src/com/oracle/javafx/scenebuilder/kit/editor/panel/inspector/editors/AutoSuggestEditor.java Fri Jun 20 09:41:56 2014 -0400 @@ -313,6 +313,7 @@ private void showPopup(List<String> suggestedItems) { if (!suggestedLv.getItems().equals(suggestedItems)) { suggestedLv.setItems(FXCollections.observableArrayList(suggestedItems)); + if (suggestedLv.getSelectionModel().getSelectedIndex() == -1) suggestedLv.getSelectionModel().selectFirst(); } if (entryField.getContextMenu().isShowing() == false) { // System.out.println("showPopup");
20-06-2014

It's late here but I wanted to look into this quickly. I just pulled the latest code from the 8udev repo and am able to reproduce the issue. Unfortunately I wasn't able to follow from the NPE to the statement that selectedItem was null without doing some debugging, so for the purposes of anyone else looking into this issue, here's more detail. The exception is long, but the important part is as follows: java.lang.NullPointerException at com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.editors.StyleEditor$StyleItem.lambda$initialize$1(StyleEditor.java:276) at com.oracle.javafx.scenebuilder.kit.editor.panel.inspector.editors.StyleEditor$StyleItem$$Lambda$553/29108529.changed(Unknown Source) at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:361) at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81) at javafx.scene.control.TextInputControl$TextProperty.fireValueChangedEvent(TextInputControl.java:1123) at javafx.scene.control.TextInputControl$TextProperty.markInvalid(TextInputControl.java:1127) at javafx.scene.control.TextInputControl$TextProperty.invalidate(TextInputControl.java:1066) at javafx.scene.control.TextInputControl$TextProperty.access$1300(TextInputControl.java:1038) at javafx.scene.control.TextInputControl.lambda$new$167(TextInputControl.java:134) From a quick look at this code, it appears that propertyTf.getText() is returning null for some reason. If I null check there, the NPE just moves to another location, so that is obviously not the fix. The next thing I looked at (again, quickly as it is getting late) is whether the propertyTf TextField is having null set as its text value. It turns out it does - you can add a breakpoint to the textPropertyChange in StyleEditor, and see that newText is sometimes null. Going back into the stacktrace, null is being set on the propertyTf TextField in AutoSuggestEditor.useSuggested(). If I take a look at the listview selection model state at that point, it appears that the selectedIndex is -1 and therefore there is no selectedItem set. Interestingly selectedIndices is correct, with a single value in the list for 0, indicating row 0 is selected. To avoid a NPE, it is possible to add a null check in here, but of course that doesn't fix the usability problem, whereby the '-fx-text-fill' text doesn't get put into the text field. A better workaround is to replace the second line in the useSuggested() method with the following: int selectedIndex = suggestedLv.getSelectionModel().getSelectedIndices().get(0); String selected = suggestedLv.getItems().get(selectedIndex); This uses the correct text string and makes everything work again. Of course it isn't the proper fix, but working that out will require more time than I have right now.
20-06-2014

@Jonathan: thanks for the quick investigation. Sorry, I could have provided more debug details. I tried getSelectedIndex(), which returned -1, but didn't try getSelectedIndices() which indeed returns the correct value ([0]).
20-06-2014

I'm looking into this
20-06-2014