私が正しく理解していれば、FXMLLoader
をインスタンス化するのではなく、Javaコードでコントローラインスタンスを定義する必要があります。
load()
に電話する前にFXMLLoader
のsetController
を呼び出すことでこれを行うことができます。あなたがこのテクニックを使用する場合は、が使用してはならない
MyController controller = new MyController();
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/fxml"));
loader.setController(controller);
Parent root = loader.load();
:これはあなたがFXMLLoader
インスタンスを作成し、インスタンスload()
メソッドを呼び出す必要があります意味し、静的load(URL)
メソッドを呼び出してはならないことに注意してくださいfx:controller
属性をFXMLファイルのルート要素に追加します。
これにより、好きなようにコントローラをインスタンス化することができます。パラメータを取るコンストラクタを持つコントローラクラスがあれば、ここでそれらを使うことができます(デフォルトのメカニズムで使われるコントローラには、ゼロ引数のコンストラクタが必要です)。
より高度が関連情報:
関連技術、おそらくより特殊なユースケースのために、FXMLLoader
にコントローラファクトリを設定することです。コントローラファクトリは、Class<?>
(fx:controller
属性で定義されたもの)をオブジェクト(コントローラ)にマップする関数です。これは基本的にコントローラがインスタンス化される方法(通常はリフレクションを使用して)をプログラマチックに制御します。
public class Model { /* ... */ }
などのモデルクラスと、モデル参照をコンストラクタパラメータとして使用するいくつかの異なるコントローラクラスがあります。通常は、同じモデルインスタンスを使用してすべてのコントローラに渡す必要があります。次のようにだから、コントローラーファクトリを定義することができます。
Model model = new Model();
Callback<Class<?>, Object> controllerFactory = type -> {
try {
// look for a constructor with a single parameter of type Model:
for (Constructor<?> c : type.getConstructors) {
if (c.getParameterCount() == 1 && c.getParameterTypes()[0] == Model.class) {
return c.newInstance(model);
}
}
// no constructor found, just invoke no-arg constructor as in default:
return type.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
};
を次に、あなたがあなたのFXMLLoader
上のコントローラの工場(複数可)を設定することができます。
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/fxml"));
loader.setControllerFactory(controllerFactory);
Parent root = loader.load();
この技術の別の用途は、依存性注入と連動していますSpringやGuiceなどのフレームワークDIフレームワークを構成してコントローラをインスタンス化し、モデルインスタンスをモデルインスタンスに挿入する場合は、コントローラファクトリを使用してFXMLLoader
がコントローラインスタンスをフレームワークから取得できるようにすることができます。例えば。
ApplicationContext context = ... ;
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/fxml"));
loader.setControllerFactory(context::getBean);
Parent root = loader.load();
やGuiceのと::春と
Injector injector = Guice.createInjector(...);
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/fxml"));
loader.setControllerFactory(injector::getInstance);
Parent root = loader.load();
私は不明でした。私はFXMLLoader(すなわち、FXMLファイルなし)を使用していませんが、単純にノードを手渡しました。 「明白な答え」は、「彼らが意図したとおりにFXMLを使用する」ことですが、それ以外の方法があるかどうかを知りたいだけでした。 これはちょっとしたハックかもしれませんが、ノードを生成するときにコントローラーインスタンスをインスタンス化してから、ノードにハンドラーを戻す前にイベントハンドラーをノードに登録することができます。 – SoCal
何をすればいいですか?コードでコントロールを作成する場合、私はあなたがしたいことを理解していません。質問を編集して、意味を示すコードを追加します。 –