输入键事件在Javafx中的对话框上不起作用?

输入键事件在Javafx中的对话框上不起作用?,javafx,javafx-2,javafx-8,Javafx,Javafx 2,Javafx 8,我已经尝试了下面的代码,它可以很好地处理鼠标事件,但当我在任何按钮上使用键事件(即输入键)时,它不会显示结果 Alert alert = new Alert(AlertType.CONFIRMATION); alert.setTitle(null); alert.setHeaderText(null); alert.setGraphic(null); alert.setContentText("Choose your option."); ButtonType buttonTypeOne =

我已经尝试了下面的代码,它可以很好地处理鼠标事件,但当我在任何按钮上使用键事件(即输入键)时,它不会显示结果

Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle(null);
alert.setHeaderText(null);
alert.setGraphic(null);
alert.setContentText("Choose your option.");

ButtonType buttonTypeOne = new ButtonType("One");
ButtonType buttonTypeTwo = new ButtonType("Two");
ButtonType buttonTypeThree = new ButtonType("Three");

alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree);

Optional<ButtonType> result = alert.showAndWait();
if (result.get() == buttonTypeOne) {
     System.out.println("One");
} else if (result.get() == buttonTypeTwo) {
     System.out.println("Two");
} else if (result.get() == buttonTypeThree) {
     System.out.println("Three");
}
Alert-Alert=新警报(AlertType.CONFIRMATION);
alert.setTitle(空);
alert.setHeaderText(空);
alert.setGraphic(空);
setContentText(“选择您的选项”);
ButtonType buttonTypeOne=新的ButtonType(“一”);
ButtonType ButtonTypeWO=新的ButtonType(“两个”);
ButtonType buttonTypeThree=新的ButtonType(“三”);
alert.getButtonTypes().setAll(buttonTypeOne、buttonTypeTwo、buttonTypeThree);
可选结果=alert.showAndWait();
if(result.get()==buttonTypeOne){
系统输出打印项次(“一”);
}else if(result.get()==buttonypetwo){
System.out.println(“两个”);
}else if(result.get()==buttonypethree){
System.out.println(“三”);
}

我不知道这是否是一种太多的解决方法,但至少它是有效的:

 import javafx.event.EventHandler;
 import javafx.scene.control.Button;
 import javafx.scene.input.KeyCode;
 import javafx.scene.input.KeyEvent;

     [...]
ButtonType buttonTypeTwo = new ButtonType("Two");
ButtonType buttonTypeThree = new ButtonType("Three");

alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree);

//Create a button for every ButtonType you add to your alert and give it a Eventhandler 
Button button1 = (Button) alert.getDialogPane().lookupButton(buttonTypeOne);
Button button2 = (Button) alert.getDialogPane().lookupButton(buttonTypeTwo);
Button button3 = (Button) alert.getDialogPane().lookupButton(buttonTypeThree);


button1.setOnKeyReleased(new EventHandler<KeyEvent>() {
    @Override
    public void handle(KeyEvent event) {
        if(event.getCode() == KeyCode.ENTER)
    alert.setResult(buttonTypeOne);     
    }
});
button2.setOnKeyReleased(new EventHandler<KeyEvent>() {
    @Override
    public void handle(KeyEvent event) {
        if(event.getCode() == KeyCode.ENTER)
    alert.setResult(buttonTypeTwo);     
    }
});
button3.setOnKeyReleased(new EventHandler<KeyEvent>() {
    @Override
    public void handle(KeyEvent event) {
        if(event.getCode() == KeyCode.ENTER)
    alert.setResult(buttonTypeThree);       
    }
});
 //go ahead with your code
Optional<ButtonType> result = alert.showAndWait();
[...]
导入javafx.event.EventHandler;
导入javafx.scene.control.Button;
导入javafx.scene.input.KeyCode;
导入javafx.scene.input.KeyEvent;
[...]
ButtonType ButtonTypeWO=新的ButtonType(“两个”);
ButtonType buttonTypeThree=新的ButtonType(“三”);
alert.getButtonTypes().setAll(buttonTypeOne、buttonTypeTwo、buttonTypeThree);
//为添加到警报中的每个按钮类型创建一个按钮,并为其提供一个Eventhandler
Button button1=(按钮)alert.getDialogPane().lookupButton(按钮);
Button button2=(按钮)alert.getDialogPane().lookupButton(按钮类型为two);
Button button3=(Button)alert.getDialogPane().lookupButton(buttonTypeThree);
button1.setOnKeyReleased(新的EventHandler(){
@凌驾
公共无效句柄(KeyEvent事件){
if(event.getCode()==KeyCode.ENTER)
警报。设置结果(按钮);
}
});
button2.setOnKeyReleased(新的EventHandler(){
@凌驾
公共无效句柄(KeyEvent事件){
if(event.getCode()==KeyCode.ENTER)
警报.setResult(buttonTypeTwo);
}
});
button3.setOnKeyReleased(新的EventHandler(){
@凌驾
公共无效句柄(KeyEvent事件){
if(event.getCode()==KeyCode.ENTER)
警报。设置结果(按钮三);
}
});
//继续你的代码
可选结果=alert.showAndWait();
[...]
您只需创建一些按钮,并为它们指定警报上的实际按钮。在下一步中,您可以为每个按钮提供一个EventHandler,它(在本例中)在释放任何键时检查键是否已输入并设置结果


我想有更好的解决办法。但这是我现在想到的最简单的方法。希望对你有帮助

我不建议让所有按钮都响应enter,因为这与大多数UI对话框的工作方式相反

通常,当您按空格键而不是回车键时,会触发带焦点的按钮。但是,有一些特殊的按钮将在特定的按键上激活:A将在回车时启动,A将在esc时启动。通常情况下,对话框中只有这些特殊类型的按钮中的一个,因此无论当前哪个按钮具有焦点,都可以通过特殊的键盘加速器触发这些按钮

此外,不同的桌面操作系统在对话框系统中放置默认和取消按钮时有不同的标准。这是为了帮助用户在任何对话框中轻松找到这些特殊按钮。JavaFX对话框系统在内部实现了一些逻辑,用于定位对话框中的按钮,用户希望在不同的桌面操作系统中看到这些按钮

假设您希望将示例中的按钮类型定义为默认按钮或取消按钮,并将其放置在操作系统中此类按钮的正确位置,那么您可以执行以下操作:

ButtonType buttonTypeTwo = new ButtonType(
    "Two",
    ButtonBar.ButtonData.OK_DONE
);
ButtonType buttonTypeThree = new ButtonType(
    "Three",
    ButtonBar.ButtonData.CANCEL_CLOSE
);
注意JavaFX系统已经自动改变了按钮的位置和一些颜色高亮显示。当用户按enter键时,将触发“2”,当用户按esc键时,将触发“3”。如果在Windows或Linux上运行相同的代码,则根据这些操作系统使用的按钮定位标准,按钮的定位可能会有所不同

如果不希望JavaFX根据操作系统标准重新定位按钮,但希望它们仍然响应enter键和esc键,则可以查找按钮并直接修改按钮属性,如下所示:

Button buttonTwo = (Button) alert.getDialogPane().lookupButton(buttonTypeTwo);
buttonTwo.setDefaultButton(true);
Button buttonThree = (Button) alert.getDialogPane().lookupButton(buttonTypeThree);
buttonThree.setCancelButton(true);

我建议让JavaFX适当地定位特定类型的按钮,而不是像上面那样执行查找


我还建议在JavaFX警报中至少设置一个CANCEL\u CLOSE(取消关闭)按钮或OK\u DONE(确定完成)按钮,否则用户可能很难真正关闭警报,因为对话框可能不会像用户预期的那样对按键做出响应。

我是如何解决的。 它工作正常,下面是我的确认警报功能。

public static boolean confirmAlert(String title, String msg){

        ButtonType buttonTypeYes = new ButtonType("Yes", ButtonBar.ButtonData.OK_DONE);
        ButtonType buttonTypeNo = new ButtonType("No",ButtonBar.ButtonData.CANCEL_CLOSE);

        Alert alert = new Alert(Alert.AlertType.NONE, msg,buttonTypeNo,buttonTypeYes);
        alert.setTitle(title);

        Button button1 = (Button) alert.getDialogPane().lookupButton(buttonTypeYes);
        button1.setDefaultButton(false); //***set default to false***

        Button button2 = (Button) alert.getDialogPane().lookupButton(buttonTypeNo);

        button1.setOnKeyReleased(event -> {
            if(event.getCode() == KeyCode.ENTER)
                alert.setResult(buttonTypeYes);
        });
        button2.setOnKeyReleased(event -> {
            if(event.getCode() == KeyCode.ENTER)
                alert.setResult(buttonTypeNo);
        });
        alert.showAndWait();
        return alert.getResult()==buttonTypeYes;
    }

您不需要设置默认方法,您希望在哪个按钮上输入密钥

Alert confirmAlert = new Alert(Alert.AlertType.CONFIRMATION, "", ButtonType.YES, ButtonType.NO);
confirmAlert.setHeaderText("Are You Sure Want To Delete ?");
Button bt1 = (Button) confirmAlert.getDialogPane().lookupButton(ButtonType.YES);
Button bt2 = (Button) confirmAlert.getDialogPane().lookupButton(ButtonType.NO);
bt2.addEventHandler(KeyEvent.ANY,(event) -> {
    if(event.getCode() == KeyCode.ENTER){
    confirmAlert.setResult(ButtonType.NO);
      }
});
Optional <ButtonType> action = confirmAlert.showAndWait();
if(action.get() == ButtonType.NO){
          System.err.println("Action You Want");
}
Alert confirmAlert=新警报(Alert.AlertType.CONFIRMATION,”,ButtonType.YES,ButtonType.NO);
confirmAlert.setHeaderText(“确实要删除吗?”);
按钮bt1=(按钮)confirmAlert.getDialogPane().lookupButton(按钮类型.是);
按钮bt2=(按钮)confirmAlert.getDialogPane().lookupButton(按钮类型.否);
bt2.addEventHandler(KeyEvent.ANY,(事件)->{
if(event.getCode()==KeyCode.ENTER){
confirmAlert.setResult(按钮类型编号);
}
});
可选操作=confirmAlert.showAndWait();
if(action.get()==ButtonType.NO){
System.err.println(“您想要的操作”);
}

这是一个很有帮助的解释。