Développer une application modulaire avec JTheque Core 2.0.3

Baptiste Wicht

Cet article va vous présenter les bases de la création d'une application modulaire avec JTheque Core.

Le présent document se base sur JTheque Core 2.0.3. Cette configuration ne fonctionnera pas avec une version moins récente du core.

Commentez ♪

Version anglophone de cet article - English version of this article: Develop a modular application with JTheque Core 2.0.3.

- Titre : Développer une application modulaire avec JTheque Core 2.0.3

- Auteur : Baptiste Wicht

- Parution : 30 août 2009

- Mise à jour : 29 décembre 2009

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2009 Baptiste Wicht. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- 1. Introduction

- 2. Environnement de JTheque

- 3. Développement de l'application

- 4. Développement du premier module

- 5. Ajout d'un second module

- 6. Conclusion

- 6-1. Sources

- 6-2. Remerciements

1 - Introduction

Cet article va vous apprendre à développer une première application toute simple avec JTheque Core.

On va développer une application modulaire très basique, un peu à la manière d'un hello world. Ce petit programme va se composer de :

- une application au sens JTheque Core ;

- un module qui va afficher un Hello World sur la vue principale ;

- un module qui va rajouter une option de menu pour afficher encore une fois Hello World.

2 - Environnement de JTheque

La première chose à faire avant de commencer à développer notre application et nos modules est de télécharger « l'environnement de développement » JTheque Core. En effet, une application faite avec JTheque Core nécessite un certain nombre de fichiers.

Vous pouvez télécharger une archive contenant tous les fichiers nécessaires sur le site du projet. Il faut ensuite choisir le fichier dev-base-XXX.zip où XXX est le numéro de version du Core. Dans notre cas, il faut donc prendre dev-base-2.0.3.zip.

Une fois le fichier téléchargé, dézippez-le. Voici l'arborescence du dossier :

- core : contient JTheque Core, la configuration ainsi que l'application modulaire ;

- lib : contient les librairies nécessaires au fonctionnement de Jtheque ;

- modules : contient les modules de l'application ;

- JTheque-Launcher.jar : le lanceur de l'application. C'est le fichier qu'il faudra exécuter pour lancer l'application.

On n'aura donc que deux choses à changer dans cette arborescence. Premièrement, il faudra ajouter notre application (application.xml) et ses ressources dans le dossier core et ensuite, il nous faudra ajouter nos modules dans le dossier « modules » et les déclarer dans la configuration de JTheque.

3 - Développement de l'application

Maintenant que l'on a vu de quoi était composée une application JTheque, on va passer au développement de la première partie de notre programme, l'application.

Une application au sens JTheque est en quelque sorte le conteneur des modules. Une application a un nom, une version, mais n'ajoute aucune fonctionnalité, ce sont les modules qui s'en chargeront. Une application sans modules n'est donc pas utilisable et vice-versa.

Une application se compose de plusieurs choses :

- un fichier XML (application.xml) décrivant l'application ;

- des images (obligatoirement dans le dossier core/images) ;

- éventuellement des fichiers .properties i18n dans le dossier core/i18n.

Pour ce qui est de l'internationalisation de l'application, on peut définir directement les différentes valeurs dans le fichier application.xml ou utiliser des fichiers d'internationalisation au format i18n. C'est cette dernière solution qu'on va utiliser dans notre cas. Voici donc les deux fichiers à créer :

application.properties

name=JTheque Demos
author=Baptiste Wicht
email=baptistewicht@redaction-developpez.com

application_fr.properties

site=http://jtheque.developpez.com/
copyright=JTheque 2009 Tous droits réservés

application_en.properties

site=http://jtheque.developpez.com/en
copyright=JTheque 2009 All rights reserved

Ensuite de quoi, on peut écrire le fichier XML. Voici le fichier XML nécessaire à cette demo :

application.xml

<?xml version="1.0" encoding="UTF-8"?>
<application version="1.0">
<i18n>
<languages>
<fr />
<en />
</languages>

