JavaFX の Controller (←この呼び方が個人的には嫌い、MVCモデルの Cなんだろうけど)のファクトリの
コールバックに、Google guice でのインジェクションを行う方法は、とても有効な手段だと思う。
前回の投稿、
JavaFX の画面遷移、簡単に書く。 - Oboe吹きプログラマの黙示録
で書いた Controller クラスと fxml 名を指定して画面遷移させるメソッド setPage と書いたものは、以下のように
Google guice でのインジェクトの約束が書ける。。
======
この投稿後、あまり良くないと思って、結局、、
JavaFX のイニシャライズ処理を Google guice で整理 - Oboe吹きプログラマの黙示録
を書くはめになった。
======
/* @see javafx.application.Application#start(javafx.stage.Stage) */ @Override public void start(Stage primaryStage) throws Exception{ stage = primaryStage; setPage(StartPage.class, "start.fxml"); } public void setPage(final Class<?> cls, String fxml, Object...params) throws Exception{ Injector injector = Guice.createInjector(new AbstractModule(){ @Override protected void configure(){ // TODO bind 定義する } }); FXMLLoader loader = new FXMLLoader(cls.getResource(fxml)); loader.setControllerFactory(new Callback<Class<?>, Object>(){ @Override public Object call(Class<?> type){ return injector.getInstance(cls); } }); Scene scene = new Scene((Parent)loader.load()); BasePage page = (BasePage)loader.getController(); page.setApp(this); page.loadParameter(params); stage.setTitle(WINDOW_TITLE); stage.setScene(scene); stage.show(); }
FXMLLoader loader の実行は、引数なしの load() の実行になる。
Callback の call メソッドのパラメータ type でなくて、setPage で渡される class を指定する!
Mainクラスの全体は以下のようになる。
import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; import javafx.util.Callback; /** * MainApp */ public class MainApp extends Application{ static Logger logger = LoggerFactory.getLogger(MainApp.class); static String WINDOW_TITLE = "fxtest2"; private Stage stage; public static void main(String[] args){ launch(args); } /* @see javafx.application.Application#start(javafx.stage.Stage) */ @Override public void start(Stage primaryStage) throws Exception{ stage = primaryStage; setPage(StartPage.class, "start.fxml"); } public void setPage(final Class<?> cls, String fxml, Object...params) throws Exception{ Injector injector = Guice.createInjector(new AbstractModule(){ @Override protected void configure(){ // TODO bind 定義する } }); FXMLLoader loader = new FXMLLoader(cls.getResource(fxml)); loader.setControllerFactory(new Callback<Class<?>, Object>(){ @Override public Object call(Class<?> type){ return injector.getInstance(cls); } }); Scene scene = new Scene((Parent)loader.load()); BasePage page = (BasePage)loader.getController(); page.setApp(this); page.loadParameter(params); stage.setTitle(WINDOW_TITLE); stage.setScene(scene); stage.show(); } }
setPage の引数、Object...params 画面遷移時に渡すパラメータ、 page.loadParameter(params);
と書いてはいるが、
guice のインジェクションとして、上の // TODO bind 定義する
で、パラメータ渡しを書く方法もあるだろう。
すると、loadParameter というメソッドは、不要になってくるはずだ。。