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

ComboBoxPopupControl: remove eventFilter for F4

XMLWordPrintable

      Use-case is to let F4 trigger a process different from opening the popup (see https://stackoverflow.com/q/58550028/203657 - which might be a bad idea as for ux ;). Typically, such a requirement can be implemented by registering an eventFilter on the combo, do custom stuff and consume the event.

      For combo and related, that's not possible because popupControl uses the F4 to toggle the popup internally (no way to override/customize)

          // called by an eventFilter registered for type KeyEvent.ANY
          private void handleKeyEvent(KeyEvent ke, boolean doConsume) {
          ...
                  } else if (ke.getCode() == KeyCode.F4) {
                  if (ke.getEventType() == KeyEvent.KEY_RELEASED) {
                      if (comboBoxBase.isShowing()) comboBoxBase.hide();
                      else comboBoxBase.show();
                  }
                  ke.consume(); // we always do a consume here (otherwise unit tests fail)
          ...

      On digging a bit, it looks like a left-over from pre-inputMap times: ComboBoxBaseBehavior has a keyMapping for F4 for doing the same. So the offending code block in popupControl can probably simply be removed.

      For convenience, a short example demonstrating the issue: compile, run

      - press F4 in any of the controls
      - expected: printout only
      - actual: printout only and popup toggled

      Note that the exact behavior depends on type of combo and its editable state
      ComboBox: misbehaves for not-editable, okay for editable
      DatePicker: never misbehaves
      ColorPicker: always misbehaves

      public class ComboAlikeKeyHandling extends Application {

          private Parent createContent() {
              ComboBox<String> combo = new ComboBox<>();
              combo.getItems().addAll("one", "two");
              
              ComboBox<String> comboEditable = new ComboBox<>();
              comboEditable.getItems().addAll("one", "two");
              comboEditable.setEditable(true);
              
              DatePicker picker = new DatePicker();
              picker.setEditable(false);
              
              DatePicker pickerEditable = new DatePicker();
              
              ColorPicker color = new ColorPicker();
              ColorPicker colorEditable = new ColorPicker();
              colorEditable.setEditable(true);
              
              EventHandler<KeyEvent> grabF4 = e -> {
                  if (e.getCode() == KeyCode.F4) {
                      System.out.println("my own F4 handling");
                      e.consume();
                  }
              };
              
              combo.addEventFilter(KeyEvent.KEY_RELEASED, grabF4);
              comboEditable.addEventFilter(KeyEvent.KEY_RELEASED, grabF4);
              picker.addEventFilter(KeyEvent.KEY_RELEASED, grabF4);
              pickerEditable.addEventFilter(KeyEvent.KEY_RELEASED, grabF4);
              color.addEventFilter(KeyEvent.KEY_RELEASED, grabF4);
              colorEditable.addEventFilter(KeyEvent.KEY_RELEASED, grabF4);
              
              VBox box = new VBox(10, combo, comboEditable, picker, pickerEditable, color, colorEditable);
              return box;
          }

          @Override
          public void start(Stage stage) throws Exception {
              stage.setScene(new Scene(createContent(), 200, 200));
              stage.setTitle("");
              stage.show();
          }

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

      }
       

            fastegal Jeanette Winzenburg
            fastegal Jeanette Winzenburg
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: