24.3 The Drag Gesture API


Now that the drop side is working, how do we make the drag side go? First, we need a bit of background information. To successfully accomplish a drag in Java, we must first recognize what constitutes a drag gesture. A drag gesture is an action the user takes to indicate that she's starting a drag. Typically, this is a mouse drag event, but it is not hard to imagine other gestures that could be used. For example, a voice-activated system might listen for the words "pick up" or something similar.

The API for drag gestures is fairly simple. Four DnD classes and interfaces make up the core: DragGestureRecognizer, MouseDragGestureRecognizer, DragGestureListener, and DragGestureEvent, as shown in Figure 24-4.

Figure 24-4. Drag recognition class diagram
figs/swng2.2404.gif

24.3.1 The DragGestureRecognizer Class

At the heart of this API is the DragGestureRecognizer class. Basically, the recognizer is responsible for recognizing a sequence of events that says "start dragging." This can be quite different for different platforms, so the DragGestureRecognizer class is abstract and must be subclassed to create an appropriate implementation. (The MouseDragGestureRecognizer takes a few more steps to complete the class and makes assumptions about using a mouse as the trigger for drag events. You can use the toolkit on your system to retrieve a concrete version.) This sounds more complex than it is. The idea is that you attach a drag gesture recognizer to a component with code similar to this:

JLabel jl = new JLabel("Drag Me!"); DragSource ds = new DragSource( ); DragGestureRecognizer dgr = ds.createDefaultDragGestureRecognizer(                             jl, DnDConstants.ACTION_COPY, this);

Now when you click on the jl label and start dragging, a drag gesture is recognized. The system then reports that recognition to your application through any registered DragGestureListener. An example is shown later in this section.

24.3.1.1 Properties

The DragGestureRecognizer uses the properties in Table 24-12 to hold information about a drag operation.

Table 24-12. DragGestureRecognizer properties

Property

Data type

get

is

set

Default value

component

Component

·

 

·

null

dragSource

DragSource

·

   

Passed through constructor

sourceActions

int

·

 

·

ACTION_NONE

triggerEvent

InputEvent

·

   

null

The component property refers to the component registered as the source for possible drag initiations. The dragSource property represents a DragSource object that wraps the component that are generating drags in much the same way that a DropTarget object wraps components that are receiving drops. The sourceActions property is the set of acceptable drag operations (coming from DnDConstants) for the drag source. The triggerEvent returns the first in a list of events that led to this recognizer declaring that a drag started. If no drag is currently recognized, this property is null.

24.3.1.2 Events

As mentioned before, the DragGestureRecognizer reports its events to a DragGestureListener and sends a DragGestureEvent. The usual add and remove methods for the listener are available.

public void addDragGestureListener(DragGestureListener dgl) throws TooManyListenersException
public void removeDragGestureListener(DragGestureListener dgl)

These methods supply the usual support for registering and unregistering listeners with the recognizer. Note that this is a unicast event; only one listener is allowed.

protected abstract void registerListeners( )
protected abstract void unregisterListeners( )

These protected methods register (and unregister) the appropriate trigger event listeners with the component associated with this recognizer. For example, if a drag starts with the user dragging the mouse, these methods would register the recognizer with the component as a MouseMotionListener. The listeners that a subclass registers to receive depend entirely on the events that can trigger a drag.

protected void fireDragGestureRecognized(int dragAction, Point p)

This method creates a DragGestureEvent and notifies the registered listener (if any) that a drag gesture has been recognized. The dragAction argument is one of the DnDConstants actions. The location of the mouse when the trigger event occurred is contained in p.

24.3.1.3 Fields

DragGestureRecognizer defines the following fields:

protected DragSource dragSource
protected Component component
protected int sourceActions

These fields support the properties of the same names.

protected DragGestureListener dragGestureListener

This field stores the active listener registered with the recognizer.

protected ArrayList events

This field stores the list of events that triggered the recognition of a drag gesture. The triggerEvent property corresponds to the first element in this list. This field can be manipulated through the appendEvent( ) and resetRecognizer( ) methods.

24.3.1.4 Constructors

