我正在尝试在 JavaFX 中重现 JavaScript 游戏的某些行为。该程序有几个数字文本字段,可以在游戏运行时进行编辑。它还在运行时接受字母键盘命令。
在我的版本中,即使聚焦数字文本字段之一,我也会 try catch 、响应和删除键盘命令。我想使用 EventFilter
应该可以工作——在键盘事件到达 TextField
之前消耗它们s 在处理事件的捕获阶段。但到目前为止,我还无法阻止字母键盘输入到达文本字段。
这是一个 SSCCE,它说明了我尝试过的方法和不起作用的方法。
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class KeyFilterSSCCE extends Application {
@Override
public void start(Stage stage) {
stage.setTitle("Key Filter SSCCE");
TextField tf = new TextField("XYZ abc");
tf.setMaxWidth(150);
Label label = new Label("Filtered Keys: ");
VBox root = new VBox(20, tf, label);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(20));
Scene scene = new Scene(root, 325, 200);
stage.addEventFilter(KeyEvent.KEY_PRESSED, e -> {
if (e.getCode() == KeyCode.S) {
label.setText(label.getText() + e.getCode().getChar());
e.consume();
}
});
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
该程序应该让您在文本字段中键入内容并在将“S”字符输入到该字段之前捕获并删除它们。代码显示 'S' 字符被正确检测到,但它们仍然显示在文本字段中,即使在 consume()
之后也是如此。编。调用后
consume()
, isConsumed()
方法确认事件被正确标记为已消费,但调度链没有像 documentation 那样短路表示。我试过将事件过滤器添加到其他
Node
s 在指向文本字段的路径中,行为没有变化。我试过过滤 KeyEvent.ANY
, KeyEvent.KEY_TYPED
, 和 KeyEvent.KEY_RELEASED
没有和改变行为。我见过这个 similar question有一个答案,提出了类似我正在尝试的东西。我误解了这应该如何工作吗?
由于所有
TextField
真实程序中的s已附TextFormatter
s,我想我可以向格式化程序添加过滤器功能以拒绝键盘命令字符。不过,这似乎是一种迂回的做法。macOS、Java 17、JavaFX 17,如果这有什么不同的话。
最佳答案
在@kleopatras 评论和更多实验之后,这里是一个按预期运行的事件过滤器版本:
stage.addEventFilter(KeyEvent.KEY_TYPED, e -> {
if (e.getCharacter().toUpperCase().equals("S")) {
label.setText(label.getText() + e.getCharacter());
e.consume();
}
});
过滤 KeyEvent.KEY_TYPED
事件是我需要的。另外,自事件getCode()
该事件的方法返回 UNDEFINED
,必须稍微修改测试以针对 getCharacter()
的结果进行测试。 ,奇怪的是,它返回一个 String
.
关于JavaFX KeyEvent.consume() 无法停止事件传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69245463/