Skip to content
This repository has been archived by the owner on Dec 8, 2017. It is now read-only.

GettingStarted

Fred Sauer edited this page Jul 18, 2015 · 7 revisions

GWT Version Compatibility Matrix

Please make sure your you GWT and gwt-dnd versions are compatible.

If you are using GWT version... Then use gwt-dnd version... Which uses gwt-dnd API version...
GWT 2.6.1 or newer gwt-dnd-3.3.4.jar 2.x
GWT 2.6.0 gwt-dnd-3.3.0.jar 2.x
GWT 2.5.1 gwt-dnd-3.2.3.jar 2.x
GWT 2.5.0 gwt-dnd-3.2.2.jar 2.x
GWT 2.4.0 gwt-dnd-3.1.2.jar 2.x
GWT 2.3.0 gwt-dnd-3.1.1.jar 2.x
GWT 2.2.0 gwt-dnd-3.1.0.jar 2.x
GWT 2.1.1 gwt-dnd-3.0.1.jar 2.x
GWT 2.1.0 gwt-dnd-3.0.1.jar 2.x
GWT 2.0.x gwt-dnd-3.0.1.jar 2.x
GWT 1.7.0 gwt-dnd-2.6.5.jar 2.x
GWT 1.6.4 gwt-dnd-2.6.5.jar 2.x
GWT 1.5.3 gwt-dnd-2.5.6.jar 2.x
GWT 1.5.2 gwt-dnd-2.5.6.jar 2.x
GWT 1.5.1 (1.5 RC2) gwt-dnd-2.5.6.jar 2.x
GWT 1.5.0 (1.5 RC1) gwt-dnd-2.5.6.jar 2.x
GWT 1.5M2 (1.5 Milestone 2) Do not use GWT1.5M2 as it does not work with gwt-dnd. -
GWT 1.4.62 (1.4 Update 2) gwt-dnd-2.0.7.jar 2.x
GWT 1.4.61 (1.4 Update) gwt-dnd-2.0.7.jar 2.x
GWT 1.4.60 (1.4) gwt-dnd-2.0.7.jar 2.x
GWT 1.4.59 (1.4 RC2) gwt-dragdrop-1.2.6.jar 1.x API
GWT 1.4.10 (1.4 RC1) gwt-dragdrop-1.1.jar 1.x API
GWT 1.3.3 gwt1.3.3-dragdrop-2007-11-02.jar 0.x API

Working examples

Try the working demo:

Adding gwt-dnd to an (Eclipse) GWT Project

  1. Download the latest gwt-dnd-<version>.jar and place it in a convenient location. * Note for Maven users: Releases are also available in Maven Central with groupId com.allen-sauer.gwt.dnd and artifact gwt-dnd.
  2. Create a GWT Eclipse project as instructed here: http://www.gwtproject.org/usingeclipse.html#creating
  3. Add the gwt-dnd jar to your project via one of these two methods: * Right-click on the project node in the Package Explorer and select 'Build Path > Add External Archives...'. Then, specify the location of the gwt-dnd-<version>.jar file. * Copy the gwt-dnd-<version>.jar file into your project's war/WEB-INF/lib directory. Then, in the Project Explorer view, right click the jar file and select 'Build Path > Add to Build Path'
  4. Make sure the GWT compiler can find the gwt-dnd source code. Modify your *.gwt.xml module to inherit gwt-dnd support:
```XML
<inherits name='com.allen_sauer.gwt.dnd.gwt-dnd'/>
```
  1. (Optional) if you want to play with the demo (examples), you'll need to grab those from the demo directory as there is no jar file for the demos (i.e. the com.allen_sauer.gwt.dnd.demo package). See the Using Source with Eclipse wiki for more details.

How to add drag-and-drop functionality to your project

  1. Construct a PickupDragController, passing in two arguments: * boundaryPanel: The area of your application where you'd like to drag widgets which is an AbsolutePanel or RootPanel. * allowDroppingOnBoundaryPanel: Decide whether widgets can be placed at any location in this area (true), or only on specific drop targets (false).

    PickupDragController dragController = new PickupDragController(...);
  2. For each drop target within the boundary panel: * Construct an appropriate DropController, e.g. SimpleDropController, AbsolutePositionDropController, FlowPanelDropController, IndexedDropController * Call DragController#registerDropController

    IndexedDropController dropController = new IndexedDropController(...);
    dragController.registerDropController(dropController);
  3. For each widget which is to be draggable: * Call either the one or two argument DragController#makeDraggable method, depending on whether the widget implements HasMouseDownHandlers directly, or is a complex widget which contains a drag handle widget that implements HasMouseDownHandlers

    dragController.makeDraggable(...);
  4. Depending on your use case, try using

```Java
dragController.setBehaviorCancelDocumentSelections(...);        
dragController.setBehaviorScrollIntoView(...);
```

A simple example (Your first drag-n-drop project)

  1. Follow the instructions above to create an Eclipse project with gwt-dnd support
  2. Modify the onModuleLoad() method in your EntryPoint class as follows:
```Java
public void onModuleLoad() {
  // ensure the document BODY has dimensions in standards mode
  RootPanel.get().setPixelSize(600, 600);

  // create a DragController to manage drag-n-drop actions
  // note: This creates an implicit DropController for the boundary panel
  PickupDragController dragController = new PickupDragController(RootPanel.get(), true);

  // add a new image to the boundary panel and make it draggable
  Image img = new Image("http://code.google.com/webtoolkit/logo-185x175.png");
  RootPanel.get().add(img, 40, 30);
  dragController.makeDraggable(img);
}
```

