web-dev-qa-db-ja.com

ボタンがクリックされたときにJavaFXアプリケーションを再起動する方法

私は問題についてここでほとんどすべての投稿を通過しましたが、それらのほとんどは適切に何をすべきかを説明していません。質問へ:

私はjavaFXアプリケーション、サイコロゲーム、人間のプレイヤー対コンピュータを作成しましたが、ゲームのプレイ中はいつでも、人間のプレイヤーはボタン「新しいゲーム」をクリックできるはずで、ゲームを最初からやり直す必要があります。

もう一度ステージを再起動してみましたが、javafxでは起動メソッドを2回呼び出すことができません。

1)アプリケーション全体を再起動せずにこれを実装できる方法はありますか?

2)できない場合は、ボタンをクリックしてアプリケーションを完全に再起動できますか?

メインクラス

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

    gameUI.launch(GameUI.class, args);

}   

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

pS私はJavaFXに非常に慣れており、Javaプログラミングに少し新しいです。

7

起動プロセスを再度実行できないことにすでに気づいています。したがって、最良のオプションは、アプリケーションクラスを書き直して、初期化ロジックを新しいメソッドに移動することです。

_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のサブクラスのインスタンスを作成する必要がないため、コードの再利用が簡単になります。
4
fabian