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

ComboBox with FilteredList: Selection in Popup wrong after change of Predicate

XMLWordPrintable

    • x86_64
    • linux

      FULL PRODUCT VERSION :
      java version "1.8.0_121"
      Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Linux linuxmint 4.4.0-59-generic #80-Ubuntu SMP Fri Jan 6 17:47:47 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux


      A DESCRIPTION OF THE PROBLEM :
      I am trying to create a ComboBox with filter. For this I have replaced the ComboBox items with a FilteredList. To filter I just change the Predicate of the FilteredList. The problem is, that the selection in the popup is dropped (no selection afterwards) when the Predicate is changed.

      I could not observe the issue when using a normal ObservableList and changing the items or when using a SortedList and changing the Comparator.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Please see the example application. This application does contain three ComboBoxes.

      The first operates on the unfiltered list.
      The second shows a filtered list.
      The third shows a sorted list.

      Every 5 seconds the filter is changed and the sorted list is reversed.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The selection in the popup of all three ComboBoxes always shows the item "1" as selected.
      ACTUAL -
      The selection in the filtered popup is OK when it is opened the first time, but once the Predicate changes, the selection is not OK anymore.

      The sorted list works OK.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.util.Comparator;
      import java.util.Timer;
      import java.util.TimerTask;
      import java.util.function.Predicate;

      import javafx.application.Application;
      import javafx.application.Platform;
      import javafx.collections.transformation.FilteredList;
      import javafx.collections.transformation.SortedList;
      import javafx.geometry.Orientation;
      import javafx.scene.Scene;
      import javafx.scene.control.ComboBox;
      import javafx.scene.layout.FlowPane;
      import javafx.stage.Stage;

      public class ComboBoxItemChange extends Application
      {
          public static void main(String[] args)
          {
              Application.launch(args);
          }

          @Override
          public void start(Stage primaryStage) throws Exception
          {
              ComboBox<String> comboBox = new ComboBox<>();
              comboBox.setId("comboBox");
              comboBox.getItems().addAll("1", "2", "3");
              comboBox.setValue("1");

              ComboBox<String> filteredComboBox = new ComboBox<>();
              filteredComboBox.setId("filteredComboBox");
              FilteredList<String> filteredList = comboBox.getItems().filtered(null);
              filteredComboBox.setItems(filteredList);
              filteredComboBox.setValue("1");

              ComboBox<String> sortedComboBox = new ComboBox<>();
              sortedComboBox.setId("sortedComboBox");
              SortedList<String> sortedList = comboBox.getItems().sorted(null);
              sortedComboBox.setItems(sortedList);
              sortedComboBox.setValue("1");

              FlowPane pane = new FlowPane(Orientation.VERTICAL);
              pane.getChildren().add(comboBox);
              pane.getChildren().add(filteredComboBox);
              pane.getChildren().add(sortedComboBox);
              primaryStage.setScene(new Scene(pane));
              primaryStage.sizeToScene();
              primaryStage.show();

              Timer timer = new Timer(true);
              timer.schedule(new TimerTask()
              {
                  Predicate<String> FILTER = value -> "1".equals(value);

                  @Override
                  public void run()
                  {
                      Platform.runLater(() ->
                      {
                          filteredList.setPredicate(filteredList.getPredicate() == null ? FILTER : null);
                          sortedList
                              .setComparator(sortedList.getComparator() == null ? Comparator.reverseOrder() : null);
                      });
                  }
              }, 5000, 5000);
          }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      Instead of modifying the Predicate, you need to create a new FilteredList and call filteredComboBox.setItems() again with this new list.

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: