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

ComboBox: action incorrectly triggered after items.setAll

XMLWordPrintable

    • x86_64
    • windows_10

      Note: the description is changed (from that in the original report) because its expectation ("Action events should only be triggered when a user interacts with the combobox and changes the value themselves.") was wrong (see doc citation in Kevin's comment below).

      Nevertheless, the behavior of firing an action after setAll (as demonstrated in the example) is wrong in two aspects:

      A) run as-is (that is with an initial selected value that's contained in both lists, though at a different index in each - "blue")

      - press the button: note that the selected value is still the inital (blue)
      - expected: no trigger of action
      - actual: action triggered twice, first with null, then with blue

      B) change initial value to "black" (== contained in original list, uncontained in new)

      - press the button: note that the selected value is pink (the item at the same index as the initial value in the old list)
      - expected: action triggered
      - actual: no action triggered




      ADDITIONAL SYSTEM INFORMATION :
      Windows 10, Openjfx 11.0.2 via maven

      A DESCRIPTION OF THE PROBLEM :
      See this stack overflow question I posted:
      https://stackoverflow.com/questions/66674211/combobox-fires-action-event-when-underlying-data-is-modified?noredirect=1#comment117901023_66674211

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create the example provided in the stack overflow question.
      Run the example, choose a new colour in the dropdown, click the button. Repeat.
      Note the console log.
      The code can be modified to instead attach a listener to the valueproperty, results will be the same.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -

      see above

      ---------- BEGIN SOURCE ----------
      package sample;

      import java.util.Arrays;
      import java.util.List;
      import javafx.application.Application;
      import javafx.collections.FXCollections;
      import javafx.collections.ObservableList;
      import javafx.geometry.Orientation;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.control.ComboBox;
      import javafx.scene.layout.FlowPane;
      import javafx.stage.Stage;

      public class Main extends Application {

          ObservableList<String> theList = FXCollections.observableArrayList();

          @Override
          public void start(Stage primaryStage) throws Exception{
              primaryStage.setTitle("Sample");
              FlowPane root = new FlowPane(Orientation.VERTICAL);
              root.setVgap(20);

              List<String> initialColors = Arrays.asList("red", "green", "blue", "black");
              theList.addAll(initialColors);

              ComboBox<String> theComboBox = new ComboBox<>();
              theComboBox.setItems(theList);
      // theComboBox.setOnAction( event -> {
      // System.out.println(String.format("theComboBox action listener triggered, current value is %s", theComboBox.getValue()));
      // });

              theComboBox.valueProperty().addListener((observable, oldValue, newValue)->{
                  System.out.println(String.format("theComboBox action listener triggered, current value is %s", theComboBox.getValue()));
              });

              Button bttn1 = new Button("Press me");
              bttn1.setOnAction(event -> {
                  List<String> someColors = Arrays.asList("red", "orange", "mauve", "pink", "blue", "salmon", "chiffon");
                  System.out.println("About to issue setAll against observable list");
                  theList.setAll(someColors);
              });

              root.getChildren().add(theComboBox);
              root.getChildren().add(bttn1);

              primaryStage.setScene(new Scene(root, 100, 150));
              primaryStage.show();

              System.out.println("Setting initial selection to \"blue\"");
              theComboBox.setValue("blue");
          }


          public static void main(String[] args) {
              launch(args);
          }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      (was: use a flag variable in the listener - for the original report, that is not wanting to be notified when value changes are triggered by modifying the items via setAll)

      FREQUENCY : always


        1. Main.java
          2 kB
          Praveen Narayanaswamy

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

              Created:
              Updated: