【发布时间】:2021-09-19 17:16:47
【问题描述】:
我正在尝试在 JavaFX 中重现 JavaScript 游戏的某些行为。该程序有几个数字文本字段,可以在游戏运行时进行编辑。它还在运行时接受字母键盘命令。
在我的版本中,我尝试捕获、响应和删除键盘命令,即使其中一个数字文本字段被聚焦。我认为使用EventFilter 应该可以工作——在处理事件的捕获阶段,在键盘事件到达TextFields 之前使用它们。但到目前为止,我还无法阻止字母键盘输入到达文本字段。
这是一个 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()ed 之后也是如此。
在调用consume() 之后,isConsumed() 方法确认事件被正确标记为已消费,但调度链没有像documentation 指示的那样短路。
我已尝试将事件过滤器添加到路径中的其他 Nodes 到文本字段,但行为没有变化。我已经尝试过滤KeyEvent.ANY、KeyEvent.KEY_TYPED 和KeyEvent.KEY_RELEASED 而不改变行为。我已经看到这个similar question 的答案提出了类似于我正在尝试的内容。
我是否误解了这应该如何工作?
由于实际程序中的所有TextFields 都附加了TextFormatters,我想我可以在格式化程序中添加一个过滤功能来拒绝键盘命令字符。不过,这似乎是一种迂回的做法。
macOS、Java 17、JavaFX 17,如果这有什么不同的话。
【问题讨论】:
-
这听起来像是一个用例,您应该使用
TextFormatter而不是EventFilter。由于我使用EventFilter和TextFormatter的经验有限,我可能会错。 -
这是我尝试找出使用哪一个时的思路。如果您要对
TextField中的文本进行任何操作,请使用TextFormatter。如果不是,请使用EventFilter。这是一个很好的例子:courses.bekwam.net/public_tutorials/bkcourse_visualcueapp.html. -
使用过滤器中输入的内容
-
.. 澄清我的夜间评论:代码显示'S'字符被正确检测,但它们仍然显示在文本字段中难怪,它被插入通过 keyTyped (与您使用的 keyPressed 相比)。解决方案是在过滤器中使用keyTyped。
-
@kleopatra,谢谢。在你的帮助下,我想出了一个有效的过滤器。