Seiten

Samstag, 3. August 2013

cdi.commons.fx -JavaFX/CDI Bootstrap

The both technologies JavaFX and CDI are greate for itself.. but how to combine them? How I can get managed JavaFX - controller instances?
Starting from the JavaFX – side, we have to implement the Class extending javafx.application.Application. The importand method will be
public void start(Stage primaryStage) throws Exception
CDIJavaFXBaseApplication
image
 
With CDIContainerSingleton.getInstance() you will get an instance of the Weld-Container. After the normal JavaFX – init  there will be an event fired with the primaryStage as attribute. Now the primaryStage is available in an managed environment.
JAvaFX –> CDI
cdi.event().select(Stage.class, new AnnotationLiteral<CDIStartupScene>() {})
      .fire(primaryStage);
The observer will catch this event. Hownthis will be donw, I show with the excample jUnit-test.
(JavaFXBaseTest)
image
The final jUnit-Class (extends JavaFXBaseTest ) will implement the method –> testImpl(final Stage stage). The jUnit-Test will be a manged instance itself.
image
But how to get the manged controller class instance?
This is done by the FXMLLoaderSingleton used from the jUnit-test.
final FXMLLoader fxmlLoader = fxmlLoaderSingleton.getFXMLLoader(LoginPane.class);

During the process of loading the fxml-file the used FxmlLoader will get an instance of an ControllerFactory-Callback.
image
The importand lines are the following
image
The ControllerFactory->Callback.call() will give back a manged instance of the controller class.
Now you can use CDI inside the pojo-fx-controller class.
public class LoginController implements CDIJavaFxBaseController {
    // Standard FXML injected fields
 @FXML TextField loginField;
 @FXML PasswordField passwordField;
 @FXML Text feedback;
 
 // CDI Injected field
 @Inject LoginService loginService;
 
    // Default application parameters
 @Inject @CDIJavaFXBaseApp
    Parameters applicationParameters;
 
 @FXML protected void handleSubmitButtonAction(ActionEvent event) {
  feedback.setText(loginService.login(loginField.getText(), passwordField.getText()));
 }

 @Override
 public void initialize(URL location, ResourceBundle resources) {
  loginField.setText(applicationParameters.getNamed().get("user"));
 }
}

So we are done..  Happy coding ;-)

UML-Diagramm