Implementing a show password toggle with JavaFX

Viewed 447

I wanted to add a toggle button that allows for the PasswordField to show the written contents, so I created a Textfield and a PasswordField that share the location in the GridPane and clicking the check box will toggle between the two. The problem is, however, that when I press Tab to navigate from the Username TextField to the PasswordField, it focuses on the invisible TextField first and then I have to press Tab again. So, all in all, to navigate from the Username TextField to the PasswordField I have to press Tab twice. picture of GUI

Is there a function in JavaFX that would better allow me to do this?

Here is my code:

Controller:

package sample;

import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.event.ActionEvent;


public class FXML_Login{

    String[] usernames = {"user", "user2", "user3"};
    String[] passwords = {"pass", "pass2", "pass3"};

    @FXML private Text loginText;
    @FXML private TextField username;
    @FXML private TextField passwordShown;
    @FXML private PasswordField passwordBullets;
    @FXML private CheckBox passToggle;

    @FXML protected void handleLoginSubmission(ActionEvent event){

        if(username.getText().equals(usernames[0]) && (passwordBullets.getText().equals(passwords[0])
                || passwordShown.getText().equals(passwords[0]))){

            loginText.setFill(Color.GREEN);
            loginText.setText("Login successful.");
        }

        else{
            loginText.setFill(Color.RED);
            loginText.setText("Login failed.");
        }
    }

    @FXML protected void togglePasswordVisible(ActionEvent event){

        if(passToggle.isSelected()){
            passwordShown.setText(passwordBullets.getText());
            passwordShown.setVisible(true);
            passwordBullets.setVisible(false);
            return;
        }

        passwordBullets.setText(passwordShown.getText());
        passwordBullets.setVisible(true);
        passwordShown.setVisible(false);
    }

    @FXML protected void initialize(){
    }
}

FXML:

<?import javafx.scene.control.CheckBox?>
<GridPane fx:controller="sample.FXML_Login"
          xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10"
          stylesheets = "/sample/styles.css">

    <Text id = "welcome"
          text="Welcome"
          GridPane.columnIndex="0"
          GridPane.rowIndex="0"
          GridPane.columnSpan="2"/>

    <Label text = "User Name: "
           GridPane.columnIndex="0"
           GridPane.rowIndex="1" />

    <TextField fx:id = "username"
               promptText = "Username"
               GridPane.columnIndex="1"
               GridPane.rowIndex="1"
               onAction="#handleLoginSubmission"/>

    <Label text = "Password: "
           GridPane.columnIndex="0"
           GridPane.rowIndex="2" />

    <TextField fx:id = "passwordShown"
               promptText = "Password"
               GridPane.columnIndex="1"
               GridPane.rowIndex="2"
               onAction="#handleLoginSubmission"/>

    <PasswordField fx:id = "passwordBullets"
                   promptText="Password"
                   GridPane.columnIndex="1"
                   GridPane.rowIndex="2"
                   onAction="#handleLoginSubmission"/>


    <Label text="Show password"
           GridPane.columnIndex="0"
           GridPane.rowIndex="3"/>

    <CheckBox fx:id="passToggle" onAction="#togglePasswordVisible"
              GridPane.columnIndex="1"
              GridPane.rowIndex="3"/>

    <HBox spacing="10"
          alignment="BOTTOM_RIGHT"
          GridPane.columnIndex="1"
          GridPane.rowIndex="4">
          <Button text="Sign In"
                  onAction="#handleLoginSubmission"/>
    </HBox>

    <Text fx:id = "loginText"
          GridPane.columnIndex="1"
          GridPane.rowIndex="6"/>



</GridPane>
1 Answers

There is an option called "Focus Traversable" that lets you navigate to it or not.

you only need to call the method "setFocusTraversable(boolean b)" with switching the checkBox and make a field traversable or not according to your desire.

here is the link to the documentation.

Related