检测JavaFX中的单键按下
作者:互联网
我在检测JavaFX中的单个按键时遇到问题.我必须检测箭头键,但是每次按下这些键中的任何一个,代码的一部分都会被多次调用.我意识到这是因为AnimationTimer()是一个循环,因此这就是原因,但是我不知道如何检测单键点击.无论如何,这是代码:
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import java.util.HashSet;
public class Main extends Application {
Stage window;
static Scene scene;
private static char[][] mapa = {
{'X','X','X','X','X'},
{'X','.','.','.','X'},
{'X','.','M','.','X'},
{'X','.','.','.','X'},
{'X','X','X','X','X'}
};
private final int sizeX = 16;
private final int sizeY = 16;
static HashSet<String> currentlyActiveKeys;
@Override
public void start(Stage primaryStage) throws Exception {
window = primaryStage;
window.setTitle("Hello World");
Group root = new Group();
scene = new Scene(root);
window.setScene(scene);
Canvas canvas = new Canvas(512 - 64, 256);
root.getChildren().add(canvas);
prepareActionHandlers();
GraphicsContext gc = canvas.getGraphicsContext2D();
new AnimationTimer() {
@Override
public void handle(long now) {
gc.clearRect(0,0,512,512);
for(int i = 0; i < mapa.length; i++) {
for(int j = 0; j < mapa[i].length; j++) {
if(mapa[i][j] == 'X') {
gc.setLineWidth(5);
gc.setFill(Color.RED);
gc.fillRect(sizeX + i*sizeX, sizeY + j*sizeY, sizeX, sizeY);
} else if(mapa[i][j] == '.') {
gc.setLineWidth(5);
gc.setFill(Color.GREEN);
gc.fillRect(sizeX + i*sizeX, sizeY + j*sizeY, sizeX, sizeY);
} else if(mapa[i][j] == 'M') {
gc.setLineWidth(5);
gc.setFill(Color.BLACK);
gc.fillRect(sizeX + i*sizeX, sizeY + j*sizeY, sizeX, sizeY);
}
}
}
if(currentlyActiveKeys.contains("LEFT")) {
System.out.println("left");
}
if(currentlyActiveKeys.contains("RIGHT")) {
System.out.println("right");
}
if(currentlyActiveKeys.contains("UP")) {
System.out.println("up");
}
if(currentlyActiveKeys.contains("DOWN")) {
System.out.println("down");
}
}
}.start();
window.show();
}
private static void prepareActionHandlers()
{
currentlyActiveKeys = new HashSet<String>();
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event)
{
currentlyActiveKeys.add(event.getCode().toString());
}
});
scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event)
{
currentlyActiveKeys.remove(event.getCode().toString());
}
});
}
public static void main(String[] args) {
launch(args);
}
}
当我按下箭头按钮(当然,与其他键相同)时,在范围内,我得到的结果如下:
down
down
down
down
down
down
显然,只要我按下按钮,就会发生这种情况.一旦我停止按它,打印就结束了.我想实现的是,一旦我按下一个按钮(无论按住多长时间),我都会下一次.我需要这样做是因为我想更新画布中矩形的颜色.
解决方法:
所发生的是,该操作系统具有一种自动键入功能,因此,即使您确实没有多次按下按键,当您按住某个按键时,它仍会继续生成按键事件.
通过添加按键和按键释放处理程序以及每个按键的布尔状态,您可以跟踪自按键被按下以来是否已处理过.然后,无论何时释放键,您都可以重置该已处理状态,以便下次真正按下该键时可以进行处理.
样品申请
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.util.HashMap;
public class Main extends Application {
private HashMap<String, Boolean> currentlyActiveKeys = new HashMap<>();
@Override
public void start(Stage stage) throws Exception {
final Scene scene = new Scene(new Group(), 100, 100);
stage.setScene(scene);
scene.setOnKeyPressed(event -> {
String codeString = event.getCode().toString();
if (!currentlyActiveKeys.containsKey(codeString)) {
currentlyActiveKeys.put(codeString, true);
}
});
scene.setOnKeyReleased(event ->
currentlyActiveKeys.remove(event.getCode().toString())
);
new AnimationTimer() {
@Override
public void handle(long now) {
if (removeActiveKey("LEFT")) {
System.out.println("left");
}
if (removeActiveKey("RIGHT")) {
System.out.println("right");
}
if (removeActiveKey("UP")) {
System.out.println("up");
}
if (removeActiveKey("DOWN")) {
System.out.println("down");
}
}
}.start();
stage.show();
}
private boolean removeActiveKey(String codeString) {
Boolean isActive = currentlyActiveKeys.get(codeString);
if (isActive != null && isActive) {
currentlyActiveKeys.put(codeString, false);
return true;
} else {
return false;
}
}
public static void main(String[] args) {
launch(args);
}
}
标签:javafx,keyboard-events,java 来源: https://codeday.me/bug/20191027/1941040.html