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

ComboBox: cancel button must not be triggered if escape is consumed by combo handler

    XMLWordPrintable

Details

    • Fix Understood

    Description

      To reproduce, run the example below, focus one of the combo, press escape

      expected: message from combo handler printed
      actual: message from cancel button is printed before message from combo handler

      The bug is similar to JDK-8207759 (there reported against ENTER and TextField), with the same underlying reason: ComboBoxBaseBehavior has a keyMapping for ESCAPE which forwards the event to the combo's parent if interpreted as not used. This manual firing of the received keyEvent wrecks the event deliverance sequence such that handlers in the parent hierarchy see the event before the consuming singleton handler of the combo.

      The fix is basically the same: in ComboBoxBaseBehavior, replace the manual forwarding by letting the event travel "naturally" up the chain.

      The example:

      public class ComboCancelButton extends Application {

          private Parent createContent() {
              ObservableList<String> data= FXCollections.observableArrayList("one", "two");
              ComboBox<String> editable = new ComboBox<>(data);
              editable.setEditable(true);
              EventHandler<KeyEvent> consumer = e -> {
                  if (e.getCode() == ESCAPE) {
                      System.out.println("consuming escape");
                      e.consume();
                  }
              };
              editable.setOnKeyPressed(consumer);
              
              ComboBox<String> notEditable = new ComboBox<>(data);
              notEditable.setOnKeyPressed(consumer);
              
              Button cancel = new Button("Cancel");
              cancel.setCancelButton(true);
              cancel.setOnAction(a -> System.out.println("cancel triggered"));
              
              VBox content= new VBox(10, editable, notEditable, cancel);
              return content;
          }

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

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

      }

      Attachments

        Issue Links

          Activity

            People

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

              Dates

                Created:
                Updated: