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

ChoiceBox: incorrect toggle selected for uncontained selectedItem




      To reproduce, compile and run the example below
      - see the first item shown (and its toggle selected on opening the popup)
      - click button to select an uncontained item
      - expected and actual: value and selected item are sync'ed (verified by print out)
      [ ignore JDK-8087555:
      - expected uncontained items displayed
      - actual: old selected item displayed
      - open popup
      - expected: no toggle selected
      - actual: old toggle selected

      Reason is a broken invariant (also partly noted - kind-of, a bit upside down - in JDK-8088012) in the implementation of choiceBox' selectionModel (maybe even in its super SingleSelectionModel?):

      assertEquals(getItems().indexOf(selectedItem), getSelectedIndex())

      Fix in ChoiceBoxSelectionModel, override select(item) to explicitly set selectedIndex to -1 if not contained:

          public void select(T obj) {
              // super doesn't updatee selectedIndex for uncontained selectedItem
              // if we don't add this, the incorrect radioItem is marked selected
              // with uncontained selectedItem (after there had been a contained once)
              if (obj != null && !choiceBox.getItems().contains(obj)) {

      It might be cleaner to fix this in SingleSelectionModel (at least in the long run). But ComboBox has a super constraint violation specified as intended behaviour (aside: I think that's utterly impossible!), better not touch super for now.

      The boundary between this issue and JDK-8087555 is that this is a failure in the selectionModel while the other is a failure in the skin

      The example:

      public class ChoiceBoxSelectedToggleBug extends Application {

          ObservableList<String> items = FXCollections.observableArrayList(
                  "5-item", "4-item", "3-item", "2-item", "1-item");
          private String title;

          private Parent getContent() {
              ChoiceBox<String> box = new ChoiceBox<>(items);
              Button setValue = new Button("Set value to uncontained");
              setValue.setOnAction(e -> {
                  System.out.println("value/ selected item: " + box.getValue() +
              BorderPane pane = new BorderPane(box);
              pane.setBottom(new HBox(10, setValue));
              title = box.getClass().getSimpleName();
              return pane;

          public void start(Stage primaryStage) throws Exception {
              Scene scene = new Scene(getContent());
              primaryStage.setTitle(System.getProperty("java.version") + title);

          public static void main(String[] args) {


        Issue Links



              fastegal Jeanette Winzenburg
              fastegal Jeanette Winzenburg
              0 Vote for this issue
              2 Start watching this issue