目前我正在使用 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();
}
最佳答案
Dialog Validation / Intercepting Button Actions
In some circumstances it is desirable to prevent a dialog from closing until some aspect of the dialog becomes internally consistent (e.g. a form inside the dialog has all fields in a valid state). To do this, users of the dialogs API should become familiar with the DialogPane.lookupButton(ButtonType) method. By passing in a ButtonType (that has already been set in the button types list), users will be returned a Node that is typically of type Button (but this depends on if the DialogPane.createButton(ButtonType) method has been overridden). With this button, users may add an event filter that is called before the button does its usual event handling, and as such users may prevent the event handling by consuming the event. Here's a simplified example:
final Button btOk = (Button) dlg.getDialogPane().lookupButton(ButtonType.OK);
btOk.addEventFilter(ActionEvent.ACTION, event -> {
if (!validateAndStore()) {
event.consume();
}
});
关于java - 如何使 JavaFX 对话框在按下 OK 按钮后不自行关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38230632/