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

Editable ComboBox: typing SPACE in textField must not hide popup

XMLWordPrintable

      To reproduce, run the example below

      - open popup
      - type anything in the textfield, including a space
      - expected: popup remains open
      - actual: popup hidden on space

      The example:

      public class ComboTextFieldSpace extends Application {
          
          @Override
          public void start(Stage stage) {
              HBox root = new HBox();

              ObservableList<String> items = FXCollections.observableArrayList(
                      "One", "Two", "Three", "Four", "Five", "Six",
                      "Seven", "Eight", "Nine", "Ten");
              ComboBox<String> cb = new ComboBox<String>(items);
              cb.setEditable(true);
              
              root.getChildren().addAll(cb);

              Scene scene = new Scene(root);
              stage.setScene(scene);
              stage.show();
          }

          public static void main(String[] args) {
              launch();
          }
          
          @SuppressWarnings("unused")
          private static final Logger LOG = Logger
                  .getLogger(ComboTextFieldSpace.class.getName());
      }


      Culprit seems to be the keyPressed handler installed on the listView in ComboBoxListViewSkin.createList:

      private ListView<T> createList() {
        ...
              _listView.setOnKeyPressed(t -> {
                  // TODO move to behavior, when (or if) this class becomes a SkinBase
                  if (t.getCode() == KeyCode.ENTER ||
                          t.getCode() == KeyCode.SPACE ||
                          t.getCode() == KeyCode.ESCAPE) {
                      comboBox.hide();
                  }
              });
           ...
      }

      Might be a reasonable thingy to do for not-editable combos but annoys users if editable. A quick hack for application code:

          public void disableHidingBySpace(ComboBox<String> cb) {
              ComboBoxListViewSkin<?> skin = (ComboBoxListViewSkin<?>) cb.getSkin();
              ListView<?> list = (ListView<?>) skin.getPopupContent();
              EventHandler<? super KeyEvent> old = list.getOnKeyPressed();
              if (old != null) {
                  list.setOnKeyPressed(key -> {
                      if (key.getCode() == KeyCode.SPACE && cb.isEditable()) {
                          return;
                      }
                      old.handle(key);
                  });
              }
          }

      A clean solution is probably related to a clean solution of JDK-8209788 - both could be handled by formally specify (in listViewBehavior) keyMappings for a ListView in the role of popupContent for a combo.

            arapte Ambarish Rapte
            fastegal Jeanette Winzenburg
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: