推奨されるアプローチ
この回答は、FXMLコントローラーにパラメーターを渡すためのさまざまなメカニズムを列挙しています。
小さなアプリケーションの場合は、呼び出し元からコントローラーに直接パラメーターを渡すことを強くお勧めします。これはシンプルで簡単で、追加のフレームワークを必要としません。
大規模で複雑なアプリケーションの場合、アプリケーション内で依存性注入またはイベントバスメカニズムを使用するかどうかを調査することは価値があります。
呼び出し元からコントローラーに直接パラメーターを渡す
FXMLローダーインスタンスからコントローラーを取得し、コントローラーのメソッドを呼び出して必要なデータ値で初期化することにより、カスタムデータをFXMLコントローラーに渡します。
次のコードのようなもの:
public Stage showCustomerDialog(Customer customer) {
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
Stage stage = new Stage(StageStyle.DECORATED);
stage.setScene(
new Scene(
(Pane) loader.load()
)
);
CustomerDialogController controller =
loader.<CustomerDialogController>getController();
controller.initData(customer);
stage.show();
return stage;
}
...
class CustomerDialogController {
@FXML private Label customerName;
void initialize() {}
void initData(Customer customer) {
customerName.setText(customer.getName());
}
}
新しいFXMLLoaderは、サンプルコードに示すように構築されますnew FXMLLoader(location)
。場所はURLであり、次の方法でFXMLリソースからそのようなURLを生成できます。
new FXMLLoader(getClass().getResource("sample.fxml"));
FXMLLoaderで静的ロード関数を使用しないように注意してください。そうしないと、ローダーインスタンスからコントローラーを取得できなくなります。
FXMLLoaderインスタンス自体は、ドメインオブジェクトについて何も知りません。アプリケーション固有のドメインオブジェクトをFXMLLoaderコンストラクターに直接渡さず、代わりに次のようにします。
- 指定された場所でfxmlマークアップに基づいてFXMLLoaderを構築します
- FXMLLoaderインスタンスからコントローラーを取得します。
- 取得したコントローラーでメソッドを呼び出して、コントローラーにドメインオブジェクトへの参照を提供します。
このブログ(別のライターによる)は、代替の類似した例を提供しています。
FXMLLoaderでのコントローラーの設定
CustomerDialogController dialogController =
new CustomerDialogController(param1, param2);
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
loader.setController(dialogController);
Pane mainPane = (Pane) loader.load();
コードで新しいコントローラーを作成し、必要なパラメーターを呼び出し元からコントローラーコンストラクターに渡すことができます。コントローラを作成したら、インスタンスメソッドを呼び出す前に、FXMLLoaderインスタンスにコントローラを設定できload()
ます。
ローダー(JavaFX 2.x)にコントローラーを設定するにfx:controller
は、fxmlファイルで属性を定義することもできません。
fx:controller
FXMLでの定義には制限があるため、コントローラーをFXMLLoaderに設定するよりも、FXMLLoaderからコントローラーを取得する方が個人的に好みます。
コントローラに外部静的メソッドからパラメータを取得させる
このメソッドの例は、Controller.javaファイル内のJavafx 2.0 How-to Application.getParameters()に対するSergeyの回答です。
依存性注入を使用する
FXMLLoaderは、FXMLLoaderでカスタムコントローラファクトリを設定できるようにすることで、Guice、Spring、Java EE CDIなどの依存性注入システムをサポートします。これにより、それぞれの依存性注入システムによって注入された依存値を持つコントローラーインスタンスを作成するために使用できるコールバックが提供されます。
SpringでのJavaFXアプリケーションとコントローラーの依存性注入の例は、以下の回答で提供されています。
本当に素敵でクリーンな依存性注入アプローチは、それを使用するサンプルのエアハックアプリケーションを備えたafterburner.fxフレームワークによって例示されています。afterburner.fxはJEE6のに依存しているjavax.inject依存性の注入を実行します。
イベントバスを使用する
元のFXML仕様の作成者および実装者であるGreg Brownは、FXMLのインスタンス化されたコントローラーと他のアプリケーションロジック間の通信のために、Guava EventBusなどのイベントバスの使用を検討することを提案しています。
EventBusは、POJOが相互に参照しなくてもJVM内の任意の場所で相互に通信できるようにする注釈を備えた、シンプルですが強力なパブリッシュ/サブスクライブAPIです。
フォローアップQ&A
最初の方法で、なぜステージに戻るのですか?show();コマンドをすでに与えているので、メソッドも無効になる可能性があります。リターンステージの直前;。ステージを返却して使用方法をどのように計画しますか
これは問題に対する機能的な解決策です。ステージはshowCustomerDialog
関数から返されるので、後でメインウィンドウのボタンクリックに基づいてステージを非表示にするなど、何かを実行したい外部クラスによってステージへの参照を格納できます。別のオブジェクト指向ソリューションでは、機能とステージ参照をCustomerDialogオブジェクト内にカプセル化したり、CustomerDialogでステージを拡張したりできます。FXML、コントローラー、およびモデルデータをカプセル化するカスタムダイアログへのオブジェクト指向インターフェイスの完全な例は、この回答の範囲を超えていますが、作成を志向する人にとって価値のあるブログ投稿になる場合があります。
StackOverflowユーザーが@dzimという名前で提供する追加情報
Spring Boot Dependency Injectionの例
それをどのように行うかという質問「The Spring Boot Way」では、添付のパーマリンクで私が答えたJavaFX 2についての議論がありました。このアプローチはまだ有効であり、2016年3月にSpring Boot v1.3.3.RELEASEでテストされています:https ://stackoverflow.com/a/36310391/1281217
場合によっては、結果を呼び出し元に返したいことがあります。その場合、関連する質問への回答を確認できます。