Développer un module JavaScript pour GWT

Dans cet article, nous allons voir comment développer puis intégrer un module écrit en JavaScript dans une application Web codée en GWT.

En tant que développeur GWT, et dans certains cas, vous aurez besoin d’écrire votre propre code JavaScript pour, par exemple, accéder à des fonctionnalités du navigateur non exposées par les API de GWT, ou si vous êtes courageux et que vous souhaitez réécrire des composants proposés par GWT. Et de manière générale, disons que vous souhaitez combler les limites de GWT avec vos propres librairies JavaScript. Pour ce faire, nous allons nous baser sur une fonctionnalité proposée par le frameworks, JSNI.

JSNI

JSNI ou JavaScript Native Interface nous permet d’écrire directement du code JavaScript dans le code source Java. Partant du principe que GWT compile votre code Java pour en générer du code JavaScript, qui sera interprété par le navigateur, il vous est donc tout à fait possible d’injecter votre propre code JavaScript. Cependant, faites très attention, car le compilateur aura beaucoup de mal à optimiser votre code JavaScript. Donc, pensez à écrire du code multi-navigateurs, propre et irréprochable ^^

Méthodologie

Même si JSNI recommande d’injecter directement votre code JavaScript dans vos classes Java, et par « code JavaScript » je veux dire votre logique applicative ; je ne suis pas vraiment d’accord avec cette pratique et voici pourquoi.

Etant avant tout un développeur JavaScript, je préfère — dès que je peux — coder mes modules en JavaScript sans se soucier ni de leurs intégration avec GWT ni de JSNI. Je pars donc du principe que mes modules seront indépendants ainsi je pourrais les utiliser en « Vanilla » ou jQuery, ou si je veux je peux les instancier depuis NodeJS ou encore les intégrer dans GWT grâce à JSNI. Cette méthode a également l’avantage de séparer le code JavaScript du code Java, ce qui est une bonne pratique, à mes yeux.

Bien évidemment, si vous pensez que votre code JavaScript sera très lié à votre application GWT, vous pouvez/devez suivre les recommandations de JSNI et « cracher » votre code JavaScript directement dans votre code source Java.

Passons maintenant aux choses sérieuses…

Préparer le code JavaScript

La première chose à faire, si vous suivez ma méthode, est de préparer votre module JavaScript. Voici le module que je vais utiliser comme exemple :

Veuillez noter au passage, que j’utilise le pattern Module en JavaScript pour ne pas polluer l’espace de nom globale et déclarer mon module dans un espace « isolé ».

Ensuite, nous le déposerons dans le répertoire war/ du projet GWT comme illustré dans la figure ci-dessous :

DemoGauge 2013-08-18 02-19-29

Et nous n’oublierons pas de l’inclure dans la page HTML :

Passons ensuite à l’écriture de nos méthodes natives en JavaScript.

Méthodes natives en JavaScript (JSNI)

La première chose à savoir, et cela va de soi, les méthodes natives JSNI sont déclarées avec le mot clé native et contiennent du code JavaScript entouré par un commentaire bien définit, commençant par /*-{ et se terminant par }-*/ ce qui donne ceci :

Si nous devions donc appeler notre module JavaScript depuis JSNI, nous l’aurions fait comme ceci :

Veuillez noter dans un premier temps que dans le code JSNI, nous utilisons $wnd et $doc pour référencer window et document.

Dans ce code, j’ai créé une classe Java JsGauge qui implémente une interface JsGaugeInterface que j’ai défini. Cette classe possède un constructeur et deux méthodes JSNI (pour l’exemple). Une fois instanciée, cette classe exécute la méthode JSNI privée newGauge() qui exécute du code JavaScript et instancie un objet JsGauge.

Aussi, vous avez surement noté la présence du type JsGaugeInterface.Options passé en paramètre à la méthode draw(). Dans cette interface, je définis un type Options permettant de passer un objet de configuration — un objet littéral JavaScript — à la méthode draw() du module JsGauge.

Pour pouvoir réaliser cela, j’ai préféré suivre les recommandations de JSNI et écrire mon code JavaScript dans la classe Java. Tout simplement parce c’est la façon la plus simple pour jongler avec les paramètres.

Donc, pour cela il faut que la classe Options remplisse deux critères :

  • qu’elle étende la classe JavaScriptObject ;
  • que son constructeur soit défini en protected.

Et voici un exemple de cette classe :

Vous remarquerez que nous utilisons une méthode statique create() pour créer un objet — oui un objet littéral dans le monde de JavaScript — qui est retourné typecasté en type Options, dans le monde de Java, que nous allons pouvoir manipuler en Java.

Arrivé à ce stade, nous sommes en mesure d’instancier les classes JsGauge et Options et les utiliser dans notre projet GWT. Mais si vous voulez aller plus loin, sachez que JSNI vous permet également d’invoquer vos méthodes Java depuis vos modules JavaScript. Et voici comment.

Accès aux méthodes/constructeurs Java depuis JavaScript

JSNI nous permet d’invoquer nos méthodes Java directement depuis JavaScript. Cependant, dû au typage dynamique de JavaScript, ces accès doivent respecter une syntaxe bien définie :

Explications :

  • instance. : cette expression doit être présente si l’objet (Java) est une instance de la classe. Si l’appel se fait sur une classe statique, cette expression doit être ignorée ;
  • nom-classe : le nom complet de la classe dans laquelle la méthode a été définie ;
  • nom-methode : correspond au nom de la méthode à invoquer. Si cette méthode est un constructeur, alors le nom de la méthode sera la chaine new ;
  • signature-param : la signature interne en Java de la méthode comme définit par JSNI (voir la documentation) ;
  • arguments : la liste des paramètres de la méthode, respectant la signature de la méthode.

En procédant ainsi, vous allez pouvoir appeler vos méthodes Java si l’utilisateur clique sur un bouton, ou suite à un évènement de callback par exemple.

Conclusion

JSNI est un mécanisme très puissant offert par GWT permettant de combler les limites du framework.

Cet article n’était qu’une sorte d’introduction à JSNI, je vous recommande vivement de lire la documentation officielle si vous voulez aller encore plus loin avec JSNI.

 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

dix − 2 =