实现JavaFX中的显示密码切换功能

huangapple go评论77阅读模式
英文:

Implementing a show password toggle with JavaFX

问题

我想添加一个切换按钮允许PasswordField显示已输入的内容所以我创建了一个Textfield和一个PasswordField它们共享GridPane中的位置点击复选框将在两者之间切换然而问题是当我按Tab键从Username TextField导航到PasswordField时它首先将焦点放在不可见的TextField上然后我必须再次按Tab键总之要从Username TextField导航到PasswordField我必须按两次Tab键
<?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="欢迎"
          GridPane.columnIndex="0"
          GridPane.rowIndex="0"
          GridPane.columnSpan="2"/>

    <Label text = "用户名:"
           GridPane.columnIndex="0"
           GridPane.rowIndex="1" />

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

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

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

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


    <Label text="显示密码"
           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="登录"
                  onAction="#handleLoginSubmission"/>
    </HBox>

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

</GridPane>
英文:

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

得分: 1

有一个名为“Focus Traversable”的选项,可以让您选择是否可以导航到它。

您只需要调用方法“setFocusTraversable(boolean b)”并切换复选框,根据您的需求使字段可遍历或不可遍历。

这是链接到文档的链接

英文:

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.

huangapple
  • 本文由 发表于 2020年5月31日 07:02:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/62109665.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定