单击按钮时如何重新启动 JavaFX 应用程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34788026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:59:55  来源:igfitidea点击:

How to restart a JavaFX application when a button is clicked

javajavafxrestartapplication-restart

提问by Raveen Athapaththu

I went through almost every post here regarding the matter but most of them doesn't explain what to do properly. To the question:

我浏览了几乎所有关于此事的帖子,但其中大多数都没有解释如何正确做。对于这个问题:

I created a javaFX application, a dice game, human player vs. computer, but during any time while playing the game human player should be able to click button "new game" and what it should do is to restart the game from beginning.

我创建了一个 javaFX 应用程序,一个骰子游戏,人类玩家与计算机,但在玩游戏的任何时间,人类玩家都应该能够点击“新游戏”按钮,它应该做的是从头开始重新启动游戏。

I tried relaunching the stage again but in javafx we cannot call the launch method twice.

我再次尝试重新启动舞台,但在 javafx 中我们不能两次调用启动方法。

1)Is there a way i can implement this without restarting the whole application?

1)有没有一种方法可以在不重新启动整个应用程序的情况下实现它?

2)if not how can i restart the application completely using a button click?

2)如果不是,我如何通过单击按钮完全重新启动应用程序?

Main class

主班

public class Main {
public static void main(String[] args) {
    GameUI gameUI = new GameUI();

    gameUI.launch(GameUI.class, args);

}   

GameUI (i removed many codes from this class to make it short. codes that i think enough to give an idea is included. sorry if it is too long.)

GameUI(我从这个类中删除了许多代码以使其简短。包含了我认为足以提供想法的代码。抱歉,如果它太长了。)

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 I am very new to JavaFX and somewhat new to java programming.

ps 我对 JavaFX 很陌生,对 Java 编程有些陌生。

采纳答案by fabian

You already noticed that you cannot do the launching process again. Therefore your best option is to rewrite the application class and move the initialisation logic to a new method:

您已经注意到您无法再次执行启动过程。因此,您最好的选择是重写应用程序类并将初始化逻辑移至新方法:

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);
}

Notes

笔记

  • Depending on the parts of the scene changed, it may be enough to change the state of some of the nodes (more efficient than creating a new scene). (Just take a look at the changes you made during the game and decide for yourself)
  • launch()is a staticmethod and you should not create a instance of your application class yourself for that reason. Use Application.launch(GameUI.class, args);instead and let the method handle the creation of the GameUIinstance.
  • It may be a better design to move the UI creation to a class different to the application class. This way reuse of the code is easier, since it does not require the creation of a instance of a subclass of Application.
  • 根据场景的变化部分,改变一些节点的状态可能就足够了(比创建新场景更有效)。(只需看看您在游戏中所做的更改并自行决定)
  • launch()是一种static方法,因此您不应自己创建应用程序类的实例。使用Application.launch(GameUI.class, args);,而不是让该方法处理的创建GameUI实例。
  • 将 UI 创建移动到与应用程序类不同的类可能是更好的设计。这种方式的代码重用更容易,因为它不需要创建Application.