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.

[pastacode lang=”java” message=”” highlight=”” provider=”manual”]

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);

[/pastacode]

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.

[pastacode lang=”java” message=”” highlight=”” provider=”manual”]

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());

[/pastacode]

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.

[pastacode lang=”java” message=”” highlight=”” provider=”manual”]

  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);
}

}

[/pastacode]

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).