在JavaFX对话框中控制ESC键操作

在JavaFX对话框中控制ESC键操作,javafx,javafx-8,Javafx,Javafx 8,我有一个JavaFX应用程序,它最初会显示一个登录对话框,供用户输入用户名和密码。请参阅下面的源代码 如果用户单击“连接”按钮,应用程序将使用输入的用户名和密码执行登录,隐藏登录对话框,然后显示主窗口 如果用户单击“退出”按钮或“X”关闭按钮,将显示警报以获得用户的确认。如果用户确认,应用程序将退出 我的问题是当用户在显示登录对话框时按Escape键时会发生什么。按下此键时,将显示退出确认警报,然后立即关闭。因此,我们看到的是,每当按下退出键时,退出确认对话框就会立即出现 为什么会这样 我想按下

我有一个JavaFX应用程序,它最初会显示一个登录对话框,供用户输入用户名和密码。请参阅下面的源代码

如果用户单击“连接”按钮,应用程序将使用输入的用户名和密码执行登录,隐藏登录对话框,然后显示主窗口

如果用户单击“退出”按钮或“X”关闭按钮,将显示警报以获得用户的确认。如果用户确认,应用程序将退出

我的问题是当用户在显示登录对话框时按Escape键时会发生什么。按下此键时,将显示退出确认警报,然后立即关闭。因此,我们看到的是,每当按下退出键时,退出确认对话框就会立即出现

为什么会这样

我想按下退出键相当于点击“退出”或“X”按钮。也就是说,当按下退出键时,将显示退出确认对话框

或者,是否可以完全禁用退出键

提前谢谢

public class TestApp extends Application {

    private Stage primaryStage;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        this.primaryStage = stage;
        HBox pane = new HBox();
        pane.setAlignment(Pos.CENTER);
        Scene scene = new Scene(pane, 300, 300);
        stage.setScene(scene);
        showLoginDialog();
    }

    public void showLoginDialog() {
        Dialog<String> loginDialog = new Dialog<>();
        loginDialog.setTitle("Login");
        loginDialog.setHeaderText("Enter User Name and Password to login.");
        loginDialog.setResizable(false);
        Label userNameLabel = new Label("User Name:");
        Label passwordLabel = new Label("Password:");
        TextField userNameField = new TextField();
        userNameField.setMaxWidth(Double.MAX_VALUE);
        PasswordField passwordField = new PasswordField();
        passwordField.setMaxWidth(Double.MAX_VALUE);
        GridPane grid = new GridPane();
        grid.setAlignment(Pos.CENTER);
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20, 35, 20, 35));
        grid.add(userNameLabel, 1, 1);
        grid.add(userNameField, 2, 1);
        grid.add(passwordLabel, 1, 2);
        grid.add(passwordField, 2, 2);
        loginDialog.getDialogPane().setContent(grid);
        loginDialog.getDialogPane().getButtonTypes().add(ButtonType.OK);
        loginDialog.getDialogPane().getButtonTypes().add(ButtonType.CANCEL);
        Button connectButton = (Button) loginDialog.getDialogPane().lookupButton(ButtonType.OK);
        connectButton.setText("Connect");
        connectButton.addEventFilter(ActionEvent.ACTION, event -> {
            // perform login here
            loginDialog.hide();
            primaryStage.show();
            event.consume();
        });
        Button exitButton = (Button) loginDialog.getDialogPane().lookupButton(ButtonType.CANCEL);
        exitButton.setText("Exit");
        exitButton.addEventFilter(ActionEvent.ACTION, event -> {            
            handleExit();
            event.consume();
        });
        Stage stage = (Stage) loginDialog.getDialogPane().getScene().getWindow();
        stage.setOnCloseRequest(event -> {
            handleExit();
            event.consume();
        });
        stage.show();
    }

    private void handleExit() {
        Alert alert = new Alert(AlertType.CONFIRMATION, "", ButtonType.YES, ButtonType.NO);
        alert.setHeaderText("Confirm exit?");
        alert.resultProperty().addListener((observable, previous, current) -> {
            if (current == ButtonType.YES) {
                System.exit(1);
            }
        });
        alert.show();
    }

}
公共类TestApp扩展应用程序{
私人阶段初级阶段;
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
public void start(Stage)引发异常{
this.primaryStage=阶段;
HBox窗格=新的HBox();
窗格设置对齐(位置中心);
场景=新场景(窗格,300300);
舞台场景;
showLoginDialog();
}
public void showLoginDialog(){
Dialog loginDialog=新建Dialog();
loginDialog.setTitle(“登录”);
setHeaderText(“输入登录的用户名和密码”);
loginDialog.SetResizeable(假);
Label usernamelab=新标签(“用户名:”);
Label passwordLabel=新标签(“密码:”);
TextField userNameField=新建TextField();
userNameField.setMaxWidth(Double.MAX_值);
PasswordField PasswordField=新PasswordField();
passwordField.setMaxWidth(Double.MAX_值);
GridPane grid=新建GridPane();
网格设置对齐(位置中心);
网格。setHgap(10);
网格设置间隙(10);
网格设置填充(新插图(20,35,20,35));
add(usernamelab,1,1);
add(userNameField,2,1);
add(passwordLabel,1,2);
add(passwordField,2,2);
loginDialog.getDialogPane().setContent(网格);
loginDialog.getDialogPane().getButtonTypes().add(ButtonType.OK);
loginDialog.getDialogPane().getButtonTypes().add(ButtonType.CANCEL);
按钮连接按钮=(按钮)loginDialog.getDialogPane().lookupButton(按钮类型.确定);
connectButton.setText(“连接”);
connectButton.addEventFilter(ActionEvent.ACTION,事件->{
//在此处执行登录
loginDialog.hide();
primaryStage.show();
event.consume();
});
按钮exitButton=(按钮)loginDialog.getDialogPane().lookupButton(按钮类型.取消);
setText(“退出”);
exitButton.addEventFilter(ActionEvent.ACTION,event->{
handleExit();
event.consume();
});
Stage Stage=(Stage)loginDialog.getDialogPane().getScene().getWindow();
stage.setOnCloseRequest(事件->{
handleExit();
event.consume();
});
stage.show();
}
私有void handleExit(){
警报警报=新警报(AlertType.CONFIRMATION,“,ButtonType.YES,ButtonType.NO);
警报。setHeaderText(“确认退出?”);
alert.resultProperty().addListener((可观察、先前、当前)->{
如果(当前==按钮类型。是){
系统出口(1);
}
});
alert.show();
}
}

