单击按钮时如何重新启动 JavaFX 应用程序
How to restart a JavaFX application when a button is clicked
关于这件事,我几乎遍历了这里的每一个 post,但其中大部分都没有解释正确的做法。
对问题:
我创建了一个 javaFX 应用程序,一个骰子游戏,人类玩家与计算机,但在玩游戏的任何时候,人类玩家都应该能够点击按钮 "new game" 以及它是什么应该做的是重新开始游戏。
我尝试重新启动舞台,但在 javafx 中我们无法调用启动方法两次。
1)有没有一种方法可以在不重新启动整个应用程序的情况下实现它?
2) 如果不是,我如何使用单击按钮完全重新启动应用程序?
主要class
public class Main {
public static void main(String[] args) {
GameUI gameUI = new GameUI();
gameUI.launch(GameUI.class, args);
}
游戏界面
(我从这个 class 中删除了许多代码以使其简短。包含了我认为足以提供想法的代码。如果它太长,抱歉。)
public class GameUI extends Application {
//all btn and label declarations
//creating instances for necessary classes
private Scene scene;
@Override
public void start(Stage primaryStage) throws Exception {
//Displaying Dice for Player and Computer
setLabelsPlyr(diesP);
setLabels(diesC);
btnThrow = new Button("Throw");
btnThrow.setPrefSize(70, 40);
//Throw action is performed
btnThrow.setOnAction(e -> {
//setting and displaying dies
DieClass[] com = getNewDiceArrC();
lblDiceOneC.setGraphic(new ImageView(diesC[0].getDieImageC()));
//so on.....
DieClass[] playerAr = getNewDiceArrP();
lblDiceOnePlyr.setGraphic(new ImageView(diesP[0].getDieImageP()));
//so on...
});
btnNewGame = new Button("New Game");
btnNewGame.setOnAction(e -> {
**//WHAT TO DO HERE?????**
});
//setting layouts
GridPane gridPane = new GridPane();
gridPane.add(lblComputer, 0, 0);
//so on.....
Scene scene = new Scene(gridPane, 1100, 400);
primaryStage.setScene(scene);
primaryStage.setTitle("dice Game");
primaryStage.show();
}
//some other methods
public void setLabels(DieClass[] dies) {
for (int i=0; i < dies.length; i++) {
lblDiceOneC = new Label();
lblDiceOneC.setGraphic(new ImageView(dies[0].getDieImageC()));
++i;
//so on.....
break;
}
}
public void setLabelsPlyr(DieClass[] dies){
for (int i=0; i<dies.length; i++) {
lblDiceOnePlyr = new Label();
lblDiceOnePlyr.setGraphic(new ImageView(dies[0].getDieImageP()));
++i;
lblDiceTwoPlyr = new Label();
//so on......
break;
}
}
p.s 我对 JavaFX 很陌生,对 java 编程也有些陌生。
您已经注意到您无法再次执行启动过程。因此,您最好的选择是重写应用程序 class 并将初始化逻辑移至新方法:
void cleanup() {
// stop animations reset model ect.
}
void startGame(Stage stage) {
// initialisation from start method goes here
btnNewGame.setOnAction(e -> {
restart(stage);
});
stage.show();
}
void restart(Stage stage) {
cleanup();
startGame(stage);
}
@Override
public void start(Stage primaryStage) {
startGame(primaryStage);
}
备注
- 根据场景变化的部分,改变一些节点的状态可能就足够了(比创建新场景更有效)。 (看看你在游戏中所做的改变,自己决定)
launch()
是一种 static
方法,您不应因此 class 自己创建应用程序实例。请改用 Application.launch(GameUI.class, args);
并让该方法处理 GameUI
实例的创建。
- 将 UI 创建移动到与应用程序 class 不同的 class 可能是更好的设计。这种代码的重用方式更容易,因为它不需要创建
Application
. 的 subclass 的实例
在您的 Start()
函数中,添加以下行:
Platform.setImplicitExit(false);
这将使您的应用程序 运行 在后台运行而不退出。
现在,使用包装函数来第二次启动,说:
void displayApplication() {
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
start(new Stage());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
关于这件事,我几乎遍历了这里的每一个 post,但其中大部分都没有解释正确的做法。 对问题:
我创建了一个 javaFX 应用程序,一个骰子游戏,人类玩家与计算机,但在玩游戏的任何时候,人类玩家都应该能够点击按钮 "new game" 以及它是什么应该做的是重新开始游戏。
我尝试重新启动舞台,但在 javafx 中我们无法调用启动方法两次。
1)有没有一种方法可以在不重新启动整个应用程序的情况下实现它?
2) 如果不是,我如何使用单击按钮完全重新启动应用程序?
主要class
public class Main {
public static void main(String[] args) {
GameUI gameUI = new GameUI();
gameUI.launch(GameUI.class, args);
}
游戏界面 (我从这个 class 中删除了许多代码以使其简短。包含了我认为足以提供想法的代码。如果它太长,抱歉。)
public class GameUI extends Application {
//all btn and label declarations
//creating instances for necessary classes
private Scene scene;
@Override
public void start(Stage primaryStage) throws Exception {
//Displaying Dice for Player and Computer
setLabelsPlyr(diesP);
setLabels(diesC);
btnThrow = new Button("Throw");
btnThrow.setPrefSize(70, 40);
//Throw action is performed
btnThrow.setOnAction(e -> {
//setting and displaying dies
DieClass[] com = getNewDiceArrC();
lblDiceOneC.setGraphic(new ImageView(diesC[0].getDieImageC()));
//so on.....
DieClass[] playerAr = getNewDiceArrP();
lblDiceOnePlyr.setGraphic(new ImageView(diesP[0].getDieImageP()));
//so on...
});
btnNewGame = new Button("New Game");
btnNewGame.setOnAction(e -> {
**//WHAT TO DO HERE?????**
});
//setting layouts
GridPane gridPane = new GridPane();
gridPane.add(lblComputer, 0, 0);
//so on.....
Scene scene = new Scene(gridPane, 1100, 400);
primaryStage.setScene(scene);
primaryStage.setTitle("dice Game");
primaryStage.show();
}
//some other methods
public void setLabels(DieClass[] dies) {
for (int i=0; i < dies.length; i++) {
lblDiceOneC = new Label();
lblDiceOneC.setGraphic(new ImageView(dies[0].getDieImageC()));
++i;
//so on.....
break;
}
}
public void setLabelsPlyr(DieClass[] dies){
for (int i=0; i<dies.length; i++) {
lblDiceOnePlyr = new Label();
lblDiceOnePlyr.setGraphic(new ImageView(dies[0].getDieImageP()));
++i;
lblDiceTwoPlyr = new Label();
//so on......
break;
}
}
p.s 我对 JavaFX 很陌生,对 java 编程也有些陌生。
您已经注意到您无法再次执行启动过程。因此,您最好的选择是重写应用程序 class 并将初始化逻辑移至新方法:
void cleanup() {
// stop animations reset model ect.
}
void startGame(Stage stage) {
// initialisation from start method goes here
btnNewGame.setOnAction(e -> {
restart(stage);
});
stage.show();
}
void restart(Stage stage) {
cleanup();
startGame(stage);
}
@Override
public void start(Stage primaryStage) {
startGame(primaryStage);
}
备注
- 根据场景变化的部分,改变一些节点的状态可能就足够了(比创建新场景更有效)。 (看看你在游戏中所做的改变,自己决定)
launch()
是一种static
方法,您不应因此 class 自己创建应用程序实例。请改用Application.launch(GameUI.class, args);
并让该方法处理GameUI
实例的创建。- 将 UI 创建移动到与应用程序 class 不同的 class 可能是更好的设计。这种代码的重用方式更容易,因为它不需要创建
Application
. 的 subclass 的实例
在您的 Start()
函数中,添加以下行:
Platform.setImplicitExit(false);
这将使您的应用程序 运行 在后台运行而不退出。
现在,使用包装函数来第二次启动,说:
void displayApplication() {
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
start(new Stage());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}