我开始使用JavaFX并且我已经构建了一个小的俄罗斯方块游戏。现在一切正常,但最后我决定添加一组radiobuttons来选择难度 - 这里我遇到了一个问题: 突然 LEFT / RIGHT / UP / DOWN 键只切换单选按钮而不控制游戏玩法更多。
为了处理游戏玩法,我在场景中添加了按键事件监听器:
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);
答案 0 :(得分:3)
第一种方法:
您可以制作RadioButton
s not focusable。
通过此更改,箭头键的默认键侦听器将不再更改无线电的状态,因为它们不会聚焦(即使由鼠标选择):
classicModeButton.setFocusTraversable(false);
interestingModeButton.setFocusTraversable(false);
如果您在Node
上没有其他可关注的Scene
,这只会有效,否则他们会在关键事件发生之前处理由屏幕的事件处理程序处理。如果您有其他节点,请检查第二种方法。
示例摘录:
// 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!"));
第二种方法:
您可以通过向Scene
和event filter添加consume the event而不是事件处理程序来处理密钥事件。这将捕获已经处于捕获阶段的事件(而不是冒泡阶段),因此事件甚至不会到达您的(可聚焦的)Node
:
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
System.out.println((event.getCode().isArrowKey()) ? "Arrow pressed!" : "Other pressed, I don't care!");
event.consume();
});
通过这一切,所有按下按键的事件都被捕获,但当然可以“让某些事件发生。”#34;通过。
可以找到有关如何传递事件的更多信息(例如)here。
答案 1 :(得分:1)
我之前从未处理过这种情况,所以我只是在这里吐出一个想法,但也许你可以为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以获得一些额外的想法和实现细节。