前回は、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();
以上のようなことができるユーティリティクラスを作成したいと思います。