7

I have a JavaFX TextField control on my FXMl that looks like this...

<TextField fx:id="input_search" onKeyPressed="#keyListener" prefHeight="25.0" prefWidth="197.0" />

I want to automatically change all characters to uppercase when the user is typing.

The code in my controller :

public void keyListener(KeyEvent event){
    //maybe transform the pressed key to uppercase here...
}
ItachiUchiha
  • 36,135
  • 10
  • 122
  • 176
Martin
  • 474
  • 2
  • 6
  • 17

2 Answers2

17

There are a few ways to achieve this:

Override replaceText()

TextField textField = new TextField() {
    @Override public void replaceText(int start, int end, String text) {
        super.replaceText(start, end, text.toUpperCase());
    }
};

Use TextFormatter

textField.setTextFormatter(new TextFormatter<>((change) -> {
    change.setText(change.getText().toUpperCase());
    return change;
}));

This part of the answer triggers textProperty twice and shouldn't be used. It is only here to show the original post.

Instead of using the onKeyPressed on your TextField, use the textProperty() of your TextField. Just add the following code inside the initialize() of the controller.

input_search.textProperty().addListener((ov, oldValue, newValue) -> {
     input_search.setText(newValue.toUpperCase());
});
ItachiUchiha
  • 36,135
  • 10
  • 122
  • 176
  • 1
    Note, that this will call the listener twice. First you get your untransformed string the user typed in, then you get the uppercased string you set inside the listener. – Vitaly Apr 16 '18 at 23:31
  • 1
    @Vitaly Thanks for pointing it out. I have added alternatives. – ItachiUchiha Apr 18 '18 at 05:29
  • Actually I believe the original (with the listener) causes a NPE when you Ctrl-Z from the text field. – Manius Aug 09 '18 at 18:42
6

Starting with JavaFX 8u40, you can set a TextFormatter object on a text field. This allows you to apply a filter/converter on the user input. Here's an example.

Listening to changes in the text property comes with the drawback of triggering two change events, one for the initial input (in your case the lower-case characters) and another one for the corrected input (the upper-case characters). If there are are other listeners on the text property, they will need to deal with both events and decide which event is relevant for them. The TextFormatter approach does not have this drawback.

Community
  • 1
  • 1
Uwe
  • 844
  • 8
  • 13
  • Thanks, I've learned something new. But there seems to be another drawback. A TextField with a TextFormatter set seems to consume the ESC KeyEvent. I don't have time to research it now but the reason might be that with TextFormatter set, ESC is used to cancel current edit: http://stackoverflow.com/a/38059343/3519572 – tomorrow Jan 23 '17 at 18:56