That's it, you're done.

Tips

  1. While the Eclipse IDE is not strictly necessary, having a good IDE such as Eclispe will make your life a lot easier. Certainly feel free to use your IDE of choice.
  2. Develop in standards mode rather than quirks mode. To learn more, start here: http://www.quirksmode.org/css/quirksmode.html.
  3. If using standards mode, and the body (i.e. RootPanel.get()) is going to be your boundary panel, you'll want to ensure that the body actually has height, either by adding (non absolutely positioned) content to the page or setting an explicit pixel size, e.g.:
```Java
// Ensure the document BODY has height in standards mode
RootPanel.get().setPixelSize(600, 600);
```
  1. Make sure you use an UncaughtExceptionHandler so that unexpected exceptions are not lost in Production Mode.
  2. Realize that Development Mode is slower than (compiled-to-JavaScript) Production Mode. So, if things feels sluggish, test your app in Production Mode to reassure yourself that your application will be fine.
  3. Be careful when adding a ClickHandler directly to your draggable widget (or its drag handle): * In IE the handler will only fire if drag sensitivity > 0 * In Firefox the handler will always fire when the mouse is clicked, even at the the end of drag operation

Another, more complicated example (Your second drag-n-drop project)

  1. Again, follow the instructions above to create an Eclipse project with gwt-dnd support
  2. Add this CSS to the HTML or CSS file in your project:
```CSS
@CHARSET "UTF-8";

.dragdrop-dropTarget-engage {
  background-color: #E0E8FF;
}

.getting-started-label {
  border: 1px solid #99AACC;
  background-color: #AACCFF;
  padding: 0.1em;
}

.getting-started-blue {
  border: 1px solid blue;
}
```
  1. Use this code in your EntryPoint class:
```Java
/*
 * Copyright 2007 Fred Sauer
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.mycompany.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

import com.allen_sauer.gwt.dnd.client.PickupDragController;
import com.allen_sauer.gwt.dnd.client.drop.AbsolutePositionDropController;
import com.allen_sauer.gwt.dnd.client.drop.DropController;
import com.allen_sauer.gwt.dnd.client.util.DOMUtil;

public class MyApplication implements EntryPoint {
  public void onModuleLoad() {
    // set uncaught exception handler
    GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
      public void onUncaughtException(Throwable throwable) {
        String text = "Uncaught exception: ";
        while (throwable != null) {
          StackTraceElement[] stackTraceElements = throwable.getStackTrace();
          text += throwable.toString() + "\n";
          for (int i = 0; i < stackTraceElements.length; i++) {
            text += "    at " + stackTraceElements[i] + "\n";
          }
          throwable = throwable.getCause();
          if (throwable != null) {
            text += "Caused by: ";
          }
        }
        DialogBox dialogBox = new DialogBox(true, false);
        DOM.setStyleAttribute(dialogBox.getElement(), "backgroundColor", "#ABCDEF");
        System.err.print(text);
        text = text.replaceAll(" ", "&nbsp;");
        dialogBox.setHTML("<pre>" + text + "</pre>");
        dialogBox.center();
      }
    });

    // use a deferred command so that the handler catches onModuleLoad2() exceptions
    DeferredCommand.addCommand(new Command() {
      public void execute() {
        onModuleLoad2();
      }
    });
  }

  private void onModuleLoad2() {
    // Create a boundary panel to constrain all drag operations
    AbsolutePanel boundaryPanel = new AbsolutePanel();
    boundaryPanel.setPixelSize(400, 300);
    boundaryPanel.addStyleName("getting-started-blue");

    // Create a drop target on which we can drop labels
    AbsolutePanel targetPanel = new AbsolutePanel();
    targetPanel.setPixelSize(300, 200);
    targetPanel.addStyleName("getting-started-blue");

    // Add both panels to the root panel
    RootPanel.get().add(boundaryPanel);
    boundaryPanel.add(targetPanel, 10, 10);

    // Create a DragController for each logical area where a set of draggable
    // widgets and drop targets will be allowed to interact with one another.
    PickupDragController dragController = new PickupDragController(boundaryPanel, true);

    // Positioner is always constrained to the boundary panel
    // Use 'true' to also constrain the draggable or drag proxy to the boundary panel
    dragController.setBehaviorConstrainedToBoundaryPanel(false);

    // Allow multiple widgets to be selected at once using CTRL-click
    dragController.setBehaviorMultipleSelection(true);

    // create a DropController for each drop target on which draggable widgets
    // can be dropped
    DropController dropController = new AbsolutePositionDropController(targetPanel);

    // Don't forget to register each DropController with a DragController
    dragController.registerDropController(dropController);

    // create a few randomly placed draggable labels
    for (int i = 1; i <= 5; i++) {
      // create a label and give it style
      Label label = new Label("Label #" + i, false);
      label.addStyleName("getting-started-label");

      // add it to the DOM so that offset width/height becomes available
      targetPanel.add(label, 0, 0);

      // determine random label location within target panel
      int left = Random.nextInt(DOMUtil.getClientWidth(targetPanel.getElement()) - label.getOffsetWidth());
      int top = Random.nextInt(DOMUtil.getClientHeight(targetPanel.getElement()) - label.getOffsetHeight());

      // move the label
      targetPanel.setWidgetPosition(label, left, top);

      // make the label draggable
      dragController.makeDraggable(label);
    }
  }
}
```

More Working Examples

There are some working examples along with the demo source code for you to look at.

There's also the library source code if you want to see what makes it tick.