Seiten

Freitag, 30. August 2013

How to setup a JavaFX / CDI Component

With cdi-commons it is very easy to start with an JavaFX / CDI Component/Application.

As an example we will start with an small Table-App with i18n and CDI.

image

 

You need the following steps:

01) create the empty Controller;

image

02) create the Root JavaFX Component

image

03) create the fxml-file

image

04) create the i18n-properties

image

05) create the KeyMapper-Class

image

06) create the transient Row-Class

image

07) create the TableFilters

image

image

08) create the RowComparator

image

09) create the DemoDataBuilder

image

10) implement the Controller methods

image

11) create the jUnit Test-Class

image

12) start implementing the Workflows….

Samstag, 24. August 2013

Finally at maven-central available

Finally we are available at the official maven repo.

image

Additionally we changed some pieces of our infrastructure.

The different bitbucket git repos are now merged to one called RapidPM-Modules.

You can find this at (BItbucket-RapidPM-Modules). The old repos are deleted and with an info message that ist redirecting to the new one

The issuetracking is back at http://jira.rapidpm.org.

Mittwoch, 14. August 2013

JavaFX/CDI Bootstrap – Add On

A few days ago I was writing about the JavaFX/CDI Bootstrap.
There are a few small changings until now.
The final jUnit-Class (extends JavaFXBaseTest ) will implement the method –> testImpl(final Stage stage).
The jUnit-Test will be a manged instance itself.
This is right.. but I forgot to Inject the a few things.
First the JavaFX component that is managed:
The jUnit example (CDIJavaFXBaseApplication001Test, you will find this at cdi-commons-fx) is using the LoginPane.
This is changed from an empty class to the following implementation

Now you have to modify the fxml based on this first version.


At this version you had to declare the controller itself. This can be done later by the init-phase. And the root – element was an pure GridPane.
The new version looks like this:
The root – element is now the self defined class LoginPane and the the controller definition is removed. So you can inject a controller at runtime depending on the ContextResolver.

The jUnit-Test itself changed a little bit. At the first version we used the fxml-Loader to get the LoginPane.. This can now be done by an Inject. (@Inject LoginPane root; )

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


Freitag, 2. August 2013

Grundgedanke: Warum CDI

Grundgedanke: Warum CDI? (Wiki)

CDI als eine Technik die auf der SE als auch auf der EE Seite zur Verfügung steht ist ein mächtiges Werkzeug um Quelltext in einer Anwendung zu entkoppeln.

Der modulare Aufbau kann auf einfache Art und Weise unterstützt und bei Alt-Anwendungen eingeführt werden.

kürzere Notation?
Manchmal ist die Notation per Inject kürzer. Sobald allerdings die einzelnen Qualifier dazukommen, ist meist der Aufwand zum Aufruf eines Konstruktors kaum unterschiedlich.

lösen von statischen Abhängigkeiten?
Dieser Punkt ist einer der Wesentlichen. Wie kann man zur Entwicklungszeit die Abhängigkeiten zu den anderen Projektmodulen möglichst gering halten?
Gehen wir von der Definition einer Liste aus. Als Rückgabewert einer Methode wird die List verwendet.

Definition Rückgabewert

image

Damit sind nachfolgende Aufrufer nicht mehr an die Implementierung der List gebunden. In der Methode jedoch besteht meist die Abhängigkeit zu der entsprechenden Implementierung obwohl auch das meist nicht notwendig ist.

Erzeugen der Liste

image

Gehen wir davon aus, dass keine spezifischen Methoden der ArrayList verwendet werden. Selten werden Methoden wie z.B. trimToSize() verwendet. Somit ist die statische Abhängigkeit zu der ArrayList nicht notwendig. Sollte sich zur Laufzeit herausstellen, das die Wahl dieser Implementierung nicht optimal gewesen ist, muss der Quelltext angepasst und neu verteilt werden. Mit std SE Mitteln kann man das durch entsprechende Factories lösen. Beispielhaft soll hier folgende Implementierung verwendet werden.

Definition ListFactory

image

Der Entwickler selbst schreibt nun seinen Quelltext unter Verwendung der Factory. Die Factory sollte unter Umständen immer neu erzeugt werden, um Nebenläufigkeitsprobleme sofort auszuschliessen. Selbstverständlich kann auch die Factory threadsave programmiert werden, im schlimmsten Fall mit den Schlüsselwort synchronized.

Verwendung ListFactory

image