<files />
</i18n>

<logo image="logo" />
<icon image="icon" />
</application>

On a donc déclaré que notre application est disponible en français et en allemand. En plus de cela, on déclare (<files />) qu'on utilise des fichiers i18n properties.

Le core supporte l'anglais, le français et l'allemand.

Pour ce qui est des images, on déclare utiliser un fichier logo.png et un fichier icon.png pour l'application. On pourrait une autre extension en spécifiant l'attribut type=« jpg » par exemple pour le fichier .jpg.

Voici les icônes qui ont été utilisées :

L'icône pour les fenêtres

Le logo du module

On va maintenant tenter un essai. Pour cela, il suffit de lancer le fichier JTheque-Launcher.jar à la racine du dossier JTheque. Il va se charger de lancer le core avec votre application.

Voici ce qui en résulte :

Lancement sans module

On peut donc voir que l'application se lance bien, mais on ne peut rien faire de très intéressant dans cette application étant donné qu'aucun module ne fournit de
fonctionnalités intéressantes.

4 - Développement du premier module

Maintenant que notre application a été développée et qu'elle fonctionne, on va passer au développement du premier module de notre application.

Ce module sera très simple, il va modifier le composant principal de la vue de l'application et y afficher Hello World de manière internationalisée.

Pour déclarer un module, il faut créer une classe portant l'annotation @Module. Ensuite de quoi, il faut les déclarer dans le contexte Spring et déclarer ce dernier dans le manifest du Jar du module.

Il n'est pas nécessaire de connaître Spring pour utiliser JTheque. Si vous ne comptez pas utiliser Spring dans votre application, il suffit juste de déclarer le module dans le contexte minimal de Spring et de développer ensuite le reste de votre application sans tenir compte du module. Il faut néanmoins savoir que le module sera instancié par Spring.

Le cycle de vie d'un module passe par trois états :

- pre-plug : il s'agit de préconfiguration ;

- plug : il s'agit de l'ajout proprement dit du module dans l'application, c'est-à-dire modification de la vue, ajouts d'élément de configuration ;

- unplug : il s'agit de l'extinction du module.

Pour effectuer des opérations dans ces trois phases, il faut utiliser des annotations sur des méthodes de votre choix, respectivement @PrePlug, @Plug et @Unplug. C'est l'application qui se chargera de détecter ces méthodes et de les invoquer.

Dans notre cas, on aura seulement besoin de modifier le composant principal de la vue durant la phase plug. Nous n'avons donc pas besoin des phases pre-plug et unplug.

Commençons déjà par déclarer notre module avec les annotations nécessaires :

package org.jtheque.demos.first;

import org.jtheque.core.managers.module.annotations.Module;
import org.jtheque.core.managers.module.annotations.Plug;

@Module(id = "jtheque-demo-module-1", i18n = "classpath:org/jtheque/demos/first/i18n/first", version = "1.0", core = "2.0.3",
jarFile = "jtheque-demo-module-1.jar")
public final class DemoFirstModule {
@Plug
public void plug(){

}
}

Là encore, ça n'a rien de compliqué. L'annotation Module déclare les informations sur le module. Les deux méthodes sont pour le moment complètement vides. L'annotation i18n contient le chemin (selon les conventions Spring) vers le resource bundle du module.

Maintenant, on va pouvoir déclarer les informations sur le module dans les fichiers d'internationalisation.

Un fichier d'internationalisation est un simple fichier .properties qui contient une liste de couples clé/valeur. Un fichier d'internationalisation représente une langue. On utilise un ensemble de ces fichiers pour internationaliser l'application. Ils doivent porter le même nom de base et se terminer par _langue ou langue est la forme abrégée de la langue concernée (de, fr, en, it…).

Les clés qui vont y être cherchées dépendent de l'identifiant (id) du module. On ajoute aussi directement l'internationalisation de la vue principale :

first_fr.properties

