62

I am working on JavaFX project. I need to perform some task on a JavaFX TextField.

For example on the "on focus" event for the TextField I want to print

System.out.println("Textfield on focus");

and on the "out focus" event it should print

System.out.println("Textfield out focus");
DVarga
  • 21,311
  • 6
  • 55
  • 60
java baba
  • 2,199
  • 13
  • 33
  • 45

3 Answers3

111

I thought it might be helpful to see an example which specifies the ChangeListener as an anonymous inner class like scottb mentioned.

TextField yourTextField = new TextField();
yourTextField.focusedProperty().addListener(new ChangeListener<Boolean>()
{
    @Override
    public void changed(ObservableValue<? extends Boolean> arg0, Boolean oldPropertyValue, Boolean newPropertyValue)
    {
        if (newPropertyValue)
        {
            System.out.println("Textfield on focus");
        }
        else
        {
            System.out.println("Textfield out focus");
        }
    }
});

I hope this answer is helpful!

Brendan
  • 3,589
  • 3
  • 20
  • 11
  • 4
    Does this execute before or after the focus actually changes? – James Wierzba Sep 01 '15 at 20:23
  • 1
    It's worth noting that `changed` will still be called even if the application is closed while `yourTextField` has focus. This was very undesirable for me, and I got around it by doing something along the lines of `primaryStage.setOnCloseRequest(event -> { removeListeners(); });` – Jake Jul 08 '16 at 19:49
19

You can use the focusedProperty of Node to attach a ChangeListener.

Extending the answer from Brendan: from JavaFX8 (as it comes with Java 8), a lambda expression combined with a ternary operator can make it really compact:

textField.focusedProperty().addListener((obs, oldVal, newVal) -> 
    System.out.println(newVal ? "Focused" : "Unfocused"));
DVarga
  • 21,311
  • 6
  • 55
  • 60
  • If the third parameter is a boolean that tells you if the `TextField` is in focus, why has everyone here named it something along the lines of `newValue`? What am I missing? – qwerty Aug 10 '20 at 16:16
  • 1
    The third Argument is the new value of the property. True: now it is focused, false: now it is unfocused. – DVarga Aug 10 '20 at 17:59
  • I get it now. I thought it was referring to the value of the text in the `TextField`. – qwerty Aug 10 '20 at 19:08
10

You will want to attach a ChangeListener to the FocusProperty of the TextField that you wish to monitor.

In JavaFX, you can attach notification events (Change or Invalidation Listeners) to any JavaFX property that an object may possess as long as the property meets the minimum definition for a JavaFX bean.

Refer to this post if your event handlers will be doing other things such as modifying Cancel or Default button settings: JavaFX 2 -- Setting the defaultButton property: mutually exclusive?

Here is some code to attach a Change Listener to a text box:

txtDx.focusedProperty().addListener(m_txtDxListener);

The Listener object has been stored in an instance field so that it may be used with both addListener() and removeListener(). For a short lived TextField, you can specify the listener object with an anonymous inner class.

Here is the private class that I wrote for my focus listener:

private class FocusPropertyChangeListener implements ChangeListener<Boolean> {

    FocusPropertyChangeListener() { System.out.println("New FPCL instance"); }

    @Override
    public void changed(ObservableValue<? extends Boolean> ov, 
        Boolean oldb, Boolean newb) {
        System.out.println("Focus change triggered");

        if (ancEncEditor.isVisible() && !ancEncEditor.isDisabled()) {
            boolean b = (newb != null && newb.booleanValue() == true);
            System.out.println("txtDx focus change event triggered: DxAdd = " + b);

            if (b) { btnDxAdd.setDefaultButton(true); }
            else { btnWindowCommit.setDefaultButton(true); }
            btnWindowCommit.setCancelButton(true);
            btnDxAdd.setDefaultButton(b);
        }
    }
}
Community
  • 1
  • 1
scottb
  • 9,908
  • 3
  • 40
  • 56
  • 2
    java baba, just add a simple change listener on focusedProperty() of the TextField, and check, which kind of focused state (true/false) it is now. – Alexander Kirov May 14 '13 at 21:38