目前我正在使用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();
}
});
解释:eventfilter捕获任何不匹配的密码,并向标签节点发送错误消息以进行通知。 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();
}
答案 0 :(得分:5)
对话框验证/拦截按钮操作
在某些情况下,最好阻止对话框关闭 直到对话框的某些方面变得内部一致(例如a 对话框内的表单使所有字段都处于有效状态)。去做这个, 对话框API的用户应该熟悉 DialogPane.lookupButton(ButtonType)方法。通过传递一个ButtonType (已经在按钮类型列表中设置),用户将是 返回一个通常是Button类型的Node(但这取决于 如果DialogPane.createButton(ButtonType)方法已经 覆盖)。使用此按钮,用户可以添加一个事件过滤器 在按钮执行其通常的事件处理之前调用,并且因此 用户可以通过使用该事件来阻止事件处理。这是一个 简化示例:
final Button btOk = (Button) dlg.getDialogPane().lookupButton(ButtonType.OK);
btOk.addEventFilter(ActionEvent.ACTION, event -> {
if (!validateAndStore()) {
event.consume();
}
});