2023-02-17 393
我在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
显然,只要我按按钮,就会发生这种情况.一旦我停止按下它,打印就结束了.我想实现的目标是,一旦我按下按钮(无论我持有多长时间),我只会得到一次.我需要这个,因为我想在canvas中更新矩形的颜色.
发生的事情是,操作系统具有一种自动键入功能,因此当您按住钥匙时,它会继续生成密钥按下事件,即使您并没有真正按下键.
通过为每个键添加密钥按下和键发布处理程序和布尔态状态,您可以跟踪自按下键以来是否已经处理过该键.然后,您可以每当释放键时重置该处理状态
示例应用程序
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);
}
}
您可以声明全局布尔值,并像press =!press一样.然后每2秒钟将其重置为true或某种效果.
if(currentlyActiveKeys.contains("DOWN") && press) {
press = !press;//sets it false
System.out.println("down");
}
我知道这已经是一个长期的问题.我只是想分享我的发现几个小时的挣扎.我终于找到了一个简单的解决方案,即通过添加清晰的功能.这是我的意思
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");
}
currentlyActiveKeys.clear();
这最后一行将清除当前有效的密钥,因此它将阻止重复,如原始帖子
中所述
以上所述是小编给大家介绍的检测JavaFX中的单键按下,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/34135.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态