javafx KeyEvent 触发两次
javafx KeyEvent triggers twice
我在使用 KeyEvent 的项目中遇到了一些问题。按下 Enter 键时将值从一个值切换到另一个值的组合框。
经过一些尝试,问题显示是 Enter 键生成了 2 次事件,因此组合框显然没有改变。
然后,我尝试用这个片段做一个简单的测试项目:
window.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if(event.getCode().equals(KeyCode.ENTER))
System.out.println("print");
}
});
程序每次输入都会打印两次。 KeyCode.ENTER 是否可能指的是多个键或类似的东西?
如果我将 KeyCode.ENTER 更改为其他内容(尝试使用 SPACE 或某些字母),它会正常工作。
可以做些什么来解决这个问题吗?
我用 3 个文件做了一个简单的项目:
主要
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class Main extends Application {
private static Stage window;
@Override
public void start(Stage primaryStage) throws Exception{
window = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static Stage getWindow(){return window;}
public static void main(String[] args) {
launch(args);
}
}
控制器:
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
@FXML
TextField textField;
Stage window;
@Override
public void initialize(URL location, ResourceBundle resources) {
window = Main.getWindow();
window.addEventFilter(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if (event.getCode().equals(KeyCode.ENTER))
System.out.println("print");
}
});
}
}
样本:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity"
prefHeight="400.0" prefWidth="600.0"
fx:controller="Controller"
xmlns="http://javafx.com/javafx/8.0.121"
xmlns:fx="http://javafx.com/fxml/1">
<children>
<TextField fx:id="textField" layoutX="14.0" layoutY="14.0" />
</children>
</AnchorPane>
按回车键打印两次。在插入 TextField 之前按预期工作。
更改此行
window.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
到
window.addEventFilter(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
编辑@James_D
的代码
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
@FXML
TextField textField;
Stage window;
@Override
public void initialize(URL location, ResourceBundle resources) {
window = Main.getWindow();
window.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
System.out.println("Key Code:"+event.getCode()+" Target:"+event.getTarget());
});
// textField.setOnAction(event -> {});
}
}
运行时你会得到
的输出
Key Code:ENTER Target:TextField[id=textField, styleClass=text-input text-field]
Key Code:ENTER Target:AnchorPane@7a78d90b[styleClass=root]
如果取消对 textField 行的注释,输出为
Key Code:ENTER Target:TextField[id=textField, styleClass=text-input text-field]
@James_D 最初我没有,但经过一番环顾后,我认为它与预设的 setOnAction 命令有关,描述是 "The action handler associated with this text field, or null if no action handler is assigned. The action handler is normally called when the user types the ENTER key." 所以当你更改 .setOnAction
消耗或什么都不消耗它可以防止这个错误,我认为这是因为它不再将输入命令踢出到 anchorPane 周围。现在至于为什么 KeyEvent.KEY_RELEASED
起作用,我认为这是因为每次按下回车键只能释放一次,而不是可以多次发送命令的按下。这完全是猜测,因为我没有证据证明我在说什么,如果你能找出一个更合理的解释,为什么我很想知道。这应该是一条评论,但变得很长。
我遇到了同样的问题。每个键都会触发 EventFilter 一次,除了 ENTER 会触发它两次。
一个更简单优雅的解决方案是简单地将 e.consume()
添加到响应进入 EventFilter 的块中。
if(e.getCode().toString().equals("ENTER")){
e.consume();
}
我在使用 KeyEvent 的项目中遇到了一些问题。按下 Enter 键时将值从一个值切换到另一个值的组合框。
经过一些尝试,问题显示是 Enter 键生成了 2 次事件,因此组合框显然没有改变。
然后,我尝试用这个片段做一个简单的测试项目:
window.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if(event.getCode().equals(KeyCode.ENTER))
System.out.println("print");
}
});
程序每次输入都会打印两次。 KeyCode.ENTER 是否可能指的是多个键或类似的东西? 如果我将 KeyCode.ENTER 更改为其他内容(尝试使用 SPACE 或某些字母),它会正常工作。 可以做些什么来解决这个问题吗?
我用 3 个文件做了一个简单的项目:
主要
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class Main extends Application {
private static Stage window;
@Override
public void start(Stage primaryStage) throws Exception{
window = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static Stage getWindow(){return window;}
public static void main(String[] args) {
launch(args);
}
}
控制器:
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
@FXML
TextField textField;
Stage window;
@Override
public void initialize(URL location, ResourceBundle resources) {
window = Main.getWindow();
window.addEventFilter(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if (event.getCode().equals(KeyCode.ENTER))
System.out.println("print");
}
});
}
}
样本:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity"
prefHeight="400.0" prefWidth="600.0"
fx:controller="Controller"
xmlns="http://javafx.com/javafx/8.0.121"
xmlns:fx="http://javafx.com/fxml/1">
<children>
<TextField fx:id="textField" layoutX="14.0" layoutY="14.0" />
</children>
</AnchorPane>
按回车键打印两次。在插入 TextField 之前按预期工作。
更改此行
window.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
到
window.addEventFilter(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
编辑@James_D
的代码import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
@FXML
TextField textField;
Stage window;
@Override
public void initialize(URL location, ResourceBundle resources) {
window = Main.getWindow();
window.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
System.out.println("Key Code:"+event.getCode()+" Target:"+event.getTarget());
});
// textField.setOnAction(event -> {});
}
}
运行时你会得到
的输出Key Code:ENTER Target:TextField[id=textField, styleClass=text-input text-field]
Key Code:ENTER Target:AnchorPane@7a78d90b[styleClass=root]
如果取消对 textField 行的注释,输出为
Key Code:ENTER Target:TextField[id=textField, styleClass=text-input text-field]
@James_D 最初我没有,但经过一番环顾后,我认为它与预设的 setOnAction 命令有关,描述是 "The action handler associated with this text field, or null if no action handler is assigned. The action handler is normally called when the user types the ENTER key." 所以当你更改 .setOnAction
消耗或什么都不消耗它可以防止这个错误,我认为这是因为它不再将输入命令踢出到 anchorPane 周围。现在至于为什么 KeyEvent.KEY_RELEASED
起作用,我认为这是因为每次按下回车键只能释放一次,而不是可以多次发送命令的按下。这完全是猜测,因为我没有证据证明我在说什么,如果你能找出一个更合理的解释,为什么我很想知道。这应该是一条评论,但变得很长。
我遇到了同样的问题。每个键都会触发 EventFilter 一次,除了 ENTER 会触发它两次。
一个更简单优雅的解决方案是简单地将 e.consume()
添加到响应进入 EventFilter 的块中。
if(e.getCode().toString().equals("ENTER")){
e.consume();
}