Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8233677

ListChangeListener of a ListView does not see actual selected index and item

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P3 P3
    • None
    • jfx11
    • javafx
    • x86_64
    • windows_10

      ADDITIONAL SYSTEM INFORMATION :
      Windows 10,
      Java 11 and onward

      A DESCRIPTION OF THE PROBLEM :
      The ListChangeListener of a ListView does not see the actual selected index and item if the selection is made programmatically by calling listView.getSelectionModel().select().

      The reason is that in the implementation of MultipleSelectionModelBase#select(int), the line

      selectedIndices.set(row)

      already fires the change listeners, before the setSelectedIndex and setSelectedItem methods are called. This was different in JDK 8.

      REGRESSION : Last worked in version 8

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create a ListChangeListener, which uses the selected index of the SelectionModel of a ListView and register the ListChangeListener at the selection model of the ListView.

      After a call to the method listView.getSelectionModel().select to change observe the selected index.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The ListChangeListener will report the actual selection.
      ACTUAL -
      The ListChangeListener will report the previous selection or -1/null in the initial case.

      ---------- BEGIN SOURCE ----------
      import javafx.application.Application;
      import javafx.collections.ListChangeListener;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.control.ListView;
      import javafx.scene.layout.BorderPane;
      import javafx.stage.Stage;


      public class ListViewTest extends Application {
          @Override
          public void start(Stage stage) {
              BorderPane root = new BorderPane();
              ListView<String> listView = new ListView<>();
              listView.getItems().addAll("a", "b", "c");
              root.setCenter(listView);
              ListChangeListener<String> listener = change -> {
                  System.out.println(listView.getSelectionModel().getSelectedIndex() + " index");
                  System.out.println(listView.getSelectionModel().getSelectedItem() + " item");
              };
              listView.getSelectionModel().getSelectedItems().addListener(listener);

              Button button = new Button("Select c");
              button.setOnAction(ev-> listView.getSelectionModel().select("c"));
              root.setBottom(button);
              Scene scene = new Scene(root);

              stage.setTitle("ListView Test");
              stage.setScene(scene);
              stage.show();
          }
          public static void main(String[] args) {
              launch(args);
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Don't use listView.getSelectionModel().getSelectedIndex() or listView.getSelectionModel().getSelectedItem() in the body of a ListChangeListener.

      FREQUENCY : always


            aghaisas Ajit Ghaisas
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: