在Javafx中输入关键事件不能正常工作?

时间:2016-02-17 13:30:03

标签: javafx javafx-2 javafx-8

我已经尝试了下面的代码,它可以正常使用鼠标事件,但是当我在任何按钮上使用按键事件,即ENTER键而不是显示结果时。

Angular2

4 个答案:

答案 0 :(得分:8)

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

通常情况下,当您按 space 而不是输入时,会触发具有焦点的按钮。但是有一些特殊的按钮会在特定键上激活:{k}将在上输入,而default button将在 esc 上触发。通常,对话框中只有一种特殊类型的按钮,因此无论当前哪个按钮具有焦点,都可以通过特殊键盘加速器触发它们。

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

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

ButtonType buttonTypeTwo = new ButtonType(
    "Two",
    ButtonBar.ButtonData.OK_DONE
);
ButtonType buttonTypeThree = new ButtonType(
    "Three",
    ButtonBar.ButtonData.CANCEL_CLOSE
);

请注意,JavaFX系统已自动更改按钮的位置和一些颜色突出显示。当用户按输入时,然后"两个"当用户按 esc ,然后"三"会发射。如果您在Windows或Linux上运行相同的代码,根据用于这些操作系统的任何按钮定位标准,按钮的位置可能会不同。

cancel button

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

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

enter image description here

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

我还建议在JavaFX Alert中至少设置一个CANCEL_CLOSE按钮或OK_DONE按钮,否则用户可能很难实际关闭警报,因为对话框可能无法响应用户期望的按键操作。

答案 1 :(得分:1)

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

 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();
[...]

您只需创建一些按钮并在警报上为其指定实际按钮。在下一步中,你可以给每个按钮一个EventHandler,它只是(在这个例子中)检查 - 当任何键被释放时 - 如果键是ENTER并设置结果。

我想有更好的解决方案。但这是我目前最容易想到的方式。希望它能帮到你。

答案 2 :(得分:0)

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

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;
    }

答案 3 :(得分:0)

您无需设置默认方法,无论您要在哪个按钮上输入键

'h