Issue
I have a simple dialog with some text fields and I want to add a simple listener to a property of the TextField. Should be a no brainer, but it's never called it seems. Debugging reveals that the listener is added (I think), but it doesn't do anything. My feeling is that it gets garbage collected. Question is, why?
ps. Adding a setOnKeyPressed handler does work fine, as do all other operations on it.
This is my class:
public class MyClass {
@FXML
private TextField emailTextField;
@FXML
private TextField codeTextField;
@FXML
private TextField nameTextField;
private static final Logger LOG = Logger.getLogger(StageController.class.getName());
@FXML
private TextField emailTextField;
@FXML
private TextField codeTextField;
@FXML
private TextField nameTextField;
private static final Logger LOG = Logger.getLogger(StageController.class.getName());
@FXML
private void initialize() {
emailTextField.onKeyPressedProperty().addListener((observable, oldValue, newValue) -> {
LOG.info("Hi!");
});
}
Solution
You're adding a ChangeListener
to the onKeyPressed
property. This property is itself an event handler which responds to key presses, and your code means that whenever the onKeyPressed
property changes, i.e. any time setOnKeyPressed(...)
or onKeyPressedProperty().set(...)
is called, your listener is invoked.
So your listener is never invoked because the onKeyPressedProperty()
never changes.
You probably don't want to respond to changes in the onKeyPressedProperty()
, but instead (perhaps) want to actually respond to key presses. You do this by either setting the onKeyPressed
property, or adding another event handler.
Either:
emailTextField.setOnKeyPressed(event -> LOG.info("Hi!"));
or:
emailTextField.addEventHandler(KeyEvent.KEY_PRESSED, event -> LOG.info("Hi!"));
Even this is likely not what you want. The text field already knows what to do when a key is pressed; depending on the key it may change the text. What you more typically want to do is respond to the text changing:
emailTextField.textProperty().addListener((obs, oldText, newText) -> LOG.info(newText));
This will respond to text changes, whether or not they occur due to key presses (e.g. it will respond to the user pasting text with the mouse) but will not respond to key presses that don't change anything (e.g. pressing SHIFT or CTRL, or DELETE when the text field is empty).
Answered By - James_D
Answer Checked By - Clifford M. (JavaFixing Volunteer)