前回は、FXMLファイルでViewを定義したときのControllerの設定についてみていきました。今回は、FXMLファイルを読み込んでControllerを取得するユーティリティクラスを作成してみたいと思います。
名称としては、FXControllerとして作成していきます。
まずは、FXMLファイルのfx:controller属性で、Controllerを指定した場合を考えていきます。この場合、FXMLファイルのURLを指定して、以下のようにControllerが取得できるようにします。
SimpleViewController controller = FXController.<SimpleViewController>from(location) .load();
ResourceBundleを指定したい場合は、以下のように指定できるようにします。
SimpleViewController controller = FXController.<SimpleViewController>from(location) .with(resources) .load();
また、ResouceBundleの代わりに、以下のようにリソースバンドルの基底名を指定できるようにします。
SimpleViewController controller = FXController.<SimpleViewController>from(location) .withResourceOf(resourceBaseName) .load();>
fx:controller属性で指定しているControllerのクラスの指定は、以下のように指定できるようにもします。
SimpleViewController controller = FXController.of(SimpleViewController.class) .from(location) .load();
次に、FXMLファイルのfx:controller属性を指定しなかった場合を考えていきます。この場合、ControllerのインスタンスとURLを指定して、以下のようにFXMLファイルを読み込めるようにします。
SimpleViewController controller = FXController.of(new SimpleViewController()) .from(loacation) .load();
また、以下のように、ResouceBundle、あるいは、リソースバンドルの基底名を指定できるようにします。
SimpleViewController controller = FXController.of(new SimpleViewController()) .from(loacation) .with(resources) .load();
SimpleViewController controller = FXController.of(new SimpleViewController()) .from(loacation) .withResourceOf(resourceBaseName) .load();
FXMLファイル名の指定については、Controllerのクラスの定義に、FXMLLocationアノテーションで指定できるようにもします。指定する場合は、ClassのgetResourceメソッドに指定する場合と同じ名称を指定するようにします。
@FXMLLocation("SimpleView.fxml") public class SimpleViewController { }
この場合、以下のようにして読み込むようにします。
SimpleViewController controller = FXController.of(new SimpleViewController()) .fromDefaultLocation() .load();
また、FXMLLocationアノテーションで指定していない場合は、次の命名規則で、FXMLファイルを検索するようにします。
Controllerと同じパッケージで、Controllerの名称から末尾の「Controller」を除いた名称に「.fxml」をつけたファイル
ofメソッドでControllerのインスタンスを指定したときに、そのインスタンスが、javafx.scene.Sceneクラス、あるいは、javafx.scene.Nodeクラスのサブクラスの場合は、javafx.fxml.FXMLLoaderクラスのsetRootメソッドにControllerのインスタンスを設定してから読み込むようにして、FXMLファイルをfx:root要素で定義した場合にも対応できるようにします。
public class SimpleControl extends StackPane { public SimpleControl() { initializeComponent(); } protected void initializeComponent() { FXController.of(this).fromDefaultLocation.load(); } }
あと、個人的には、依存性の注入にgoogle-guiceを使いたいので、以下のように、com.google.inject.Injectorの指定もできるようにしておきます。
SimpleViewController controller = FXController.of(SimpleViewController.class) .using(injector) .from(location) .load();
この場合も、以下のように、アノテーション、あるいは、命名規則で、FXMLファイルを検索できるようにします。
SimpleViewController controller = FXController.of(SimpleViewController.class) .using(injector) .fromDefaultLocation() .load();
ResourceBundle、あるいは、リソースバンドルの基底名についても、指定できるようにしておきます。
SimpleViewController controller = FXController.of(SimpleViewController.class) .using(injector) .fromDefaultLocation() .with(resources) .load();
SimpleViewController controller = FXController.of(SimpleViewController.class) .using(injector) .fromDefaultLocation() .withResourceOf(resourceBaseName) .load();
さらに、ofメソッドに、Controllerのインスタンスを指定できるようにもしておきます。
SimpleViewController controller = FXController.of(new SimpleViewController()) .using(injector) .fromDefaultLocation() .load();
また、com.google.inject.Injectorについては、usingメソッドで毎回指定せず、以下のようにstaticメソッドで指定し、常にそこで指定したcom.google.inject.Injectorを用いてインスタンスを取得できるようにもします。
FXController.setDefaultInjector(injector); SimpleViewController controller = FXController.of(SimpleViewController.class) .fromDefaultLocation() .load();
以上のようなことができるユーティリティクラスを作成したいと思います。