Bisher wurde nun die statische Abhängigkeit zur ArrayList verhindert, die Entscheidung eine ArrayList zu nehmen ist jedoch immer noch expliziet gefallen.

Umgehen kann man das durch die Verwendung der ListFactory. 

Die Implementierung der ListFactory selber hat auch wieder die statischen Abhängigkeiten zu allen vorgesehenen Implementierungen. 

Der nächste Schritt kann ein ContextRsolver sein, der in die Factory eingebunden wird und zur Laufzeit die Wahl der Implementierung trifft.

Der ContextResolver wird entweder beim Methodenaufruf übergeben, oder bei der Initialisierung der Factory erzeugt/übergeben/geholt.

Möchte man nun die Factory so erstellen, das diese wiederum nicht statische Abhängigkeiten zu den jeweiligen Contexten bzw Implementierungen der Liste hat, muss eine Registry gebaut werden.

Dort kann man zur Laufzeit die jeweiligen Implementierungen registrieren und für eine Auflösung zur Verfügung stellen.

Spätestens ab diesem Zeitpunkt wird die Implementierung aufwendig, da man entweder diesen Mechanismus für alle Implementierungen vorhalten muss, oder eine generische Implementierung notwendig ist.

Hier Hilft CDI durch seine Konzepte, ohne das man sich mit der Basisimplementierung der Infrastruktur beschäftigen muss. 

 

Wie ist nun die Lösung mittels CDI?

Für den Entwickler sieht die Verwendung exemplarisch (CDILegacyTest) wie folgt aus.

Def List per CDI

image

Die Verwendung erfolgt wie gewohnt. Das AnnotationsLiteral CDILegacyTest gibt an, welcher Producer zu wählen ist.

Def ListProducer

image

Fertig sind wir.

dynamische Rekonfiguration?

CDI stellt eine sehr angenehme Basis zur Erzeugung dynamisch rekonfigurierbarer Systeme dar. Das Konzept der Instance<T> ist hier der Einstiegspunkt.

In der Definition der Attribute wird der Proxy Instance<T> verwendet.

Def List-Instance

image

Zu dem Zeitpunkt wenn auf die Variable zugegriffen werden muss, wird per get() die konkrete Implementierung geholt.

Verwendung der Liste

image

Damit kann die Entscheidung von der Erzeugung der verwendenden Instanz auf den Zeitpunkt der Verwendung verschoben werden.

In diesem Moment sollten im System hinreichend Informationen zur Verfügung stehen um die richtige Implementierung wählen zu können. Das Konzept basiert auf einem ContextResolver.

In diesem werden die Zustandsinformationen der Laufzeitumgebung, des Benutzers und was immer notwendig ist aggregiert und führen zu einer deklarativen Entscheidung.

Das Ergebnis ist ein umgebungsspezifisches AnnotationsLiteral mit dessen Hilfe die zur Verfügung stehenden Producer ausgewählt werden. Fertig ist das dynamisch rekonfigurierbare System.

Die Implementierung des ContextResolvers kann wiederum lean selektiert werden (Zwinkern)

Donnerstag, 1. August 2013

cdi.commons.logger - ProgrammingHandbook - RapidPM

Die Definition eines Loggers gehört zu fast jeder Klasse. Immer wieder ist der Logger zu definieren und in diesem Zuge dann auch die Entscheidung zu treffen, welcher Logger zu verwenden ist.
Nachträglich dieses zu ändern bedeutet immer, alle Klassen zu modifizieren. Es geht auch anders..
... siehe 
cdi.commons.logger - ProgrammingHandbook - RapidPM:

'via Blog this'

CDI MessageBus

Working on migration projects, I often have to share data between the old Swing part and the new JavaFX part.

To send data in a SE-environment from part A to part B you can use a MessageBus. Based on the Guava – EventBus 

you can use the cdi-commons MessageBus now.

The code is available at (https://bitbucket.org/svenruppert/cdi-commons)

On producer and consumer – side you will get the MessageBus per inject.

image      

The consumer has to implement an MessageBusCallback<T> with the consumer method.

image

An example is available as jUnit-Test (MessageBusTest)

image

The Class TestCallbackData is a pojo itself.

After you register the Callback instance with messageBus.registerCallBack(callBack); the consumer is ready to work.

If you don´t want to get the messages anymore, call messageBus.destroyCallBack(callBack);

The producer “only” has to fill the message with the data and send this via messageBus.post(message); Thats it!!

image

 

Finally the full UML-diagramm.

 

image