likethesky
likethesky

Reputation: 846

JavaFX KeyEvent processing in Modal Window / Dialog

I'm trying to have my dialog accept <Enter> for the defaultButton and <ESC> to execute the cancelButton.

I have some code like this:

dialog1 = new Stage(StageStyle.UNDECORATED);
dialog1.initModality(Modality.WINDOW_MODAL);
dialog1.initOwner(primaryStage);
dialog1.setScene(
  new Scene(
    HBoxBuilder.create().styleClass("modal-dialog").children(
      LabelBuilder.create().text("Tells user what to do...").build(),
      ButtonBuilder.create().text("Next step").defaultButton(true).onAction(new EventHandler<ActionEvent>() {
        @Override public void handle(ActionEvent actionEvent) {
          // take action and close the dialog1.
          // do "OK" actions here...
          dialog1.close();
        }
      }).build(),
      ButtonBuilder.create().text("Cancel").cancelButton(true).onAction(new EventHandler<ActionEvent>() {
        @Override public void handle(ActionEvent actionEvent) {
          // abort action and close dialog1.
          // do "CANCEL" actions here...
          dialog1.close();
        }
      }).build()
    ).build()
    , Color.TRANSPARENT
  )
);
dialog1.getScene().getStylesheets().add(getClass().getResource("ModalDialog.css").toExternalForm());

And I'd like to add something like the below to handle the keyboard. Is something simple like this possible?

.onAction(new EventHandler<KeyEvent>() {
  @Override public void handle(KeyEvent t) {
    if (t.getCode() == KeyCode.ENTER) {
      // do "OK" actions here
      dialog1.close();                    
    } else {
      // do "CANCEL" actions here
      dialog1.close();                    
    }
  }
}).build()        

My problem is, I have looked around for a 'node' to hang this handler on, but can't seem to find one. Like TextInputBuilder, or something like that. I also don't know the exact format of the syntax, even if a TextInputBuilder was the correct node to create, so if you'd show me the exact form that the call should take, that'd be great.

I am guessing something like:

dialog1.setScene(
  new Scene(
    HBoxBuilder.create().styleClass("modal-dialog").children(
      TextInputFieldBuilder.onAction(new EventHandler<KeyEvent>() {
        @Override public void handle(KeyEvent t) {
          if (t.getCode() == KeyCode.ENTER) {
            // do "OK" actions here
            dialog1.close();                    
          } else {
            // do "CANCEL" actions here
            dialog1.close();                    
          }
        }
      }).build(),
      LabelBuilder.create().text("Tells user what to do...").build(),
      // [ ... ]

Upvotes: 0

Views: 1305

Answers (1)

jewelsea
jewelsea

Reputation: 159416

I'm trying to have my dialog accept <Enter> for the defaultButton and <ESC> to execute the cancelButton.

This is a the default behaviour of the defaultButton and cancelButton, so usually no extra code would be required to do this.


If, in the unlikely event, that some other control in the scene is consuming or presses and you really want to override that:

  1. Add a filter on the scene to trap the relevant KeyEvents.
  2. Invoke the fire event on the corresponding button when you receive it.
  3. consume the event after you have processed it by invoking fire so that the event won't get routed to the button handler causing the event to potentially be handled twice.

Don't duplicate code for ok/cancel and dialog closing in the key event handler which is already defined for the buttons.

Upvotes: 1

Related Questions