JavaFX の画面遷移、簡単に書く。

JavaFX の画面遷移、Webページ閲覧のように切り替え、

いろんなやり方のサンプルを見たけど、どれも釈然としない。もっとシンプルに書けるはずだ。

javafx.application.Application継承の mainメソッドクラス

public class MainApp extends Application{
   static Logger logger = LoggerFactory.getLogger(MainApp.class);
   static int    WINDOW_WIDTH  = 500;
   static int    WINDOW_HEIGHT = 300;
   static String WINDOW_TITLE  = "fxtest";
   private Stage stage;

   public static void main(String[] args){
      launch(args);
   }

   @Override
   public void start(Stage primaryStage) throws Exception{
      stage = primaryStage;
      setPage(StartPage.class, "start.fxml");
   }

   /* BasePage を継承した Controller は遷移先画面の class と fxml名、任意に渡すパラメータで遷移を実行する */
   public void setPage(Class<?> cls, String fxml, Object...params) throws Exception{
      FXMLLoader loader = new FXMLLoader();
      Scene scene = new Scene((Parent)loader.load(cls.getResourceAsStream(fxml)), WINDOW_WIDTH, WINDOW_HEIGHT);
      BasePage page = (BasePage)loader.getController();
      page.setApp(this);
      page.loadParameter(params);
      stage.setTitle(WINDOW_TITLE);
      stage.setScene(scene);
      stage.show();
   }
}

MainApp の setPage で遷移する画面の抽象クラス

public abstract class BasePage{
   private MainApp application;

   public void setApp(MainApp application){
      this.application = application;
   }

   public void setPage(Class<? extends BasePage> cls, String fxml, Object...params){
      try{
         application.setPage(cls, fxml, params);
      }catch(Exception e){
         e.printStackTrace();
         throw new RuntimeException(e);
      }
   }

   public void loadParameter(Object[] params){
   }
}

これを継承する側で、パラメータを受信したければ、loadParameterをオーバーライドする。

最初に表示する画面、→ fxml ボタンなどの Action に紐つかせて動くようにする nextPage の実行で
、setPage をパラメータ付けて呼ぶ。→ AlphaPage に遷移する。

public class StartPage extends BasePage{

   public void nextPage(){
      setPage(AlphaPage.class, "alpha.fxml", "ABC");
   }
}

遷移先の AlphaPage → loadParameter を Override して受信したパラメータを Label にセットして表示する

public class AlphaPage extends BasePage{

   @FXML private Label status;

   public void backPage(){
      setPage(StartPage.class, "start.fxml");
   }

   @Override
   public void loadParameter(Object[] params){
      status.setText(params[0].toString());
   }
}