Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Listen to changes in TextField defined in FXML

I am writing a simpe login GUI that is composed by a GridPane, which is the main container, then a TextField which takes in the user nickname and finally a login Button.

I wrote the GUI structure in FXML combined with CSS.

What I wanted to do was keeping the login Button disabled until the user actually wrote something in the TextField. I could only find an answer related to this but I wanted to know what was the best method to put this Listener in the FXML code itself so that I could get a cleaner code in the FXML controller.

I tried to use the method onKeyTyped but that didn't do the work cause I get no response whenever I'm typing in the TextField.

This is my FXML code

<TextField fx:id="usernameTextField"
           promptText="Username"
           onKeyTyped="#userTyped"
           stylesheets="@loginStyle.css">

What's the best method to achieve this?

like image 979
Mattia Righetti Avatar asked Jan 24 '26 10:01

Mattia Righetti


1 Answers

In general, if you want to perform an action if the text of a text field changes, you need to register a listener with the text field's textProperty(), which you haver to do in the controller:

@FXML
private TextField usernameTextField ;

public void initialize() {
    usernameTextField.textProperty().addListener((obs, oldText, newText) -> {
        // do what you need with newText here, e.g.
        loginButton.setDisable(newText.isEmpty());
    });
}

However, if all you need is to bind a property in one control to a property in another control (or some simple dependency of that property), you can use FXML expression binding:

<TextField fx:id="usernameTextField"/>
<Button text="Login" disable="${usernameTextField.text.empty}" />

Here's a SSCCE:

ButtonDisableTest.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Button?>

<VBox alignment="CENTER" spacing="5" xmlns:fx="http://javafx.com/fxml/1">
    <TextField fx:id="usernameTextField"/>
    <Button text="Login" disable="${usernameTextField.text.empty}" />
</VBox>
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class ButtonDisableTest extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("ButtonDisableTest.fxml"));
        Scene scene = new Scene(root, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

enter image description here

like image 147
James_D Avatar answered Jan 27 '26 00:01

James_D



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!