Créer un événement personnalisé pour GWT 1.6
Par Patrice le mardi 26 mai 2009, 17:49 - GWT - Lien permanent
Dans une application métier on a souvent besoin de créer des composants personnalisés mais surtout que ces composants puissent envoyer un évènement personnalisé. Depuis GWT 1.6, le système d'évènements a été repensé pour être plus extensible. Voici donc un petit tutorial pour comprendre comment créer notre évènement.
Commençons par créer un composant personnalisé, faisons quelque chose de simple, un champ TextBox avec une image à gauche. Pour cela créons une classe qui étend Composite, et dans le constructeur créons un HorizontalPanel et ajoutons-y une Image et un TextBox :
Maintenant dans notre EntryPoint, mettons simplement :
Cela nous donne ce résultat :
Voilà, maintenant nous avons créé notre propre composant, nous aimerions bien pouvoir faire du code spécifique dans notre classe TestEvent dès que notre TextBox change de valeur pour par exemple valider le contenu.
Pour cela, il nous faut déjà nous enregistrer à l’évènement ChangeEvent du composant TextBox en utilisant la fonction addChangeHandler(), et lui passant un ChangeHandler. Le ChangeHandler est une interface qui demande d’implémenter la fonction onChange() qui sera alors appelée par le TextBox dès que la sa valeur changera. Ajoutons alors un peu de code dans la classe MyComponent pour afficher une boite de dialogue Javascript lors de l’évènement ChangeEvent du TextBox :
Avec cet exemple, nous comprenons alors le principe du Handler, c’est la fonction qui sera appelée lors de l’envoi d’un évènement. Un évènement est la classe qui contient les informations de l’évènement (par exemple le composant source, les coordonnées de la souris, etc …) et la méthode add*Handler() permet d’enregistrer un Handler à un évènement donné par le composant.
Maintenant comment pouvons-nous afficher notre boîte de dialogue dans la classe principale TestEvent ?
Nous pourrions de la même façon récupérer le TextBox et ajouter notre évènement dessus, mais nous perdrions le principe de notre composant : on ne doit pas pouvoir accéder aux composants internes de celui-ci.
Il faut donc que nous créions notre propre évènement et l’envoyions lors de l’évènement onChange du TextBox. Pour cela, il faut créer 3 éléments :
- *Event : La classe qui représente notre évènement, dans laquelle nous pouvons ajouter des informations que nous voulons faire passer par l’évènement (objet source, valeur modifié, etc …). Elle étend la classe abstraite GwtEvent<*Handler>.
- *Handler : Interface qui décrit le prototype de la fonction qui sera appelée lors de l’envoi de l’évènement et que chaque classe qui veut réagir à celui-ci devra implémenter. La fonction est souvent de la forme on*(*Event event); Elle étend l’interface EventHandler.
- Has*Handlers : Interface qui étend l’interface Hashandlers et qui décrit le prototype de la fonction add*Handler() qui permet de s’abonner à l’évènement. Cette interface devra être étendue par tous les composants qui enverront ce type d’évènement.
Il faut bien sûr remplacer l’étoile par le nom de votre évènement. Créons maintenant notre évènement ValidEvent, cette évènement sera envoyé lors du changement de la valeur du TextBox dans notre composant.
Commençons par créer notre interface ValidHandler qui étend EventHandler et qui contient simplement une methode onValid(ValidEvent event);
La classe Event doit étendre la classe abstraite GwtEvent<EventHandler> et doit implémenter trois méthodes :
- public GwtEvent.Type<*Handler> getAssociatedType() : Retourne le type de l’évènement : typiquement retourne le type créé en variable locale (par private static final GwtEvent.Type<*Handler> TYPE = new GwtEvent.Type<*Handler>())
- protected void dispatch(*Handler handler) : Cette fonction doit simplement appeler la methode créée dans le handler : on*(*Event event);
- static public GwtEvent.Type<*Handler> getType() : Cette méthode n’est pas obligatoire mais sert pour implémenter la méthode add*Handler() de l’interface Has*Handler(). Elle fonctionne comme getAssociatedType sauf qu’elle est statique.
Voici donc notre classe ValidEvent :
Nous avons ajouté un champ à notre évènement pour qu’il puisse contenir le contenu de la TextBox qui a changé. Ces paramètres dépendent de nos évènements métier et des informations que l’on veut envoyer en même temps que l’évènement.
Il nous reste simplement l’interface HasValidHandlers qui étend l’interface Hashandlers et qui contient la déclaration de la méthode pour ajouter notre handler au composant qui l’envoie. Cette fonction de la forme add*Handler prend le Handler en paramètre et retourne un HandlerRegistration.
Chaque composant qui veut envoyer cet évènement (enfin surtout permettre à d’autres composants de s’inscrire à cet évènement) n’a simplement qu’à implémenter cette méthode, en utilisant la méthode addHandler qui est définie dans la super classe Widget. Cette méthode prend en paramètres le handler à enregistrer et le type de l’évènement que l’on peut récupérer grâce à la méthode getType() précédemment décrite.
Implémentons l’interface HasValidHandler à notre composant MyComponent en ajoutant cette méthode :
Maintenant il nous reste juste une chose, c’est envoyer notre évènement, pour cela la classe contient la methode fireEvent(GwtEvent<?> event); qui permet d’envoyer l’évènement, c’est GWT qui s’occupe ensuite d’appeler tous les Handlers qui sont enregistrés pour l’évènement envoyé. Modifions maintenant notre composant pour envoyer notre évènement :
Il nous reste une dernière chose, c’est de s’enregistrer à notre évènement sur notre composant depuis notre classe principale et d’ajouter notre code métier (juste l’afficher avec une boite de dialogue).
Nous venons maintenant de créer notre propre évènement.

Commentaires
Excellent article !