I am designing a JavaFX app. I have made the decision to load the dialog forms/windows used to collect user input dynamically (from FXML) in response to a user event (eg. clicking a button) and then to "unload" the window when the user is finished with the form and dismisses it.
After each FXML form is loaded, there are listviews, tableviews, and comboboxes that need to be initialized before the dialog is shown to the user. Here is some of the code I use for this purpose:
@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();
}
};
:
:
I don't want to show all the code. The point here is that for every control on my form that uses subclasses of Cell (ListCell, etc.), I am using an anonymous inner class to provide the cell factory.
These anonymous inner classes will be holding references to their enclosing class. My conclusion is that these references will prevent the forms from being garbage collected at any point after the form has been dismissed by the user. I'm worried, then, that if the form is opened and dismissed many times in a session, a memory leak problem will ensue.
Am I on target about this? Will I need to write code that uncouples the cell factories from the controls when the user dismisses the form? Is this a problem with event listeners (or anything that is commonly addressed by using inner classes) in general? Is it wise to always deregister event or action handlers before an object is released?
EDIT:
Many of these same issues have been handled in this post: When exactly is it leak safe to use (anonymous) inner classes?.
I guess I am inclined to believe that for this situation, in which the windows may be repeatedly constructed and dismissed, that I will need to try and null out any potentially long-lived reference to the JavaFX controller class; most especially the cell factories.