【问题标题】:How to restart a JavaFX application when a button is clicked单击按钮时如何重新启动 JavaFX 应用程序
【发布时间】:2016-04-19 16:29:00
【问题描述】:

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

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

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

1)有没有办法在不重新启动整个应用程序的情况下实现这一点?

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

主类

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

    gameUI.launch(GameUI.class, args);

}   

游戏界面 (我从这个类中删除了许多代码以使其简短。包括我认为足以给出想法的代码。如果太长,请见谅。)

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 编程也有些陌生。

【问题讨论】:

    标签: java javafx restart application-restart


    【解决方案1】:

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

    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 方法,因此您不应自己创建应用程序类的实例。请改用Application.launch(GameUI.class, args);,并让该方法处理GameUI 实例的创建。
    • 将 UI 创建移动到与应用程序类不同的类可能是更好的设计。这种方式代码的重用更容易,因为它不需要创建Application 的子类的实例。

    【讨论】:

    • 感谢详细的回答,关于将 UI 创建移动到不同的类,我试过了,但是当我这样做时,我无法更新 UI,即死了(在程序内)但它没有得到在 UI 中更新。我进行了研究,据我了解,这是因为应用程序作为线程运行,并且在线程运行时我们无法更新。我当然想把 ui 部分移到另一个类,但我做不到。
    • @RaveenAthapaththu:有一些方法可以从应用程序线程中调用代码(例如Platform.runLater)。但是如果您将一些代码移到另一个类中,确实没有太大区别。您可以编写一个创建场景的工厂,您在start 方法中所做的就是将场景放在Stage 中并显示它。当然,由于应用程序生命周期/不同的线程,您必须小心,但恕我直言,这是值得的。也许您应该从原始版本开始并使用委托模式(使用构造函数,开始 [, init?])进行折射,然后逐步折射代码。
    【解决方案2】:

    在您的 Start() 函数中,添加以下行:

    Platform.setImplicitExit(false);
    

    这将使您的应用程序在后台运行而无需退出。

    现在,使用包装函数来启动第二次,比如:

    void displayApplication() {
             Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        start(new Stage());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    

    【讨论】:

      猜你喜欢
      • 2018-11-22
      • 1970-01-01
      • 1970-01-01
      • 2022-11-27
      • 2021-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多