JavaFX fireEvent 堆栈溢出错误
JavaFX fireEvent StackOverflowError
我目前正在使用 JavaFX 开发一个小游戏,但在捕获 keyEvents 时遇到了一些问题。
现在我可以捕捉到它们了,但是程序抛出一个 java.lang.WhosebugError
并且在按下某个键时它没有按照我的预期进行。
这里是主要内容class:
public class WarbladeFX extends Application {
Game root;
public void start(Stage primaryStage) {
root = new Game();
Scene scene = new Scene(root, 800, 600);
scene.setFill(new Color(0,0,0,1));
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
public void handle(KeyEvent event) {
Event.fireEvent(root, event);
}
});
scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
public void handle(KeyEvent event) {
Event.fireEvent(root, event);
}
});
primaryStage.setTitle("WarbladeFX");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
和游戏 class:
public class Game extends Group {
Entity ship;
long delta;
HashSet<String> input = new HashSet<>();
public Game() {
File f = new File("src/ressources/ship.gif");
ship = new Entity(new Image("file:///" + f.getAbsolutePath().replace("\", "/")) ,300, 300);
getChildren().add(ship);
setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
//System.out.println(".handle()");
String code = event.getCode().toString();
if(!input.contains(code))
input.add(code);
}
});
setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
String code = event.getCode().toString();
input.remove(code);
}
});
new AnimationTimer(){
@Override
public void handle(long now) {
if(input.contains("LEFT"))
ship.setVelX(-1);
if(input.contains("RIGHT"))
ship.setVelX(1);
ship.move(now);
getChildren().clear();
getChildren().add(ship);
}
}.start();
}
}
有些帮助会非常好。
当您在事件处理方法中再次触发该事件时,您将生成一个无限循环。尝试在此方法中处理事件,即对用户输入做出反应。
在场景图中的节点上触发的事件将 "bubble up" 到父级,然后是父级的父级,最终一直到场景。因此,您在场景中定义的事件处理程序 "refire" 到 root
的事件将冒泡到场景并再次处理,再次被重新触发到 root
,并且等等...
如果你想捕捉场景中任何地方的事件,然后在Game
class中处理它们,在Game
中定义一些方法来处理事件并调用这些方法方法。不要"refire"事件。
例如:
public class Game extends Group {
Entity ship;
long delta;
HashSet<String> input = new HashSet<>();
public Game() {
File f = new File("src/ressources/ship.gif");
ship = new Entity(new Image("file:///" + f.getAbsolutePath().replace("\", "/")) ,300, 300);
getChildren().add(ship);
new AnimationTimer(){
@Override
public void handle(long now) {
if(input.contains("LEFT"))
ship.setVelX(-1);
if(input.contains("RIGHT"))
ship.setVelX(1);
ship.move(now);
getChildren().clear();
getChildren().add(ship);
}
}.start();
}
public void keyDown(String key) {
if(!input.contains(key))
input.add(key);
}
public void keyUp(String key) {
input.remove(code);
}
}
然后你可以做
public class WarbladeFX extends Application {
Game root;
public void start(Stage primaryStage) {
root = new Game();
Scene scene = new Scene(root, 800, 600);
scene.setFill(new Color(0,0,0,1));
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
public void handle(KeyEvent event) {
game.keyDown(event.getCode().toString());
}
});
scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
public void handle(KeyEvent event) {
game.keyUp(event.getCode().toString());
}
});
primaryStage.setTitle("WarbladeFX");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
我目前正在使用 JavaFX 开发一个小游戏,但在捕获 keyEvents 时遇到了一些问题。
现在我可以捕捉到它们了,但是程序抛出一个 java.lang.WhosebugError
并且在按下某个键时它没有按照我的预期进行。
这里是主要内容class:
public class WarbladeFX extends Application {
Game root;
public void start(Stage primaryStage) {
root = new Game();
Scene scene = new Scene(root, 800, 600);
scene.setFill(new Color(0,0,0,1));
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
public void handle(KeyEvent event) {
Event.fireEvent(root, event);
}
});
scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
public void handle(KeyEvent event) {
Event.fireEvent(root, event);
}
});
primaryStage.setTitle("WarbladeFX");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
和游戏 class:
public class Game extends Group {
Entity ship;
long delta;
HashSet<String> input = new HashSet<>();
public Game() {
File f = new File("src/ressources/ship.gif");
ship = new Entity(new Image("file:///" + f.getAbsolutePath().replace("\", "/")) ,300, 300);
getChildren().add(ship);
setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
//System.out.println(".handle()");
String code = event.getCode().toString();
if(!input.contains(code))
input.add(code);
}
});
setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
String code = event.getCode().toString();
input.remove(code);
}
});
new AnimationTimer(){
@Override
public void handle(long now) {
if(input.contains("LEFT"))
ship.setVelX(-1);
if(input.contains("RIGHT"))
ship.setVelX(1);
ship.move(now);
getChildren().clear();
getChildren().add(ship);
}
}.start();
}
}
有些帮助会非常好。
当您在事件处理方法中再次触发该事件时,您将生成一个无限循环。尝试在此方法中处理事件,即对用户输入做出反应。
在场景图中的节点上触发的事件将 "bubble up" 到父级,然后是父级的父级,最终一直到场景。因此,您在场景中定义的事件处理程序 "refire" 到 root
的事件将冒泡到场景并再次处理,再次被重新触发到 root
,并且等等...
如果你想捕捉场景中任何地方的事件,然后在Game
class中处理它们,在Game
中定义一些方法来处理事件并调用这些方法方法。不要"refire"事件。
例如:
public class Game extends Group {
Entity ship;
long delta;
HashSet<String> input = new HashSet<>();
public Game() {
File f = new File("src/ressources/ship.gif");
ship = new Entity(new Image("file:///" + f.getAbsolutePath().replace("\", "/")) ,300, 300);
getChildren().add(ship);
new AnimationTimer(){
@Override
public void handle(long now) {
if(input.contains("LEFT"))
ship.setVelX(-1);
if(input.contains("RIGHT"))
ship.setVelX(1);
ship.move(now);
getChildren().clear();
getChildren().add(ship);
}
}.start();
}
public void keyDown(String key) {
if(!input.contains(key))
input.add(key);
}
public void keyUp(String key) {
input.remove(code);
}
}
然后你可以做
public class WarbladeFX extends Application {
Game root;
public void start(Stage primaryStage) {
root = new Game();
Scene scene = new Scene(root, 800, 600);
scene.setFill(new Color(0,0,0,1));
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
public void handle(KeyEvent event) {
game.keyDown(event.getCode().toString());
}
});
scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
public void handle(KeyEvent event) {
game.keyUp(event.getCode().toString());
}
});
primaryStage.setTitle("WarbladeFX");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}