JavaFX KeyEvent.consume() 无法停止事件传播

标签 java javafx

我正在尝试在 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/

相关文章:

JavaFX - 不同类型的表列列表

java - 哪些 Web 框架可以在 Google 应用引擎上成功使用? Struts/Spring 怎么样?

java - 即使使用 X 按钮取消或关闭打印对话框,文档仍在打印?

java - Docker 中的 OOM,带有 Spring Boot + H2 + JPA 和批处理

java - 如何在 JavaFX 中对任务进行排队?

java - 在动态 TableView 中编辑单元格值?

java - 如何在JavaFX/ScalaFX中实现可滚动、可缩放的 map ?

webview - JavaFX WebView 在重新加载时重新创建窗口

java - 如何调试 JBossESB?

java - 十进制格式的模式