Clear prompt text in JavaFX TextField only when user starts typing

I know it’s a bit old, but I needed it myself and this is still very relevant.
I will complete jewelsea‘s answer and give a simpler solution.

Background

Apparently this was the default behavior of Java(FX) (prompt text in a TextField was cleared only when the user starts typing).
But then, following a request (or a bug report) in the JIRA system,
Java changed this behavior (and made the default to clear the text when the TextField gets focus).

You can review this bug report here.


Solution

To get back to the old default (and nicer behavior IMO), all you need to do is to add the following line(s) of code.

In case your application interface is written using proper Java code.

Java Code:

textField.setStyle("-fx-prompt-text-fill: derive(-fx-control-inner-background, -30%);");

Where textField is your TextField component.


And in case your application interface is written using FXML and CSS, add the following to your CSS file.

JavaFX FXML (CSS):

.text-input, .text-input:focused {
    -fx-prompt-text-fill: derive(-fx-control-inner-background, -30%);
}

——————————————————————————–

Cleared-on-Focus Behavior

Currently it’s the default behavior (the text-field’s prompt text is cleared when the text-field gets focus),
so you don’t need to do anything to get this behavior,
but in case Java will decide to go back to the cleared-on-typing behavior,
and you want to get the cleared-on-focus behavior, this is how to:

In case of proper Java code – it’s a bit tricky since you can’t define behavior of pseudo-classes directly.

Java Code (using bindings):

textField.styleProperty().bind(
        Bindings
        .when(textField.focusedProperty())
            .then("-fx-prompt-text-fill: transparent;")
            .otherwise("-fx-prompt-text-fill: derive(-fx-control-inner-background, -30%);"));

or –

Java Code (using events):

textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
    @Override
    public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
        if (newValue) {
            textField.setStyle("-fx-prompt-text-fill: transparent;");
        } else {
            textField.setStyle("-fx-prompt-text-fill: derive(-fx-control-inner-background, -30%);");
        }
    }
});

JavaFX FXML CSS:

Add the following to your CSS file.

.text-input {
    -fx-prompt-text-fill: derive(-fx-control-inner-background, -30%);
}

.text-input:focused {
    -fx-prompt-text-fill: transparent;
}

Hope this helped…

Leave a Comment