Inject @FXMLLoader with a qualifier to bind it to a specific view
Currently, one can use @FxView on a controller to link resources (fxml, css, bundles) to it which will be constructed on startup. Then inject FxViewRepository to access it, something like:
@FxView("login")
@Singleton
public class LoginController {
public void prepareLogin(){...}
}
@FxView("core")
@Singleton
public class CoreController {
@Inject FxViewRepository fxViewRepository;
@FXML BorderPane root;
@FXML
void initialize() {
if (!isLoggedIn()) {
var loginViewData = fxViewRepository.getViewData("login");
root.setCenter(loginViewData.getRootNode());
loginViewData.<LoginController>getController().prepareLogin();
}
}
}
or inject FXMLLoader to load the view on demand:
@FxView("core")
@Singleton
public class CoreController {
@Inject FXMLLoader fxmlLoader;
@FXML BorderPane root;
@FXML
void initialize() {
Parent loginRoot = fxmlLoader.load(getClass().getResourceAsStream("/login.fxml"));
root.setCenter(loginRoot);
fxmlLoader.<LoginController>getController().prepareLogin();
}
}
It would be nice to be able to inject FXMLLoader and bind it to a view using a qualifier (making @FxView a qualifier?), something like:
@FxView("core")
@Singleton
public class CoreController {
@Inject @FxView("login") FXMLLoader fxmlLoader;
@FXML BorderPane root;
@FXML
void initialize() {
Parent loginRoot = fxmlLoader.load();
root.setCenter(loginRoot);
fxmlLoader.<LoginController>getController().prepareLogin();
}
}
Why don't you directly inject LoginController in the CoreController ?
Why don't you directly inject
LoginControllerin theCoreController?
Maybe it is not a good example what I provide. What I mean is to create a new view and not use the existing instance in FxViewRepository.
It could be better define different annotation and not to use @FxView, something like:
@FxView("core")
@Singleton
public class CoreController {
@Inject @FxViewLoader("message-dialog") FXMLLoader messageDialogFxmlLoader;
@FXML
void onButtonClicked() {
Dialog<?> messageDialog = messageDialogFxmlLoader.load(); // no need to invoke setLocation() nor setResources()
messageDialogFxmlLoader.<MessageDialogController>getController().setMessage("Hello World");
messageDialog.showAndWait();
}
}
@Dependant
public class MessageDialogController {
// ...
public void setMessage(String message) {
// ...
}
}
I'll have a look next !