/*
 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.awt.dnd;

import java.awt.event.InputEvent;
import java.awt.Component;
import java.awt.Point;

import java.io.InvalidObjectException;
import java.util.Collections;
import java.util.TooManyListenersException;
import java.util.ArrayList;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

The DragGestureRecognizer is an abstract base class for the specification of a platform-dependent listener that can be associated with a particular Component in order to identify platform-dependent drag initiating gestures.

The appropriate DragGestureRecognizer subclass instance is obtained from the DragSource associated with a particular Component, or from the Toolkit object via its createDragGestureRecognizer() method.

Once the DragGestureRecognizer is associated with a particular Component it will register the appropriate listener interfaces on that Component in order to track the input events delivered to the Component.

Once the DragGestureRecognizer identifies a sequence of events on the Component as a drag initiating gesture, it will notify its unicast DragGestureListener by invoking its gestureRecognized() method.

When a concrete DragGestureRecognizer instance detects a drag initiating gesture on the Component it is associated with, it fires a DragGestureEvent to the DragGestureListener registered on its unicast event source for DragGestureListener events. This DragGestureListener is responsible for causing the associated DragSource to start the Drag and Drop operation (if appropriate).

Author:Laurence P. G. Cable
See Also:
/** * The {@code DragGestureRecognizer} is an * abstract base class for the specification * of a platform-dependent listener that can be associated with a particular * {@code Component} in order to * identify platform-dependent drag initiating gestures. * <p> * The appropriate {@code DragGestureRecognizer} * subclass instance is obtained from the * {@link DragSource} associated with * a particular {@code Component}, or from the {@code Toolkit} object via its * {@link java.awt.Toolkit#createDragGestureRecognizer createDragGestureRecognizer()} * method. * <p> * Once the {@code DragGestureRecognizer} * is associated with a particular {@code Component} * it will register the appropriate listener interfaces on that * {@code Component} * in order to track the input events delivered to the {@code Component}. * <p> * Once the {@code DragGestureRecognizer} identifies a sequence of events * on the {@code Component} as a drag initiating gesture, it will notify * its unicast {@code DragGestureListener} by * invoking its * {@link java.awt.dnd.DragGestureListener#dragGestureRecognized gestureRecognized()} * method. * <P> * When a concrete {@code DragGestureRecognizer} * instance detects a drag initiating * gesture on the {@code Component} it is associated with, * it fires a {@link DragGestureEvent} to * the {@code DragGestureListener} registered on * its unicast event source for {@code DragGestureListener} * events. This {@code DragGestureListener} is responsible * for causing the associated * {@code DragSource} to start the Drag and Drop operation (if * appropriate). * * @author Laurence P. G. Cable * @see java.awt.dnd.DragGestureListener * @see java.awt.dnd.DragGestureEvent * @see java.awt.dnd.DragSource */
public abstract class DragGestureRecognizer implements Serializable { private static final long serialVersionUID = 8996673345831063337L;
Construct a new DragGestureRecognizer given the DragSource to be used in this Drag and Drop operation, the Component this DragGestureRecognizer should "observe" for drag initiating gestures, the action(s) supported for this Drag and Drop operation, and the DragGestureListener to notify once a drag initiating gesture has been detected.
Params:
  • ds – the DragSource this DragGestureRecognizer will use to process the Drag and Drop operation
  • c – the Component this DragGestureRecognizer should "observe" the event stream to, in order to detect a drag initiating gesture. If this value is null, the DragGestureRecognizer is not associated with any Component.
  • sa – the set (logical OR) of the DnDConstants that this Drag and Drop operation will support
  • dgl – the DragGestureRecognizer to notify when a drag gesture is detected
Throws:
/** * Construct a new {@code DragGestureRecognizer} * given the {@code DragSource} to be used * in this Drag and Drop operation, the {@code Component} * this {@code DragGestureRecognizer} should "observe" * for drag initiating gestures, the action(s) supported * for this Drag and Drop operation, and the * {@code DragGestureListener} to notify * once a drag initiating gesture has been detected. * * @param ds the {@code DragSource} this * {@code DragGestureRecognizer} * will use to process the Drag and Drop operation * * @param c the {@code Component} * this {@code DragGestureRecognizer} * should "observe" the event stream to, * in order to detect a drag initiating gesture. * If this value is {@code null}, the * {@code DragGestureRecognizer} * is not associated with any {@code Component}. * * @param sa the set (logical OR) of the * {@code DnDConstants} * that this Drag and Drop operation will support * * @param dgl the {@code DragGestureRecognizer} * to notify when a drag gesture is detected * * @throws IllegalArgumentException * if ds is {@code null}. */
protected DragGestureRecognizer(DragSource ds, Component c, int sa, DragGestureListener dgl) { super(); if (ds == null) throw new IllegalArgumentException("null DragSource"); dragSource = ds; component = c; sourceActions = sa & (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK); try { if (dgl != null) addDragGestureListener(dgl); } catch (TooManyListenersException tmle) { // cant happen ... } }
Construct a new DragGestureRecognizer given the DragSource to be used in this Drag and Drop operation, the Component this DragGestureRecognizer should "observe" for drag initiating gestures, and the action(s) supported for this Drag and Drop operation.
Params:
  • ds – the DragSource this DragGestureRecognizer will use to process the Drag and Drop operation
  • c – the Component this DragGestureRecognizer should "observe" the event stream to, in order to detect a drag initiating gesture. If this value is null, the DragGestureRecognizer is not associated with any Component.
  • sa – the set (logical OR) of the DnDConstants that this Drag and Drop operation will support
Throws:
/** * Construct a new {@code DragGestureRecognizer} * given the {@code DragSource} to be used in this * Drag and Drop * operation, the {@code Component} this * {@code DragGestureRecognizer} should "observe" * for drag initiating gestures, and the action(s) * supported for this Drag and Drop operation. * * @param ds the {@code DragSource} this * {@code DragGestureRecognizer} will use to * process the Drag and Drop operation * * @param c the {@code Component} this * {@code DragGestureRecognizer} should "observe" the event * stream to, in order to detect a drag initiating gesture. * If this value is {@code null}, the * {@code DragGestureRecognizer} * is not associated with any {@code Component}. * * @param sa the set (logical OR) of the {@code DnDConstants} * that this Drag and Drop operation will support * * @throws IllegalArgumentException * if ds is {@code null}. */
protected DragGestureRecognizer(DragSource ds, Component c, int sa) { this(ds, c, sa, null); }
Construct a new DragGestureRecognizer given the DragSource to be used in this Drag and Drop operation, and the Component this DragGestureRecognizer should "observe" for drag initiating gestures.
Params:
  • ds – the DragSource this DragGestureRecognizer will use to process the Drag and Drop operation
  • c – the Component this DragGestureRecognizer should "observe" the event stream to, in order to detect a drag initiating gesture. If this value is null, the DragGestureRecognizer is not associated with any Component.
Throws:
/** * Construct a new {@code DragGestureRecognizer} * given the {@code DragSource} to be used * in this Drag and Drop operation, and * the {@code Component} this * {@code DragGestureRecognizer} * should "observe" for drag initiating gestures. * * @param ds the {@code DragSource} this * {@code DragGestureRecognizer} * will use to process the Drag and Drop operation * * @param c the {@code Component} * this {@code DragGestureRecognizer} * should "observe" the event stream to, * in order to detect a drag initiating gesture. * If this value is {@code null}, * the {@code DragGestureRecognizer} * is not associated with any {@code Component}. * * @throws IllegalArgumentException * if ds is {@code null}. */
protected DragGestureRecognizer(DragSource ds, Component c) { this(ds, c, DnDConstants.ACTION_NONE); }
Construct a new DragGestureRecognizer given the DragSource to be used in this Drag and Drop operation.
Params:
  • ds – the DragSource this DragGestureRecognizer will use to process the Drag and Drop operation
Throws:
/** * Construct a new {@code DragGestureRecognizer} * given the {@code DragSource} to be used in this * Drag and Drop operation. * * @param ds the {@code DragSource} this * {@code DragGestureRecognizer} will * use to process the Drag and Drop operation * * @throws IllegalArgumentException * if ds is {@code null}. */
protected DragGestureRecognizer(DragSource ds) { this(ds, null); }
register this DragGestureRecognizer's Listeners with the Component subclasses must override this method
/** * register this DragGestureRecognizer's Listeners with the Component * * subclasses must override this method */
protected abstract void registerListeners();
unregister this DragGestureRecognizer's Listeners with the Component subclasses must override this method
/** * unregister this DragGestureRecognizer's Listeners with the Component * * subclasses must override this method */
protected abstract void unregisterListeners();
This method returns the DragSource this DragGestureRecognizer will use in order to process the Drag and Drop operation.
Returns:the DragSource
/** * This method returns the {@code DragSource} * this {@code DragGestureRecognizer} * will use in order to process the Drag and Drop * operation. * * @return the DragSource */
public DragSource getDragSource() { return dragSource; }
This method returns the Component that is to be "observed" by the DragGestureRecognizer for drag initiating gestures.
Returns:The Component this DragGestureRecognizer is associated with
/** * This method returns the {@code Component} * that is to be "observed" by the * {@code DragGestureRecognizer} * for drag initiating gestures. * * @return The Component this DragGestureRecognizer * is associated with */
public synchronized Component getComponent() { return component; }
set the Component that the DragGestureRecognizer is associated with registerListeners() and unregisterListeners() are called as a side effect as appropriate.
Params:
  • c – The Component or null
/** * set the Component that the DragGestureRecognizer is associated with * * registerListeners() and unregisterListeners() are called as a side * effect as appropriate. * * @param c The {@code Component} or {@code null} */
public synchronized void setComponent(Component c) { if (component != null && dragGestureListener != null) unregisterListeners(); component = c; if (component != null && dragGestureListener != null) registerListeners(); }
This method returns an int representing the type of action(s) this Drag and Drop operation will support.
Returns:the currently permitted source action(s)
/** * This method returns an int representing the * type of action(s) this Drag and Drop * operation will support. * * @return the currently permitted source action(s) */
public synchronized int getSourceActions() { return sourceActions; }
This method sets the permitted source drag action(s) for this Drag and Drop operation.
Params:
  • actions – the permitted source drag action(s)
/** * This method sets the permitted source drag action(s) * for this Drag and Drop operation. * * @param actions the permitted source drag action(s) */
public synchronized void setSourceActions(int actions) { sourceActions = actions & (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK); }
This method returns the first event in the series of events that initiated the Drag and Drop operation.
Returns:the initial event that triggered the drag gesture
/** * This method returns the first event in the * series of events that initiated * the Drag and Drop operation. * * @return the initial event that triggered the drag gesture */
public InputEvent getTriggerEvent() { return events.isEmpty() ? null : events.get(0); }
Reset the Recognizer, if its currently recognizing a gesture, ignore it.
/** * Reset the Recognizer, if its currently recognizing a gesture, ignore * it. */
public void resetRecognizer() { events.clear(); }
Register a new DragGestureListener.
Params:
  • dgl – the DragGestureListener to register with this DragGestureRecognizer.
Throws:
/** * Register a new {@code DragGestureListener}. * * @param dgl the {@code DragGestureListener} to register * with this {@code DragGestureRecognizer}. * * @throws java.util.TooManyListenersException if a * {@code DragGestureListener} has already been added. */
public synchronized void addDragGestureListener(DragGestureListener dgl) throws TooManyListenersException { if (dragGestureListener != null) throw new TooManyListenersException(); else { dragGestureListener = dgl; if (component != null) registerListeners(); } }
unregister the current DragGestureListener
Params:
  • dgl – the DragGestureListener to unregister from this DragGestureRecognizer
Throws:
/** * unregister the current DragGestureListener * * @param dgl the {@code DragGestureListener} to unregister * from this {@code DragGestureRecognizer} * * @throws IllegalArgumentException if * dgl is not (equal to) the currently registered {@code DragGestureListener}. */
public synchronized void removeDragGestureListener(DragGestureListener dgl) { if (dragGestureListener == null || !dragGestureListener.equals(dgl)) throw new IllegalArgumentException(); else { dragGestureListener = null; if (component != null) unregisterListeners(); } }
Notify the DragGestureListener that a Drag and Drop initiating gesture has occurred. Then reset the state of the Recognizer.
Params:
  • dragAction – The action initially selected by the users gesture
  • p – The point (in Component coords) where the gesture originated
/** * Notify the DragGestureListener that a Drag and Drop initiating * gesture has occurred. Then reset the state of the Recognizer. * * @param dragAction The action initially selected by the users gesture * @param p The point (in Component coords) where the gesture originated */
protected synchronized void fireDragGestureRecognized(int dragAction, Point p) { try { if (dragGestureListener != null) { dragGestureListener.dragGestureRecognized(new DragGestureEvent(this, dragAction, p, events)); } } finally { events.clear(); } }
Listeners registered on the Component by this Recognizer shall record all Events that are recognized as part of the series of Events that go to comprise a Drag and Drop initiating gesture via this API.

This method is used by a DragGestureRecognizer implementation to add an InputEvent subclass (that it believes is one in a series of events that comprise a Drag and Drop operation) to the array of events that this DragGestureRecognizer maintains internally.

Params:
  • awtie – the InputEvent to add to this DragGestureRecognizer's internal array of events. Note that null is not a valid value, and will be ignored.
/** * Listeners registered on the Component by this Recognizer shall record * all Events that are recognized as part of the series of Events that go * to comprise a Drag and Drop initiating gesture via this API. * <P> * This method is used by a {@code DragGestureRecognizer} * implementation to add an {@code InputEvent} * subclass (that it believes is one in a series * of events that comprise a Drag and Drop operation) * to the array of events that this * {@code DragGestureRecognizer} maintains internally. * * @param awtie the {@code InputEvent} * to add to this {@code DragGestureRecognizer}'s * internal array of events. Note that {@code null} * is not a valid value, and will be ignored. */
protected synchronized void appendEvent(InputEvent awtie) { events.add(awtie); }
Serializes this DragGestureRecognizer. This method first performs default serialization. Then, this object's DragGestureListener is written out if and only if it can be serialized. If not, null is written instead.
@serialDataThe default serializable fields, in alphabetical order, followed by either a DragGestureListener, or null.
Since:1.4
/** * Serializes this {@code DragGestureRecognizer}. This method first * performs default serialization. Then, this object's * {@code DragGestureListener} is written out if and only if it can be * serialized. If not, {@code null} is written instead. * * @serialData The default serializable fields, in alphabetical order, * followed by either a {@code DragGestureListener}, or * {@code null}. * @since 1.4 */
private void writeObject(ObjectOutputStream s) throws IOException { s.defaultWriteObject(); s.writeObject(SerializationTester.test(dragGestureListener) ? dragGestureListener : null); }
Deserializes this DragGestureRecognizer. This method first performs default deserialization for all non-transient fields. This object's DragGestureListener is then deserialized as well by using the next object in the stream.
Since:1.4
/** * Deserializes this {@code DragGestureRecognizer}. This method first * performs default deserialization for all non-{@code transient} * fields. This object's {@code DragGestureListener} is then * deserialized as well by using the next object in the stream. * * @since 1.4 */
@SuppressWarnings("unchecked") private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException { ObjectInputStream.GetField f = s.readFields(); DragSource newDragSource = (DragSource)f.get("dragSource", null); if (newDragSource == null) { throw new InvalidObjectException("null DragSource"); } dragSource = newDragSource; component = (Component)f.get("component", null); sourceActions = f.get("sourceActions", 0) & (DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK); events = (ArrayList<InputEvent>)f.get("events", new ArrayList<>(1)); dragGestureListener = (DragGestureListener)s.readObject(); } /* * fields */
The DragSource associated with this DragGestureRecognizer.
@serial
/** * The {@code DragSource} * associated with this * {@code DragGestureRecognizer}. * * @serial */
protected DragSource dragSource;
The Component associated with this DragGestureRecognizer.
@serial
/** * The {@code Component} * associated with this {@code DragGestureRecognizer}. * * @serial */
protected Component component;
The DragGestureListener associated with this DragGestureRecognizer.
/** * The {@code DragGestureListener} * associated with this {@code DragGestureRecognizer}. */
protected transient DragGestureListener dragGestureListener;
An int representing the type(s) of action(s) used in this Drag and Drop operation.
@serial
/** * An {@code int} representing * the type(s) of action(s) used * in this Drag and Drop operation. * * @serial */
protected int sourceActions;
The list of events (in order) that the DragGestureRecognizer "recognized" as a "gesture" that triggers a drag.
@serial
/** * The list of events (in order) that * the {@code DragGestureRecognizer} * "recognized" as a "gesture" that triggers a drag. * * @serial */
protected ArrayList<InputEvent> events = new ArrayList<InputEvent>(1); }