目前我正在使用Dialog<User> loginDialog = new Dialog<>();
来创建一个登录对话框,在该对话框中,用户需要输入用户名和密码,然后点击“确认”按钮进行登录。
我的问题
不幸的是,每次按下“确认”按钮时,对话框面板都会自动关闭,无论登录是否成功。我希望只有在取消按钮被按下或者登录成功时才关闭对话框面板。
解决方案
正如NwDX所指出的那样,需要使用addEventFilter方法。我的实现看起来像这样:
btnLogin.addEventFilter(ActionEvent.ACTION, event -> {
if (!comboAdministrator.getValue().getPassword().equals(pfLogin.getText())) {
lblErrorNotification.setText("Password is incorrect. Try again!");
pfLogin.requestFocus();
event.consume();
}
});
解释:事件过滤器会捕获任何不匹配的密码,并将错误消息发送到标签节点以进行通知。event.consume()是必要的,否则对话框将再次关闭并恢复其原始行为。
完整代码解决方案
private Optional<User> showLoginDialog() {
Dialog<User> dialog = new Dialog<>();
dialog.setTitle("Administrator Login");
dialog.setHeaderText("Enter administrator password");
dialog.initOwner(btnShowManagerView.getScene().getWindow());
dialog.getDialogPane().getStylesheets().add("util/resources/myCSS.css");
dialog.setGraphic(new ImageView(ResourceClass.class.getResource("locker.png").toString()));
ButtonType loginButtonType = new ButtonType("Login", ButtonData.YES);
ButtonType cancelButtonType = ButtonType.CANCEL;
dialog.getDialogPane().getButtonTypes().addAll(loginButtonType, cancelButtonType);
Label lblErrorNotification = new Label();
lblErrorNotification.setTextFill(Color.RED);
GridPane gridPane = new GridPane();
gridPane.setHgap(10);
gridPane.setVgap(10);
gridPane.setPadding(new Insets(20, 150, 20, 20));
ComboBox<User> comboAdministrator = new ComboBox();
comboAdministrator.setItems(main.getAdministrators());
comboAdministrator.setValue(main.getAdministrators().get(0));
comboAdministrator.setConverter(new StringConverter<User>() {
@Override
public String toString(User object) {
return object.getLoginName();
}
@Override
public User fromString(String string) {
return null;
}
});
main.enableComboBoxBaseShowIfFocused(comboAdministrator);
PasswordField pfLogin = new PasswordField();
gridPane.add(new Label("AdminUser"), 0, 0);
gridPane.add(comboAdministrator, 1, 0);
gridPane.add(new Label("Password"), 0, 1);
gridPane.add(pfLogin, 1, 1);
gridPane.add(lblErrorNotification, 1, 2);
Button btnLogin = (Button) dialog.getDialogPane().lookupButton(loginButtonType);
btnLogin.addEventFilter(ActionEvent.ACTION, event -> {
if (!comboAdministrator.getValue().getPassword().equals(pfLogin.getText())) {
lblErrorNotification.setText("Password is incorrect. Try again!");
pfLogin.requestFocus();
event.consume();
}
});
btnLogin.disableProperty()
.bind(pfLogin.textProperty().isEmpty());
dialog.getDialogPane().setContent(gridPane);
Platform.runLater(()
-> comboAdministrator.requestFocus());
dialog.setResultConverter((ButtonType buttonType) -> {
if (buttonType == loginButtonType) {
return comboAdministrator.getValue();
}
return null;
});
return dialog.showAndWait();
}