All of the constructors for DragGestureRecognizer are protected. Because the class is abstract, a subclass is needed to create an instance of DragGestureRecognizer anyway. In real programs, you would use the DragSource.createDefaultDragGestureRecognizer( ) method or the Toolkit.createDragGestureRecognizer( ) method to build a recognizer.

protected DragGestureRecognizer(DragSource ds)
protected DragGestureRecognizer(DragSource ds, Component c)
protected DragGestureRecognizer(DragSource ds, Component c, int sa)
protected DragGestureRecognizer(DragSource ds, Component c, int sa, DragGestureListener dgl)

Create DragGestureRecognizer objects and use the supplied arguments to override the default property values for dragSource, component, and sourceActions, respectively. If supplied, dgl is used as the listener for any recognition events.

24.3.1.5 Trigger event list methods

Since it is possible a sequence of events (such as pressing the Tab key and then dragging the mouse) is responsible for causing a drag, the following methods help set up the list of trigger events correctly:

protected void appendEvent(InputEvent awtie)

This method allows individual events to be stored in the recognizer. The list can be cleared using the resetRecognizer( ) method.

public void resetRecognizer( )

This method clears any events in the trigger event list. If a drag is currently in progress, it is effectively cancelled.

24.3.2 The MouseDragGestureRecognizer Class

For many applications, we use the mouse drag as the drag gesture. The MouseDragGestureRecognizer class implements the appropriate recognizer functions for us. Note that this class is still abstract. Individual platforms must subclass it and fill out the specifics of what constitutes a valid drag initiation. However, this class does make it much easier to create your own recognizer than to start from the DragGestureRecognizer class directly.

As you start playing with DnD functionality, you will probably rely on the prebuilt recognizers you can retrieve from the DragSource class.

24.3.2.1 Constructors

The MouseDragGestureRecognizer class contains the same set of constructors found in its parent class:

protected MouseDragGestureRecognizer(DragSource ds)
protected MouseDragGestureRecognizer(DragSource ds, Component c)
protected MouseDragGestureRecognizer(DragSource ds, Component c, int act)
protected MouseDragGestureRecognizer(DragSource ds, Component c, int act, DragGestureListener dgl)
24.3.2.2 Mouse methods

Because this class recognizes gestures started by mouse events, it implements both the MouseListener and MouseMotionListener interfaces. The following methods come from these interfaces:

public void mouseClicked(MouseEvent e)
public void mouseDragged(MouseEvent e)
public void mouseEntered(MouseEvent e)
public void mouseExited(MouseEvent e)
public void mouseMoved(MouseEvent e)
public void mousePressed(MouseEvent e)
public void mouseReleased(MouseEvent e)

In the MouseDragGestureRecognizer class, these methods are all empty. Subclasses must override the methods to provide appropriate functionality.

24.3.2.3 Listener methods

This class implements the two abstract methods inherited from DragGestureListener:

protected void registerListeners( )
protected void unregisterListeners( )

These methods register and unregister this recognizer as a MouseListener and a MouseMotionListener with its component.

24.3.3 The Drag Gesture Events and Listeners

The DragGestureListener interface provides one method to indicate whether a drag gesture has been recognized:

public void dragGestureRecognized(DragGestureEvent dge)

The DragGestureEvent provides you with everything you need to know about the drag the user has initiated. If you like everything you see, you can start the drag process. If something is wrong (the wrong action, the wrong object to drag, the application is not in a draggable mode, etc.), you can ignore the gesture.

24.3.3.1 Properties

Most of the properties stored in a DragGestureEvent provide convenient access to similar properties in the DragGestureRecognizer that generated the event. These are listed in Table 24-13.

Table 24-13. DragGestureEvent properties

Property

Data type

get

is

set

Default value

component

Component

·

     

dragAction

int

·

     

dragOrigin

Point

·

     

dragSource

DragSource

·

     

sourceAsDragGestureRecognizer

DragGestureRecognizer

·

     

triggerEvent

InputEvent

·

     

