Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inject @FXMLLoader with a qualifier to bind it to a specific view #75

Open
Eng-Fouad opened this issue Oct 8, 2024 · 3 comments · May be fixed by #79
Open

Inject @FXMLLoader with a qualifier to bind it to a specific view #75

Eng-Fouad opened this issue Oct 8, 2024 · 3 comments · May be fixed by #79

Comments

@Eng-Fouad
Copy link
Member

Eng-Fouad commented Oct 8, 2024

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();
    }
}
@Eng-Fouad Eng-Fouad linked a pull request Oct 9, 2024 that will close this issue
@CodeSimcoe
Copy link
Contributor

Why don't you directly inject LoginController in the CoreController ?

@Eng-Fouad
Copy link
Member Author

Eng-Fouad commented Oct 15, 2024

Why don't you directly inject LoginController in the CoreController ?

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) {
         // ...
    }
}

@CodeSimcoe
Copy link
Contributor

I'll have a look next !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants