JavaFX默认的PasswordField控件不能动态切换输入内容是否可见,无法满足实际需求。这里通过自定义JavaFX控件,实现如下的效果:
隐藏密码时
显示密码时
- 1.自定义组件,继承StackPane
- 2.内部使用一个TextField和一个PasswordField,分别充当密码可见时和不可见时展示的控件,默认显示PasswordField
- 3.分别给TextField和PasseordField设置样式,主要是设置眼睛图片作为background图片
- 4.分别监听TextField和PasseordField的鼠标移动事件,当鼠标移动到眼睛图片附近时,设置鼠标指针的样式为手形
- 5.分别监听TextField和PasseordField的鼠标点击事件,当点击的位置在眼睛图片附近时,切换要显示的控件
- 6.将TextField和PasswordField的textProperty属性进行双向绑定
- 7.定义一个用于获取输入内容的方法
public class FXPasswordField extends StackPane {
private final TextField textField;
private final PasswordField passwordField;
public FXPasswordField() {
super();
textField = new TextField();
passwordField = new PasswordField();
initStyle();
initEvent();
textField.textProperty().bindBidirectional(passwordField.textProperty());
getChildren().addAll(textField, passwordField);
}
private void initStyle() {
String style = "-fx-padding: 5px 30px 5px 5px; -fx-background-repeat: no-repeat; -fx-background-position: right 10 center; -fx-background-size: contain;";
String textFieldStyle = style "-fx-background-image: url(/assets/image/eye-open.png);";
String passwordFieldStyle = style "-fx-background-image: url(/assets/image/eye-close.png);";
textField.setStyle(textFieldStyle);
passwordField.setStyle(passwordFieldStyle);
setOnMouseMovedEvent(textField, textFieldStyle);
setOnMouseMovedEvent(passwordField, passwordFieldStyle);
}
private void setOnMouseMovedEvent(TextField textField, String style){
textField.setOnMouseMoved((MouseEvent event) -> {
double width = textField.getWidth();
if(event.getX() > width - 30){
textField.setStyle(style "-fx-cursor: hand;");
}else{
textField.setStyle(style "-fx-cursor: text;");
}
});
}
private void initEvent(){
setOnMouseClickedEvent(textField, passwordField);
setOnMouseClickedEvent(passwordField, textField);
}
private void setOnMouseClickedEvent(TextField willHideInput, TextField willShowInput){
willHideInput.setOnMouseClicked((MouseEvent event) -> {
double width = textField.getWidth();
if(event.getX() > width - 30){
// 移除当前显示的输入框, 显示另一个输入框
setNodeVisible(willHideInput, false);
setNodeVisible(willShowInput, true);
}
});
}
private void setNodeVisible(Node node, boolean visible){
node.setVisible(visible);
node.setManaged(visible);
}
public String getText(){
return textField.getText();
}
}
使用