JavaFX アプリを設計しています。ユーザーイベント(ボタンのクリックなど)に応じてユーザー入力を動的に(FXMLから)収集するために使用されるダイアログフォーム/ウィンドウをロードし、ユーザーが操作を終了したときにウィンドウを「アンロード」することにしました。形成し、それを却下します。
各 FXML フォームがロードされた後、ダイアログがユーザーに表示される前に初期化する必要があるリストビュー、テーブルビュー、およびコンボボックスがあります。この目的で使用するコードの一部を次に示します。
@FXML // This method is called by the FXMLLoader when
//initialization is complete
void initialize() {
// Initialize your logic here: all @FXML variables will have been injected
ObservableList<Institution> ilist = Institution.getInstitutionList();
Callback<ListView<Institution>, ListCell<Institution>> cellfactory =
new Callback<ListView<Institution>, ListCell<Institution>>() {
@Override
public ListCell<Institution> call(ListView<Institution> p) {
return new InstitutionListCell();
}
};
cbxInst.setCellFactory(cellfactory);
cbxInst.setButtonCell(cellfactory.call(null));
cbxInst.setPromptText(CensusAssistant.RES_STRING_INSTSELECT);
cbxInst.setItems(ilist);
cbxInst.setDisable((ilist.size() < 1));
Callback<ListView<Rotation>, ListCell<Rotation>> rotfactory =
new Callback<ListView<Rotation>, ListCell<Rotation>>() {
@Override
public ListCell<Rotation> call(ListView<Rotation> p) {
return new EncRotationListCell();
}
};
:
:
すべてのコードを表示したくありません。ここでのポイントは、Cell のサブクラス (ListCell など) を使用するフォーム上のすべてのコントロールに対して、セル ファクトリを提供するために匿名の内部クラスを使用していることです。
これらの匿名内部クラスは、それらを囲むクラスへの参照を保持します。私の結論は、これらの参照により、ユーザーがフォームを閉じた後の任意の時点でフォームがガベージ コレクションされるのを防ぐことができるということです。そのため、セッション中にフォームを何度も開いたり閉じたりすると、メモリ リークの問題が発生するのではないかと心配しています。
私はこれについて目標を達成していますか?ユーザーがフォームを閉じたときにセル ファクトリをコントロールから切り離すコードを記述する必要がありますか? これは一般的に、イベントリスナー (または内部クラスを使用して一般的に対処されるもの) の問題ですか? オブジェクトが解放される前に、常にイベントまたはアクション ハンドラーの登録を解除するのが賢明ですか?
編集:
これらと同じ問題の多くは、この投稿で処理されています: (匿名の) 内部クラスを使用しても安全なのはいつですか? .
ウィンドウが繰り返し構築されて閉じられる可能性があるこの状況では、JavaFX コントローラー クラスへの潜在的に長命の参照をすべて無効にする必要があると考える傾向があると思います。特に細胞工場。