【发布时间】:2016-09-25 03:10:00
【问题描述】:
我在检测 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
显然,只要我按下按钮,就会发生这种情况。一旦我停止按下它,打印就会结束。我希望实现的是,一旦我按下一个按钮(无论我按住它多长时间),我只会得到一次down。我需要这个,因为我想更新canvas 中矩形的颜色。
【问题讨论】:
-
这个related question 可能有帮助(也可能没有)。我的猜测是你正在尝试做一些不同的事情。
-
@jewelsea 我正在编辑代码并粘贴了错误的版本。现在有
setOnKeyPressed -
@jewelsea 按下箭头时英雄不断移动。在我的示例中,即使我按住键,我也想成为英雄只是迈出一步。这是行不通的。按住按钮时,我得到了多张照片。
-
是的,我做到了。它没有帮助。这是因为在下一个
AnimationTimer循环中,当您按下按钮时,它将再次从setOnKeyPressed添加到Set
标签: java javafx keyboard-events