Mois : janvier 2009

Tests croisés et revue de code

Nous avons démarré depuis lundi le sprint 17. Les résultats des sprints précédents nous ont permis de concentrer nos efforts sur les tests et la revue de code croisés.

Ces actions ne se substituent pas aux tests fonctionnels réalisés mais permettent d’améliorer la qualité des développements tout en favorisant un partage et une communication dans l’équipe.

En terme d’organisation comment ça marche ? Tous les matins lors du scrum, chacun choisit en plus de ses engagements quotidiens une tâche déjà développée par un autre membre de l’équipe pour la tester ou faire de la revue de code.

Le lendemain matin, les problèmes soulevés lors des tests croisés et des éventuelles revues de code sont souvent résolus : le « testeur » a corrigé, ou le pair-programming a fonctionné !

Bref : une excellente communication entre tous les membres de l’équipe et une qualité éprouvée …Aucune ombre au tableau !

GWT et Drag and Drop

Le « glisser-déposer », ou Drag and Drop, n’est pas géré nativement par GWT.

Afin de palier à ce manque, un certains nombres d’implémentations ont été élaborées.
Le choix de Viaxoft s’est porté sur dnd-gwt, et ceux pour deux raisons :

  • Cette API présente l’avantage d’être non invasive, de n’impliquer aucune génération de code annexe.
  • « dnd » permet la réutilisation directe des widgets de GWT et de nos composites.

Cette note survole les grands principes autours desquels s’articule cette librairie.

containingPanel.setPixelSize(w, h);
containingPanel.getElement().getStyle().setProperty("position","relative");
PickupDragController dragController = new PickupDragController(containingPanel, true);//Paramétrage du comportement DnD
//On interdit les selections mulitples et aux Widgets draggables d'être déposés hors des drop zones
dragController.setBehaviorBoundaryPanelDrop(false);
dragController.setBehaviorMultipleSelection(false);

Une fois un DragController défini, n’importe quel widget implémentant SourcesMouseEvents peut être transformé en élément « draggable ». On pourrait donc penser être limité aux Image, Label et FocusPanel. Cependant tout composite implémentant l’interface est lui-même éligible. Le DragController permet notamment de distinguer un composite dans son ensemble de sa partie réalisant le Drag & Drop.

class TextAndPicto extends Composite implements SourcesMouseEvents{
TextField text;
Image picto;
public LabelAndPicto(TextField text, Image picto)
{
this.text = text;
this.picto=picto;
HorizontalPanel mainPanel = new HorizontalPanel();
mainPanel.add(picto);
mainPanel.add(text);
initWidget(mainPanel);
}

public void addMouseListener(MouseListener listener) {
picto.addMouseListener(listener);

}

public void removeMouseListener(MouseListener listener) {
picto.removeMouseListener(listener);
...

TextAndPicto w = new TextAndPicto(new TextBox(), new Image("pictoViaxeo/clients.gif"));
dragController.makeDraggable(w,w.getImage());
Enfin le DropController permet de définir le comportement des widgets sur lesquels pourront être déposés les éléments « draggables ». Le constructeur prend en paramètre le widget qui servira de « drop zone », et les 4 méthodes suivantes sont définies par l’interface afin de gérer son comportement : onEnter, onLeave, onDrop et onPreviewDrop. Les deux premières sont appelées lorsqu’un item est « dragué » au dessus de la drop zone. La troisième détermine les actions à prendre consécutivement à la dépose du dit item. Et enfin, onPreviewDrop permet d’effectuer des contrôles préalables avant l’exécution d’onDrop.
  public class DropZoneListener extends SimpleDropController {
private VerticalPanel panel;

public DropZoneListener(Widget dropTarget) {
super(dropTarget);
panel = (VerticalPanel)dropTarget;
}

public void onDrop(DragContext context) {
super.onDrop(context);
for(SmartWidget smartWidget : (List)context.selectedWidgets)
panel.add(smartWidget);
}

public void onEnter(DragContext context) {
super.onEnter(context);
panel.addStyleName("viaxeo-DnD-Liste-Header-seleted");
}

public void onLeave(DragContext context) {
super.onLeave(context);
panel.removeStyleName("viaxeo-DnD-Liste-Header-seleted");
}

public void onPreviewDrop(DragContext context) throws VetoDragException {
super.onPreviewDrop(context);
}

}
Dnd-gwt propose un large panel de DropController allant du GridConstrainedDropController (gestion du drop par grilles) au FlexTableRowDropController (ajout/suppression dynamique de lignes dans une FlexTable).

GWT et éditeur de texte riche : impossible ?

Au cours du développement du produit, nous avons été confronté à un problème imprévu : l’intégration d’un éditeur de texte riche au sein d’une application écrite en GWT.

En effet, nous désirions laisser la possibilité à l’utilisateur de créer ou modifier une page web en mode WYSIWYG directement depuis l’application, mais l’éditeur proposé par GWT ne nous paraissait pas suffisant.

Après une rapide analyse des solutions existantes, nous avons tout d’abord décidé d’utiliser FCKeditor, celui-ci semblant offrir le plus grand nombre de fonctionnalités sur le marché à l’heure actuelle.
Nous sommes pour cela repartis de gwt-html-editor que nous avons adaptée à nos besoins. Cependant, si cette solution fonctionnait parfaitement lors de nos tests en hosted mode, dès le premier test de l’application déployée, nous avons rencontré des problèmes :

  • comportements différents selon les navigateurs
  • problèmes lors du premier chargement du composant
  • problèmes lors du rechargement du composant

Ces problèmes étant impossibles à résoudre facilement, nous avons décidé de tester les solutions concurrentes : XinhaTinyMCE et Yahoo! editor.
Mais celles-ci se sont avérées souffrir des même problèmes que FCKeditor. En effet, ces éditeurs ont été conçus pour fonctionner au sein d’une application web « classique », et ne sont pas adaptés pour une application entièrement enAJAX, comme celles réalisées en GWT.

Suite à ce constat, nous avons choisi de privilégier une solution hybride : la visualisation du texte riche se fait dans une iframe au sein de l’application, mais son édition se fait dans une page web classique présentée en popup.

Le composant s’articule autour de trois fichiers :

  • FCKRichEditorImpl.java, le composant en lui-même
  • iframeFckEditor.html, la page web affichant le rendu au sein d’une iframe (l’iframe permet d’avoir un style propre à la page affichée, ce que ne permettait pas l’utilisation d’un setInnerHTML (), par exemple)
  • pageFckEditor.html, la page en popup permettant d’éditer le texte grâce à FCKeditor

Cette solution fonctionne parfaitement et ne souffre pas des problèmes cités précédemment, mais elle en apporte cependant deux nouveaux :

  • moins bonne intégration de l’édition de texte avec le reste de l’application
  • possibilité de problème avec les bloqueurs de popup

C’est pourquoi nous restons à l’écoute du marché, et surveillons avec attention les nouvelles solutions disponibles.

Si vous désirez le code de notre solution n’hésitez pas à nous contacter

Loading...
X