Implement Drag and Drop in Your Web Apps / Page 4
Implement Drag and Drop in Your Web Apps [con't]
Using Drag Sources and Drop Targets
We've seen the application and its two composite widgets. Now things start to get interesting because next we look at how you implement your own drag sources and drop targets by using the drag-and-drop module.
Our sample application implements a single drag source—the MusicPlayerDragSource class—and two drop targets: IpodDropTarget and ZuneDropTarget. Let's start with the drag source, which is listed in Listing 6.5.
Listing 6.5 com.gwtsolutions.client.MusicPlayerDragSource
This class extends the DragSource class, which is part of our dnd module. That DragSource class implements four methods that subclasses are likely to override:
|
The preceding methods are called by the dnd module when one of the following occurs: The drag starts; the drag source is dropped outside a drop target; or the drop is accepted or rejected by a drop target.
When the drag starts, the music player drag source adds to itself the CSS style named pointerCursor. That style defines a single property, the cursor property, with the value pointer. Setting that style effectively changes the cursor when it's over our drag source. See Listing 6.9 on page 181 for the definition of that CSS style.
When a music player drag source is dropped outside any drop target, we invoke super.droppedOutsideDropTarget(), which returns the drag source to its original position, and we reset the cursor by removing the pointerCursor style from the drag source widget.
When a music player drag source is dropped on a drop target that rejects the drop, we invoke super.droppedOutsideDropTarget(), which returns the drag source to its original position and resets the cursor. Notice that in this case, dropping a music player outside a drop target has the same effect, from the point of view of the drag source, as being rejected by a drop target.
When a music player drag source is dropped on a drop target that accepts the drop, we simply reset the cursor. It's up to the drop target to add the music player to the drop target's enclosed panel.
We only have one drag source class, because iPods and Zunes react identically when they are dragged and dropped; however, we need two drop targets because the iPod drop target only accepts iPods and the Zune drop target only accepts Zunes. That said, however, the two kinds of drop targets are much more similar than they are different, so we have a base class that encapsulates those similarities. That drop target base class is listed in Listing 6.6.
Listing 6.6 com.gwtsolutions.client.MusicPlayerDropTarget
This class extends the DropTarget class, which is also part of our dnd module. That class implements three methods that subclasses typically override:
|
The preceding methods are called by the dnd module when a drag source enters, exits, or is dropped on a drop target. The drop target superclass also defines one abstract method that subclasses must implement: boolean acceptsDragSource(DragSource ds), which determines whether a drop target will accept a given drag source.
When a music player drag source enters or exits a drop target, we manipulate styles depending on whether the drag source is acceptable to the drop target to achieve drag-over and drag-under effects.
When a music player drag source is dropped on the drop target, we call super.dragSourceDropped(), which notifies the drag source of the drop by calling the drag source's acceptedByDropTarget method or rejectedByDropTarget method, depending on whether or not the drop target accepts the drop.
Now that we've encapsulated common drop target behavior in a base class, let's look at the subclasses specific to iPods and Zunes, listed in Listing 6.7 and Listing 6.8.
Listing 6.7 com.gwtsolutions.public.IpodDropTarget
Listing 6.8 com.gwtsolutions.public.ZuneDropTarget
The only thing that the drop targets specific to the music player do is define what kind of music player they will accept, by checking whether the component wrapped in the drag source is an iPod or a Zune.
com.google.gwt.user.client.ui.UIObject
• removeStyleName(String style)
Removes a CSS style from the set of styles applied to a single GWT widget.
Because you can selectively add and remove styles to a widget, you can change the way the widget looks under certain conditions, such as changing a drop target's border to indicate that a hovering draggable is acceptable (or not) for dropping on the drop target.
com.google.gwt.user.client.ui.AbsolutePanel
• remove(Widget w)
Removes the specified widget from the absolute panel. AbsolutePanel inherits this method from its superclass, ComplexPanel. If the widget is not a child of the panel, the method does nothing; otherwise, it removes the widget's DOM element from the panel's DOM element.
Defining the CSS Classes
Listing 6.9 shows the CSS styles used by the application's drag source and drop targets.
Listing 6.9 com/gwtsolutions/public/css/styles.css
Take note of the cursor styles—pointerCursor, moveCursor, noDropCursor—and the blueBorder style. Each of those styles has only one attribute, and the styles are added and removed from widgets. With GWT, it is not uncommon to define CSS styles with one attribute that are mixed in with other CSS styles for a single widget.

Printed with permission from from the book Google Web Toolkit Solutions: More Cool & Useful Stuff written by David Geary and Rob Gordon. ISBN 0132344815  Copyright © 2007 Prentice Hall.
URL:

Digg This
Find a programming school near you