我在使用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之前,工作正常。
答案 0 :(得分:1)
我有同样的问题。每个键都会触发一次EventFilter,除了ENTER,它会触发两次。
更简单和优雅的解决方案是简单地将e.consume()
添加到您的块中,以响应进入EventFilter。
if(e.getCode().toString().equals("ENTER")){
e.consume();
}
答案 1 :(得分:0)
更改此行
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命令有关,描述是&#34;与此文本字段关联的动作处理程序,如果没有分配动作处理程序,则为null 。通常在用户键入ENTER键时调用操作处理程序。&#34;因此,当您将.setOnAction
更改为使用或不更改时,它会阻止此错误,我认为这是因为它不再将enter命令踢到anchorPane周围。现在关于为什么KeyEvent.KEY_RELEASED
有效,我认为这是因为每次按下输入键只能释放一次,而不是可以多次发送命令的按键。这是完全的猜测,因为我不知道我在说什么,如果你能弄清楚为什么我想知道实际的推理。这应该是一个评论,但很长。