The dragOrigin property corresponds to the location of the mouse when the gesture was recognized. The sourceAsDragGestureRecognizer property is merely a convenience property allowing you to access the source of the event as a DragGestureRecognizer rather than as an Object, which is what happens with the source property inherited from the EventObject class.

24.3.3.2 Event list methods

In discussing the DragGestureRecognizer fields, we noted that several events can be sequenced together to create a drag. The entire list of these events can be retrieved with these methods:

public Iterator iterator( )

This method returns an iterator for the ArrayList storing the events. If you've worked with the Collections APIs, this method may be more to your liking.

public Object[] toArray( )
public Object[] toArray(Object[] array)

These methods return the list of events in an Object array. The first method creates a new array, while the second fills the supplied array.

24.3.3.3 Drag initiation methods

We worry about DragGestureEvent objects because they have the mechanism for starting a drag operation. These methods are required to get a drag underway and usually appear in your dragGestureRecognized( ) method. Now you can package the data to be dragged and pick a cursor to indicate that a successful drag start has occurred. (You can pick one of the cursors predefined in the DragSource class. See Table 24-15 for a complete list.) This sounds worse than it is. Be sure to look at the example code to get an idea of the relatively small amount of programming required.

public void startDrag(Cursor dragCursor, Transferable transferable, DragSourceListener dsl) throws InvalidDnDOperationException

This method starts a drag operation with the initial cursor defined by dragCursor. The data that will be transferred in the operation needs to be wrapped up in a Transferable object. The dsl argument should be the DragSourceListener associated with the drag source. Often, you can bundle the DragSourceListener and the DragGestureListener together in one class.

public void startDrag(Cursor dragCursor, Image dragImage, Point imageOffset, Transferable transferable, DragSourceListener dsl) throws InvalidDnDOperationException

This method is similar to the first startDrag( ) with the exception of the dragImage and imageOffset arguments. If draggable images are supported on your platform (they may not be!), then you can supply an image and an offset to use during the drag operation. The offset represents the location of the mouse pointer relative to the upper-left corner of the image. You can find out if your platform supports drag images using the dragImageSupported property of the DragSource class, which is discussed in the next section.

24.3.4 A Simple Gesture

While they won't do us any good by themselves, we need to familiarize ourselves with these drag gestures before we can do anything with the DnD process. (This must be done in the 1.3 and 1.2 SDKs. In the 1.4 SDK, we need to do this only if we want more control over the drag process.) Here's a simple example of a JList object that will eventually contain draggable list items. Right now, we'll just make sure that we can recognize a drag gesture when it happens in our list object.

/*  * GestureTest.java  * A simple (?) test of the DragSource classes to  * create a draggable object in a Java application  */ import java.awt.*; import java.awt.dnd.*; import java.awt.datatransfer.*; import java.awt.event.*; import java.io.*; import java.util.*; import javax.swing.*; public class GestureTest extends JFrame {   DragSource ds;   JList jl;   String[] items = {"Java", "C", "C++", "Lisp", "Perl", "Python"};   public GestureTest( ) {     super("Gesture Test");     setSize(200,150);     setDefaultCloseOperation(EXIT_ON_CLOSE);     // Create a JList object and add it to our application.     jl = new JList(items);     jl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);     getContentPane( ).add(new JScrollPane(jl), BorderLayout.CENTER);     // Now create a DragRecognizer with the DragSource class; you can      // use a Toolkit if you prefer. Notice that we specify our JList      // object when creating the recognizer, not when creating the drag      // source.     ds = new DragSource( );     DragGestureRecognizer dgr = ds.createDefaultDragGestureRecognizer(                                 jl, DnDConstants.ACTION_COPY,                                  new DragGestureListener( ) {           // Report the recognized drag event to the console.           public void dragGestureRecognized(DragGestureEvent dge) {             System.out.println("Drag Gesture Recognized!");           }         });     setVisible(true);   }   public static void main(String args[]) {     new GestureTest( );   } }


Java Swing
Graphic Java 2: Mastering the Jfc, By Geary, 3Rd Edition, Volume 2: Swing
ISBN: 0130796670
EAN: 2147483647
Year: 2001
Pages: 289
Authors: David Geary

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net