在我的用户界面中,我有一个像这样的PasswordField(urm底部的那个!):
我希望用户能够选中您在图片中看到的复选框并显示所有“秘密”密码字符。与我们从许多现代的询问密码的 UI 中获得的选项没有太大区别。 但是,我在 JavaFX API 中找不到任何可以让我这样做的东西?
如果我的担忧成立,那么我想使用一个
TextField
来显示按下的最后一个键仅半秒或直到按下下一个键,然后他将屏蔽所有以前的用户输入。这会产生一种很酷的动画效果,有时可以在现代 UI 中看到。但是,有没有办法让我掌握依赖于操作系统的(我认为它依赖于操作系统??)我应该使用密码回显字符?
如果无法获得与操作系统相关的字符,那么我很乐意使用您在图片上看到的字符(Windows 8 计算机上的 JavaFX)。这个陌生人的 UTF-8 代码点是什么?
> 但是,我在 JavaFX API 中找不到任何可以让我这样做的东西?
PasswordField
组件默认不显示屏蔽文本。但是,您可以将 PasswordField
与 TextField
一起使用,并分别使用这些组件切换屏蔽/未屏蔽文本。未屏蔽的文本由 TextField
显示,如下面的示例演示所示。
>我想使用一个 TextField 来显示最后一个按下的键仅半秒或直到按下下一个键,然后他将屏蔽所有以前的用户输入。
由于
PasswordField
,本身就是TextField
的扩展版本。您始终可以使用您提到的属性构建自己的自定义密码文本框。
>有没有办法让我掌握我应该使用的操作系统相关的(我认为它是操作系统相关的??)密码回显字符?
坦白说没有抓住你在这里说的话。您可以通过向
PasswordField.textPrperty()
添加更改侦听器来跟踪文本更改,并执行动画、计时器等。您可以通过扩展 PasswordFieldSkin
并通过 CSS -fx-skin
使用它来覆盖默认的子弹遮罩。请参阅此处来源中的项目符号定义:
public class PasswordFieldSkin extends TextFieldSkin {
public static final char BULLET = '\u2022';
public PasswordFieldSkin(PasswordField passwordField) {
super(passwordField, new PasswordFieldBehavior(passwordField));
}
@Override protected String maskText(String txt) {
TextField textField = getSkinnable();
int n = textField.getLength();
StringBuilder passwordBuilder = new StringBuilder(n);
for (int i=0; i<n; i++) {
passwordBuilder.append(BULLET);
}
return passwordBuilder.toString();
}
}
最后,这是使用绑定显示密码字符的演示应用程序:
@Override
public void start(Stage primaryStage) {
// text field to show password as unmasked
final TextField textField = new TextField();
// Set initial state
textField.setManaged(false);
textField.setVisible(false);
// Actual password field
final PasswordField passwordField = new PasswordField();
CheckBox checkBox = new CheckBox("Show/Hide password");
// Bind properties. Toggle textField and passwordField
// visibility and managability properties mutually when checkbox's state is changed.
// Because we want to display only one component (textField or passwordField)
// on the scene at a time.
textField.managedProperty().bind(checkBox.selectedProperty());
textField.visibleProperty().bind(checkBox.selectedProperty());
passwordField.managedProperty().bind(checkBox.selectedProperty().not());
passwordField.visibleProperty().bind(checkBox.selectedProperty().not());
// Bind the textField and passwordField text values bidirectionally.
textField.textProperty().bindBidirectional(passwordField.textProperty());
VBox root = new VBox(10);
root.getChildren().addAll(passwordField, textField, checkBox);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Demo");
primaryStage.setScene(scene);
primaryStage.show();
}
您需要创建三个元素:
将密码字段放置在相同位置(x,y):
<PasswordField fx:id="pass_hidden" layoutX="X" layoutY="Y" />
<TextField fx:id="pass_text" layoutX="X" layoutY="Y"/>
<CheckBox fx:id="pass_toggle" onAction="#togglevisiblePassword" .... />
注意: 替换
X
和 Y
的值。
添加您的控制器:
@FXML
private PasswordField pass_hidden;
@FXML
private TextField pass_text;
@FXML
private CheckBox pass_toggle;
/**
* Controls the visibility of the Password field
* @param event
*/
@FXML
public void togglevisiblePassword(ActionEvent event) {
if (pass_toggle.isSelected()) {
pass_text.setText(pass_hidden.getText());
pass_text.setVisible(true);
pass_hidden.setVisible(false);
return;
}
pass_hidden.setText(pass_text.getText());
pass_hidden.setVisible(true);
pass_text.setVisible(false);
}
// The controller class needs to implement Initializable to override initialize
@Override
public void initialize(URL location, ResourceBundle resources) {
this.togglevisiblePassword(null);
}
如果您想知道密码的值,您可以创建一个返回它的方法:
private String passwordValue() {
return pass_toggle.isSelected()?
pass_text.getText(): pass_hidden.getText();
}
我知道这很旧,但我正在寻找答案,这是我的解决方案:
@FXML
private JFXButton showpassword;
private String password;
showpassword.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
password = passwordField.getText();
passwordField.clear();
passwordField.setPromptText(password);
});
showpassword.addEventFilter(MouseEvent.MOUSE_RELEASED, e -> {
passwordField.setText(password);
passwordField.setPromptText("Password");
});
使用“WIN10 Eye - 解锁密码”等图形按钮
好吧,密码字段有一个属性可以设置项目符号中的文本。此方法 maskText(String txt) 保留在皮肤上。您可以用新的皮肤替换它。当您键入方法 maskText 测试时,如果您可以替换为项目符号.. 使用一个布尔值来通知.. 您可以从另一事件重用此代码。这是一个例子。问候
public class Main extends Application {
@Override
public void start(Stage stage) throws Exception {
StackPane root = new StackPane();
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(50));
PasswordField passwordField = new PasswordField();
passwordField.setSkin(new VisiblePasswordFieldSkin(passwordField));
root.getChildren().add(passwordField);
stage.setScene(new Scene(root, 400, 400));
stage.show();
}
}
class VisiblePasswordFieldSkin extends TextFieldSkin {
private final Button actionButton = new Button("View");
private final SVGPath actionIcon = new SVGPath();
private boolean mask = true;
public VisiblePasswordFieldSkin(PasswordField textField) {
super(textField);
actionButton.setId("actionButton");
actionButton.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
actionButton.setPrefSize(30,30);
actionButton.setFocusTraversable(false);
actionButton.setBackground(new Background(new BackgroundFill(Color.TRANSPARENT, CornerRadii.EMPTY, new Insets(0))));
getChildren().add(actionButton);
actionButton.setCursor(Cursor.HAND);
actionButton.toFront();
actionIcon.setContent(Icons.VIEWER.getContent());
actionButton.setGraphic(actionIcon);
actionButton.setVisible(false);
actionButton.setOnMouseClicked(event -> {
if(mask) {
actionIcon.setContent(Icons.VIEWER_OFF.getContent());
mask = false;
} else {
actionIcon.setContent(Icons.VIEWER.getContent());
mask = true;
}
textField.setText(textField.getText());
textField.end();
});
textField.textProperty().addListener((observable, oldValue, newValue) -> actionButton.setVisible(!newValue.isEmpty()));
}
@Override
protected void layoutChildren(double x, double y, double w, double h) {
super.layoutChildren(x, y, w, h);
layoutInArea(actionButton, x, y, w, h,0, HPos.RIGHT, VPos.CENTER);
}
@Override
protected String maskText(String txt) {
if (getSkinnable() instanceof PasswordField && mask) {
int n = txt.length();
StringBuilder passwordBuilder = new StringBuilder(n);
for (int i = 0; i < n; i++) {
passwordBuilder.append(BULLET);
}
return passwordBuilder.toString();
} else {
return txt;
}
}
}
enum Icons {
VIEWER_OFF("M12 6c3.79 0 7.17 2.13 8.82 5.5-.59 1.22-1.42 2.27-2." +
"41 3.12l1.41 1.41c1.39-1.23 2.49-2.77 3.18-4.53C21.27 7.11 17 4 12 4c-1.27 " +
"0-2.49.2-3.64.57l1.65 1.65C10.66 6.09 11.32 6 12 6zm-1.07 1.14L13 9.21c.57.25 1.03.71 " +
"1.28 1.28l2.07 2.07c.08-.34.14-.7.14-1.07C16.5 9.01 14.48 7 12 7c-.37 0-.72.05-1.07." +
"14zM2.01 3.87l2.68 2.68C3.06 7.83 1.77 9.53 1 11.5 2.73 15.89 7 19 12 19c1.52 0 2.98-.29 " +
"4.32-.82l3.42 3.42 1.41-1.41L3.42 2.45 2.01 3.87zm7.5 7.5l2.61 2.61c-.04.01-.08.02-.12.02-1.38 " +
"0-2.5-1.12-2.5-2.5 0-.05.01-.08.01-.13zm-3.4-3.4l1.75 1.75c-.23.55-.36 1.15-.36 1.78 0 2.48 2.02 " +
"4.5 4.5 4.5.63 0 1.23-.13 1.77-.36l.98.98c-.88.24-1.8.38-2.75.38-3.79 0-7.17-2.13-8.82-5.5.7-1.43 1.72-2.61 2.93-3.53z"),
VIEWER("M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7." +
"5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z");
private String content;
Icons(String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
void viewpass(ActionEvent event) {
if (checkpass.isSelected()){
pass.setPromptText(pass.getText());
pass.setText("");
pass.setDisable(true);
}else {
pass .setText(pass.getPromptText());
pass.setPromptText("");
pass.setDisable(false);
}
}
您还可以使用带有单选按钮的文本字段和密码字段来完成此操作,如下所示。
import javafx.fxml.Initializable;
import com.jfoenix.controls.*;
import com.jfoenix.controls.JFXPasswordField;
import com.jfoenix.controls.JFXRadioButton;
import javafx.fxml.FXML;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable{
@FXML
private JFXPasswordField PasswordField;
@FXML
private JFXRadioButton passVisible;
@FXML
private JFXTextField textField1;
@Override
public void initialize(URL location, ResourceBundle resources)
{
textField1.textProperty().bind(PasswordField.textProperty());
textField1.visibleProperty().bind(passVisible.selectedProperty());
PasswordField.visibleProperty().bind(passVisible.selectedProperty().not());
}
}