JavaFX:禁用键盘控制RadioButtons

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaFX:禁用键盘控制RadioButtons相关的知识,希望对你有一定的参考价值。

我开始使用JavaFX了,我已经构建了一个小的俄罗斯方块游戏。现在一切正常,但最后我决定添加一组radiobuttons来选择难度 - 这里我遇到了一个问题:突然左/右/上/下键只切换单选按钮而不控制游戏玩法更多。

为了处理游戏玩法,我在场景中添加了一个按键事件监听器:

public void setKeyEventHandler() {
    game.getScene().setOnKeyPressed(Field::handleKeyEvent);
}

private static void handleKeyEvent(KeyEvent event) {
    // ... handle the event to move the figure
}

但正如我所说,由于我添加了收音机按钮,因此不再执行。有没有办法禁用键盘键更改单选按钮,并使它们只能通过鼠标点击更改?我是否需要以某种方式消除它们的焦点?但是怎么样?

编辑:也许我应该补充一点,我只是使用setOnAction()函数处理单选按钮的事件,例如:

classicModeButton.setOnAction((e) -> interestingMode = false); 
interestingModeButton.setOnAction((e) -> interestingMode = true);
答案

第一种方法:

你可以制作你的RadioButtons not focusable

通过此更改,箭头键的默认键侦听器将不再更改无线电的状态,因为它们不会聚焦(即使由鼠标选择):

classicModeButton.setFocusTraversable(false);
interestingModeButton.setFocusTraversable(false);

这只有在Node上没有其他可聚焦的Scenes时才有效,否则它们会在屏幕的事件处理程序处理之前处理键事件。如果您有其他节点,请检查第二种方法。

一个示例代码段:

// Init the variables
BooleanProperty interestingMode = new SimpleBooleanProperty(false);
RadioButton classicModeButton = new RadioButton("Classic");
RadioButton interestingModeButton = new RadioButton("Interesting");
ToggleGroup tg = new ToggleGroup();

classicModeButton.setToggleGroup(tg);
interestingModeButton.setToggleGroup(tg);
tg.selectToggle(classicModeButton);

// The radios should be not focusable
classicModeButton.setFocusTraversable(false);
interestingModeButton.setFocusTraversable(false);

// On toggle-change, the mode will be changed
interestingMode.bind(tg.selectedToggleProperty().isEqualTo(interestingModeButton));

// Just print the changes
tg.selectedToggleProperty().addListener((observable, oldValue, newValue) ->
        System.out.println((newValue == interestingModeButton) ? "Hmm, interesting" : "Classic .. boring"));

scene.setOnKeyPressed(e -> 
        System.out.println((e.getCode().isArrowKey()) ? "Arrow pressed!" : "Other pressed, I don't care!"));

第二种方法:

您可以通过向event filterScene添加consume the event而不是事件处理程序来处理键事件。这将捕获已经处于捕获阶段的事件(而不是冒泡阶段),因此该事件甚至不会达到您的(可聚焦的)Nodes:

scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
    System.out.println((event.getCode().isArrowKey()) ? "Arrow pressed!" : "Other pressed, I don't care!");
    event.consume();
});

有了这个,所有按键事件都被捕获,但当然可以“让一些事件”通过。

有关事件如何传递的更多信息可以在(例如)here找到。

另一答案

我之前从未处理过这种情况,所以我只是在这里吐出一个想法,但也许你可以为javafx.scene.input.KeyEvent实现一个处理程序。

在你的处理程序中,你可能会说:

if(event.getCode().isNavigationKey()){
    // Some navigation key was pressed
    event.consume(); // prevent further propagation 
    yourGamesControlElement.requestFocus(); // transfer focus
    handleKeyMovementInGame(event.getCode()); // handle the action
}

这种检测方法的一个好处是isNavigationKey()将为您处理所有键码检查,包括检查常规箭头键和数字键盘箭头键。

我还建议查看this GitHub Gist,它讨论了使用KeyEvents来阻止JavaFX在按下Tab键时转移焦点,以及JavaFX KeyCode documentation用于一些其他想法和实现细节。

以上是关于JavaFX:禁用键盘控制RadioButtons的主要内容,如果未能解决你的问题,请参考以下文章

Void用户检查单选按钮而不禁用它

GroupBox 与 radioButtons 启用另一个 groupBox 不保持按钮状态

JavaFX:初始化 RadioButton 选择状态

如何禁用键盘某个键?

从对话框控制器[javaFX]中访问OK按钮

如何在对话框中将事件侦听器绑定到JavaFX TextFields。当字段为空时,“确定”按钮将被禁用,反之亦然