Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clear prompt text in JavaFX TextField only when user starts typing

The default behaviour is that the prompt text in the field is erased as the field is being focused. That is when the marker is in the field.

Is it possible to configure the textfield so the prompt text is only erased when the user have started typing?

Otherwise I need to add a label beside/over each textfield for description of the value in it.

like image 999
Ramon Avatar asked Aug 04 '14 18:08

Ramon


People also ask

How do I set JavaFX prompt text?

To set the prompt text for a TextField use the setPromptText method: txtFld.

How do I make text field not editable in JavaFX?

In order to create a non editable JTextField , all you have to do is: Create a class that extends JFrame . Create a new JTextField . Use setEditable(false) that sets the specified boolean to indicate whether or not this textfield should be editable.

What is the difference between text and label in JavaFX?

A Text is a geometric shape (like a Rectangle or a Circle), while Label is a UI control (like a Button or a CheckBox). In Swing, geometric shapes were restricted to the painting mechanism, while in JavaFX they can be used in more generic ways. And you can use a Text clipping, giving the node shape by the text.


2 Answers

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...

like image 179
LionGod8 Avatar answered Oct 02 '22 22:10

LionGod8


You could configure the '-fx-prompt-text-fill' key in '.text-field:focused' area like in '.text-field' area (css):

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

and add the 'promptText' entry in fxml file:

<TextField fx:id="XY_Id" promptText="First name">

That is all and works for me.

like image 39
Daniel h. Avatar answered Oct 02 '22 20:10

Daniel h.