MVCの使用
この回答のほとんどは、呼び出し元のクラスからコントローラーにパラメーターを渡すための直接呼び出しに焦点を当てています。
代わりに、呼び出し元とコントローラーを分離し、設定可能でリッスン可能なプロパティを持つモデルクラスを含むより一般的なアーキテクチャを使用して、コントローラー間の通信を実現する場合は、次の基本的な概要を参照してください。
推奨されるアプローチ
この回答は、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(loader.load())
);
CustomerDialogController controller = loader.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 = loader.load();
コードで新しいコントローラーを作成し、呼び出し元からコントローラーコンストラクターに必要なパラメーターを渡すことができます。コントローラを構築したら、インスタンスメソッドを呼び出す前に、FXMLLoaderインスタンスにコントローラを設定できます。load()
ローダーにコントローラーを設定するには(JavaFX 2.xの場合)fx:controller
、fxmlファイルで属性を定義することもできません。
FXMLでの定義に制限があるためfx:controller
、私は個人的に、コントローラーをFXMLLoaderに設定するよりも、FXMLLoaderからコントローラーを取得することを好みます。
コントローラに外部静的メソッドからパラメータを取得させる
このメソッドは、Controller.javaファイルのJavafx 2.0 How-to Application.getParameters()に対するSergeyの回答によって例示されています。
依存性注入を使用する
FXMLLoaderは、FXMLLoaderにカスタムコントローラーファクトリを設定できるようにすることで、Guice、Spring、JavaEECDIなどの依存性注入システムをサポートします。これは、それぞれの依存性注入システムによって注入された依存性の値を持つコントローラーインスタンスを作成するために使用できるコールバックを提供します。
Springを使用したJavaFXアプリケーションとコントローラーの依存性注入の例は、次の回答に記載されています。
本当に素晴らしく、クリーンな依存性注入アプローチは、それを使用するサンプルのエアハックアプリケーションを備えたafterburner.fxフレームワークによって例示されています。afterburner.fxは、JEE6javax.injectに依存して依存性注入を実行します。
イベントバスを使用する
元のFXML仕様の作成者および実装者であるGregBrownは、FXMLインスタンス化コントローラーと他のアプリケーションロジック間の通信に、GuavaEventBusなどのイベントバスの使用を検討することを提案することがよくあります。
EventBusは、アノテーションを備えたシンプルで強力なパブリッシュ/サブスクライブAPIであり、POJOが相互に参照しなくてもJVM内のどこでも相互に通信できるようにします。
フォローアップQ&A
最初の方法で、なぜステージに戻るのですか?すでにコマンドshow()を指定しているため、このメソッドも無効にすることができます。リターンステージの直前;。ステージに戻って使用をどのように計画しますか
これは、問題に対する機能的な解決策です。ステージはshowCustomerDialog
関数から返されるため、後でメインウィンドウのボタンクリックに基づいてステージを非表示にするなど、何かを実行したい外部クラスがステージへの参照を保存できます。別のオブジェクト指向ソリューションでは、CustomerDialogオブジェクト内に機能とステージ参照をカプセル化するか、CustomerDialogにStageを拡張させることができます。FXML、コントローラー、およびモデルデータをカプセル化するカスタムダイアログへのオブジェクト指向インターフェイスの完全な例は、この回答の範囲を超えていますが、作成したい人にとっては価値のあるブログ投稿になる可能性があります。
@dzimという名前のStackOverflowユーザーによって提供される追加情報
SpringBoot依存性注入の例
「TheSpringBootWay」のやり方についての質問で、添付のパーマリンクで答えたJavaFX2についての議論がありました。このアプローチはまだ有効であり、2016年3月にSpring Boot v1.3.3.RELEASEでテストされています:
https ://stackoverflow.com/a/36310391/1281217
結果を発信者に返したい場合があります。その場合は、関連する質問への回答を確認できます。