Changing Focus With The Return Key

GitHub repository

This is an issue I wanted to fix with a current project and whilst it’s a small issue, I find it useful to enter data into a field, hit ENTER, and expect to go to the next field in the tab order.

In this demo app, every time you update a JDBC parameter and hit TAB or ENTER, the JDBC URL automatically updates.

To do this you need to:

  1. Handle the ENTER key being pressed
  2. Move focus to the next control in the tab order
  3. Set this behaviour for all relevant text controls

Step 1 is straightforward, but Step 2 is a bit messier. Tab order in JavaFX is controlled by the order controls are arranged inside their parent.

Steps 1 and 2 – Handle The Enter Key and Change Focus

I wanted to enable multiple controls to process the ENTER key, so I created an EventHandler for events.

This handler finds the index of the control handling the key press and requests focus from next control in parent’s list. A bit ugly, but it works.

/**
 * Force a focus lost event on enter key as well as tab
 */
class FocusHandler : EventHandler<KeyEvent> {
  override fun handle(e: KeyEvent?) {
    if (e?.code === KeyCode.ENTER) {
      val ctrl = e.source as Control

      // Tab order is determined by order of the children 
      // inside the parent.
      // On hitting enter we shift focus to next child in order
      val kids = ctrl.parent.childrenUnmodifiable

      val nextFocus = kids.indexOf(ctrl) + 1
      if (nextFocus < kids.size) {
        kids[nextFocus].requestFocus()
      }
    }
  }
}

Step 3 – Enable ENTER Key Handling for Multiple Controls

We attach our FocusHandler to all relevant controls.

....
val enterKeyHandler = FocusHandler()

hostText.onKeyPressed = enterKeyHandler
portText.onKeyPressed = enterKeyHandler
databaseText.onKeyPressed = enterKeyHandler
....

And that’s it.

One thought on “Changing Focus With The Return Key

Leave a comment