jtheque-demo-module-1.name=JTheque Demo Module 1
jtheque-demo-module-1.author=Baptiste Wicht
jtheque-demo-module-1.description=Premier module de démo

label.message=Bonjour le monde !

first_en.properties

jtheque-demo-module-1.name=JTheque Demo Module 1
jtheque-demo-module-1.author=Baptiste Wicht
jtheque-demo-module-1.description=First demo module

label.message=Hello World !

L'application va automatiquement rechercher et résoudre ces messages pour internationaliser le module. On place ces fichiers dans le dossier : org/jtheque/demos/module/first/resources/18n

Pour étendre l'application ou accéder aux services de JTheque, il faut toujours passer par la classe Managers qui fournit un accès aux différents managers (services) de JTheque Core. Dans notre cas, on va avoir besoin d'accéder au IViewManager qui gère tout ce qui est de la présentation de l'application.

Pour ce qui est de la méthode plug(), on va juste devoir ajouter un JLabel avec un texte internationalisé. Dans JTheque, pour qu'un composant soit internationalisable, il faut implémenter l'interface Internationalizable et le rajouter dans ILanguageManager pour qu'il soit modifié lorsque la langue change. Dans le cas d'un label, ce composant existe déjà dans JTheque Core, il s'agit du JThequeI18nLabel qui prend directement en paramètre une clé d'internationalisation :

@Plug
public void plug(){
SwingUtils.inEdt(new Runnable(){
@Override
public void run(){
JThequeI18nLabel label = new JThequeI18nLabel("label.message");
label.setFont(label.getFont().deriveFont(36f));

Managers.getManager(IViewManager.class).setMainComponent(label);
}
});
}

C'est donc extrêmement simple. On récupère notre manager avec la classe Managers, ensuite de quoi, on modifie le composant principal et on indique qu'il faut utiliser le label internationalisé comme composant principal.

Maintenant on va déclarer notre module dans le contexte d'application Spring. Il s'agit en fait simplement d'un fichier XML :

first.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="firstModule" class="org.jtheque.demos.first.DemoFirstModule" lazy-init="false" />

</beans>

On place ce fichier au même niveau que DemoFirstModule. Pour ceux qui ne connaissent pas Spring, c'est exactement comme si on déclarait une instance de notre module avec le nom firstModule.

On va donc tester ce que donne ce module. Encore une fois, il va falloir générer un Jar de notre projet. Le Manifest du Jar doit comprendre le lien vers notre fichier XML. Voici donc ce que donne le fichier Manifest :

Manifest-Version: 1.0
Module-Context: org/jtheque/demos/first/first.xml

On génère ensuite notre fichier Jar et on le met dans le dossier modules de l'environnement JTheque sous le nom jtheque-demo-module-1.jar.

Maintenant il faut configurer JTheque pour qu'il prenne en compte notre module. Pour cela, il faut modifier le fichier config.xml dans le dossier core. On va donc ajouter le tag discovery permettant d'ajouter automatiquement les modules du dossier modules à l'application.

config.xml

<state class="org.jtheque.core.managers.module.ModuleConfiguration">
<discovery />
</state>

On peut maintenant tester le résultat en lançant JTheque-Launcher.jar et voici ce qu'on obtient :

Hello World

Comme on peut le voir, notre module s'est maintenant bien intégré dans notre application.

5 - Ajout d'un second module

On va maintenant créer un second module qui ajoutera une option de menu pour afficher un Hello World. On pourrait bien sûr faire cela dans le premier module, mais c'est surtout pour montrer comment créer plusieurs modules.

Pour ajouter les options de menu, on a juste besoin de la phase plug. Voici ce que donne le squelette de notre nouveau module (DemoSecondModule) :

@Module(id = "jtheque-demo-module-2", i18n = "classpath:org/jtheque/demos/second/i18n/second", version = "1.0",
core = "2.0.3", jarFile = "jtheque-demo-module-2.jar")
public final class DemoSecondModule {
@Plug
public void plug() {
}
}

