javafx KeyEvent触发两次
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javafx KeyEvent触发两次相关的知识,希望对你有一定的参考价值。
我在使用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>
按Enter键时打印两次。在插入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 Line的输出
Key Code:ENTER Target:TextField[id=textField, styleClass=text-input text-field]
@James_D最初我没有,但经过一些环顾四周,我认为它与预设的setOnAction命令有关,描述是“与此文本字段关联的动作处理程序,如果没有分配动作处理程序,则为null。动作处理程序通常是当用户键入ENTER键时调用。“因此,当您将.setOnAction
更改为使用或不更改时,它会阻止此错误,我认为这是因为它不再将enter命令踢到anchorPane周围。现在关于为什么KeyEvent.KEY_RELEASED
工作,我认为这是因为每次按下输入键只能释放一次,而不是可以多次发送命令的按键。这是完全的猜测,因为我不知道我在说什么,如果你能弄清楚为什么我想知道实际的推理。这应该是一个评论,但很长。
我遇到过同样的问题。每个键都会触发一次EventFilter,除了ENTER,它会触发两次。
更简单和优雅的解决方案是简单地将e.consume()
添加到您的块中,以响应进入EventFilter。
if(e.getCode().toString().equals("ENTER")){
e.consume();
}
以上是关于javafx KeyEvent触发两次的主要内容,如果未能解决你的问题,请参考以下文章
什么触发(或生成)KeyEvent.ACTION_MULTIPLE?