看看这是否有区别:

private void handleExit() {
    Alert alert = new Alert(AlertType.CONFIRMATION, "", ButtonType.YES, ButtonType.NO);
    alert.setHeaderText("Confirm exit?");

    Optional<ButtonType> result = alert.showAndWait();
    if(result.get() == ButtonType.YES)
    {
         Platform.exit();
    }

    alert.show();
}
private void handleExit(){
警报警报=新警报(AlertType.CONFIRMATION,“,ButtonType.YES,ButtonType.NO);
警报。setHeaderText(“确认退出?”);
可选结果=alert.showAndWait();
if(result.get()==ButtonType.YES)
{
Platform.exit();
}
alert.show();
}

看看这是否有区别:

private void handleExit() {
    Alert alert = new Alert(AlertType.CONFIRMATION, "", ButtonType.YES, ButtonType.NO);
    alert.setHeaderText("Confirm exit?");

    Optional<ButtonType> result = alert.showAndWait();
    if(result.get() == ButtonType.YES)
    {
         Platform.exit();
    }

    alert.show();
}
private void handleExit(){
警报警报=新警报(AlertType.CONFIRMATION,“,ButtonType.YES,ButtonType.NO);
警报。setHeaderText(“确认退出?”);
可选结果=alert.showAndWait();
if(result.get()==ButtonType.YES)
{
Platform.exit();
}
alert.show();
}

上面的代码对我来说很好。“退出”按钮仅显示确认对话框,仅此而已。当我按下“退出”键时,确认警报显示,然后立即关闭。我没有遇到这种情况。很奇怪。。。你确定你正在运行上面的代码吗?你的jdk版本是什么?我正在使用JFK1.8。我刚刚尝试了你的代码,它对我也很有效。上面的代码对我来说很好。“退出”按钮仅显示确认对话框,仅此而已。当我按下“退出”键时,确认警报显示,然后立即关闭。我没有遇到这种情况。很奇怪。。。你确定你正在运行上面的代码吗?你的jdk版本是什么?我正在使用JFK1.8。我刚刚尝试了你的代码,它对我也很有效。我用你的handleExit()方法替换了我的handleExit()。现在发生的是:当我按下并释放ESC键时,确认警报将出现、消失,然后再次出现;在alert.show()之前。然后,当应用程序运行时,我按下并释放登录对话框上的ESC按钮。“XX”已经打印出来了!这意味着alert.showAndWait()根本不会阻塞!很奇怪!你肯定有点奇怪。我会更新Java和我的IDE。我的JDK版本是1.8.0_66。我用的是Eclips