Avec les fichiers d'internationalisation suivants :

second_fr.properties

jtheque-demo-module-2.name=JTheque Demo Module 2
jtheque-demo-module-2.author=Baptiste Wicht
jtheque-demo-module-2.description=Deuxième module de démo

dialog.message=Bonjour le monde !

second_en.properties

jtheque-demo-module-2.name=JTheque Demo Module 2
jtheque-demo-module-2.author=Baptiste Wicht
jtheque-demo-module-2.description=Second demo module

dialog.message=Hello world !

C'est donc quasiment la même chose que pour le premier module. On va maintenant ajouter une option au menu « Fichier ». Là encore, pour que l'action soit internationalisable, il faudrait la faire implémenter Internationalizable, mais encore une fois, cela existe déjà avec la classe abstraite JThequeAction qui prend en paramètre une clé d'internationalisation.

Voici donc notre action toute simple :

package org.jtheque.demos.second;

import org.jtheque.core.managers.view.able.IViewManager;
import org.jtheque.core.managers.view.impl.actions.JThequeAction;
import org.jtheque.core.managers.Managers;

import java.awt.event.ActionEvent;

final class HelloWorldAction extends JThequeAction {
HelloWorldAction() {
super("dialog.message");
}

@Override
public void actionPerformed(ActionEvent e) {
Managers.getManager(IViewManager.class).displayI18nText("dialog.message");
}
}

Rien de bien compliqué, on utilise le IViewManager pour afficher un texte internationalisé sous forme de boîte de dialogue. On peut maintenant ajouter cette action dans le menu de l'application en utilisant le manager IFeatureManager. Depuis JTheque Core 2.0.3, il existe une façon déclarative simple de créer des options de menu via l'interface Menu. Pour cela, on peut étendre la classe AbstractMenu et choisir les méthodes à redéfinir pour ajouter des menus (features).

@Plug
public void plug() {
Managers.getManager(IFeatureManager.class).addMenu(new DemoMenu());
}

private static final class DemoMenu extends AbstractMenu {
@Override
protected List<Feature> getFileMenuSubFeatures(){
return features(
createSubFeature(150, new HelloWorldAction())
);
}
}

On ajoute donc une sous-action au menu Fichier, avec notre action et on le place avec 150 comme index de position (0 est la première et 1000 est l'index de l'action quitter).

On crée ensuite le fichier XML de déclaration du module :

second.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="secondaryModule" class="org.jtheque.demos.second.DemoSecondModule" lazy-init="false" />

</beans>

On peut maintenant générer un nouveau fichier jar (jtheque-demo-module-2.jar) avec un nouveau Manifest :

Manifest-Version: 1.0
Module-Context: org/jtheque/demos/second/test.xml

Finalement, on peut tester en lançant JTheque Core. Et voici le résultat :

Nouveau menu

Hello world

Notre deuxième module est donc correctement lancé.

6 - Conclusion

Avec relativement peu de code, nous avons donc réussi à développer une application tout à fait modulaire comprenant deux modules, mais pouvant en accueillir de nombreux autres.

Les services offerts par JTheque sont bien plus nombreux que ceux présentés ici, si vous voulez en savoir plus, pour le moment, je vous invite à consulter la Javadoc de la dernière version du core. À terme, je vais écrire un guide pour présenter toutes les fonctionnalités de JTheque Core.

Si vous voulez commenter cet article, n'hésitez pas à vous exprimer dans le sujet lié : Commentez
Si vous voulez faire un commentaire, une suggestion ou vous exprimer sur le projet JTheque, n'hésitez pas à intervenir sur le forum dédié.

6-1 - Sources

L'application est directement disponible sous forme de fichier XML. Les sources des deux modules sont disponibles sous forme de projet Maven :

- application.xml

- JTheque Demo Module 1

- JTheque Demo Module 2

6-2 - Remerciements

Un grand merci à tomlev pour sa relecture.