0N/A/*
2362N/A * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage java.awt.dnd;
0N/A
0N/Aimport java.awt.Component;
0N/Aimport java.awt.Cursor;
0N/Aimport java.awt.GraphicsEnvironment;
0N/Aimport java.awt.HeadlessException;
0N/Aimport java.awt.Image;
0N/Aimport java.awt.Point;
0N/Aimport java.awt.Toolkit;
0N/Aimport java.awt.datatransfer.FlavorMap;
0N/Aimport java.awt.datatransfer.SystemFlavorMap;
0N/Aimport java.awt.datatransfer.Transferable;
0N/Aimport java.awt.dnd.peer.DragSourceContextPeer;
0N/Aimport java.io.IOException;
0N/Aimport java.io.ObjectInputStream;
0N/Aimport java.io.ObjectOutputStream;
0N/Aimport java.io.Serializable;
0N/Aimport java.security.AccessController;
0N/Aimport java.util.EventListener;
0N/Aimport sun.awt.dnd.SunDragSourceContextPeer;
0N/Aimport sun.security.action.GetIntegerAction;
0N/A
0N/A
0N/A/**
0N/A * The <code>DragSource</code> is the entity responsible
0N/A * for the initiation of the Drag
0N/A * and Drop operation, and may be used in a number of scenarios:
0N/A * <UL>
0N/A * <LI>1 default instance per JVM for the lifetime of that JVM.
0N/A * <LI>1 instance per class of potential Drag Initiator object (e.g
0N/A * TextField). [implementation dependent]
0N/A * <LI>1 per instance of a particular
0N/A * <code>Component</code>, or application specific
0N/A * object associated with a <code>Component</code>
0N/A * instance in the GUI. [implementation dependent]
0N/A * <LI>Some other arbitrary association. [implementation dependent]
0N/A *</UL>
0N/A *
0N/A * Once the <code>DragSource</code> is
0N/A * obtained, a <code>DragGestureRecognizer</code> should
0N/A * also be obtained to associate the <code>DragSource</code>
0N/A * with a particular
0N/A * <code>Component</code>.
0N/A * <P>
0N/A * The initial interpretation of the user's gesture,
0N/A * and the subsequent starting of the drag operation
0N/A * are the responsibility of the implementing
0N/A * <code>Component</code>, which is usually
0N/A * implemented by a <code>DragGestureRecognizer</code>.
0N/A *<P>
0N/A * When a drag gesture occurs, the
0N/A * <code>DragSource</code>'s
0N/A * startDrag() method shall be
0N/A * invoked in order to cause processing
0N/A * of the user's navigational
0N/A * gestures and delivery of Drag and Drop
0N/A * protocol notifications. A
0N/A * <code>DragSource</code> shall only
0N/A * permit a single Drag and Drop operation to be
0N/A * current at any one time, and shall
0N/A * reject any further startDrag() requests
0N/A * by throwing an <code>IllegalDnDOperationException</code>
0N/A * until such time as the extant operation is complete.
0N/A * <P>
0N/A * The startDrag() method invokes the
0N/A * createDragSourceContext() method to
0N/A * instantiate an appropriate
0N/A * <code>DragSourceContext</code>
0N/A * and associate the <code>DragSourceContextPeer</code>
0N/A * with that.
0N/A * <P>
0N/A * If the Drag and Drop System is
0N/A * unable to initiate a drag operation for
0N/A * some reason, the startDrag() method throws
0N/A * a <code>java.awt.dnd.InvalidDnDOperationException</code>
0N/A * to signal such a condition. Typically this
0N/A * exception is thrown when the underlying platform
0N/A * system is either not in a state to
0N/A * initiate a drag, or the parameters specified are invalid.
0N/A * <P>
0N/A * Note that during the drag, the
0N/A * set of operations exposed by the source
0N/A * at the start of the drag operation may not change
0N/A * until the operation is complete.
0N/A * The operation(s) are constant for the
0N/A * duration of the operation with respect to the
0N/A * <code>DragSource</code>.
0N/A *
0N/A * @since 1.2
0N/A */
0N/A
0N/Apublic class DragSource implements Serializable {
0N/A
0N/A private static final long serialVersionUID = 6236096958971414066L;
0N/A
0N/A /*
0N/A * load a system default cursor
0N/A */
0N/A
0N/A private static Cursor load(String name) {
0N/A if (GraphicsEnvironment.isHeadless()) {
0N/A return null;
0N/A }
0N/A
0N/A try {
0N/A return (Cursor)Toolkit.getDefaultToolkit().getDesktopProperty(name);
0N/A } catch (Exception e) {
0N/A e.printStackTrace();
0N/A
0N/A throw new RuntimeException("failed to load system cursor: " + name + " : " + e.getMessage());
0N/A }
0N/A }
0N/A
0N/A
0N/A /**
0N/A * The default <code>Cursor</code> to use with a copy operation indicating
0N/A * that a drop is currently allowed. <code>null</code> if
0N/A * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
0N/A *
0N/A * @see java.awt.GraphicsEnvironment#isHeadless
0N/A */
0N/A public static final Cursor DefaultCopyDrop =
0N/A load("DnD.Cursor.CopyDrop");
0N/A
0N/A /**
0N/A * The default <code>Cursor</code> to use with a move operation indicating
0N/A * that a drop is currently allowed. <code>null</code> if
0N/A * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
0N/A *
0N/A * @see java.awt.GraphicsEnvironment#isHeadless
0N/A */
0N/A public static final Cursor DefaultMoveDrop =
0N/A load("DnD.Cursor.MoveDrop");
0N/A
0N/A /**
0N/A * The default <code>Cursor</code> to use with a link operation indicating
0N/A * that a drop is currently allowed. <code>null</code> if
0N/A * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
0N/A *
0N/A * @see java.awt.GraphicsEnvironment#isHeadless
0N/A */
0N/A public static final Cursor DefaultLinkDrop =
0N/A load("DnD.Cursor.LinkDrop");
0N/A
0N/A /**
0N/A * The default <code>Cursor</code> to use with a copy operation indicating
0N/A * that a drop is currently not allowed. <code>null</code> if
0N/A * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
0N/A *
0N/A * @see java.awt.GraphicsEnvironment#isHeadless
0N/A */
0N/A public static final Cursor DefaultCopyNoDrop =
0N/A load("DnD.Cursor.CopyNoDrop");
0N/A
0N/A /**
0N/A * The default <code>Cursor</code> to use with a move operation indicating
0N/A * that a drop is currently not allowed. <code>null</code> if
0N/A * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
0N/A *
0N/A * @see java.awt.GraphicsEnvironment#isHeadless
0N/A */
0N/A public static final Cursor DefaultMoveNoDrop =
0N/A load("DnD.Cursor.MoveNoDrop");
0N/A
0N/A /**
0N/A * The default <code>Cursor</code> to use with a link operation indicating
0N/A * that a drop is currently not allowed. <code>null</code> if
0N/A * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
0N/A *
0N/A * @see java.awt.GraphicsEnvironment#isHeadless
0N/A */
0N/A public static final Cursor DefaultLinkNoDrop =
0N/A load("DnD.Cursor.LinkNoDrop");
0N/A
0N/A private static final DragSource dflt =
0N/A (GraphicsEnvironment.isHeadless()) ? null : new DragSource();
0N/A
0N/A /**
0N/A * Internal constants for serialization.
0N/A */
0N/A static final String dragSourceListenerK = "dragSourceL";
0N/A static final String dragSourceMotionListenerK = "dragSourceMotionL";
0N/A
0N/A /**
0N/A * Gets the <code>DragSource</code> object associated with
0N/A * the underlying platform.
0N/A *
0N/A * @return the platform DragSource
0N/A * @exception HeadlessException if GraphicsEnvironment.isHeadless()
0N/A * returns true
0N/A * @see java.awt.GraphicsEnvironment#isHeadless
0N/A */
0N/A public static DragSource getDefaultDragSource() {
0N/A if (GraphicsEnvironment.isHeadless()) {
0N/A throw new HeadlessException();
0N/A } else {
0N/A return dflt;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Reports
0N/A * whether or not drag
0N/A * <code>Image</code> support
0N/A * is available on the underlying platform.
0N/A * <P>
0N/A * @return if the Drag Image support is available on this platform
0N/A */
0N/A
0N/A public static boolean isDragImageSupported() {
0N/A Toolkit t = Toolkit.getDefaultToolkit();
0N/A
0N/A Boolean supported;
0N/A
0N/A try {
0N/A supported = (Boolean)Toolkit.getDefaultToolkit().getDesktopProperty("DnD.isDragImageSupported");
0N/A
0N/A return supported.booleanValue();
0N/A } catch (Exception e) {
0N/A return false;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Creates a new <code>DragSource</code>.
0N/A *
0N/A * @exception HeadlessException if GraphicsEnvironment.isHeadless()
0N/A * returns true
0N/A * @see java.awt.GraphicsEnvironment#isHeadless
0N/A */
0N/A public DragSource() throws HeadlessException {
0N/A if (GraphicsEnvironment.isHeadless()) {
0N/A throw new HeadlessException();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Start a drag, given the <code>DragGestureEvent</code>
0N/A * that initiated the drag, the initial
0N/A * <code>Cursor</code> to use,
0N/A * the <code>Image</code> to drag,
0N/A * the offset of the <code>Image</code> origin
0N/A * from the hotspot of the <code>Cursor</code> at
0N/A * the instant of the trigger,
0N/A * the <code>Transferable</code> subject data
0N/A * of the drag, the <code>DragSourceListener</code>,
0N/A * and the <code>FlavorMap</code>.
0N/A * <P>
0N/A * @param trigger the <code>DragGestureEvent</code> that initiated the drag
0N/A * @param dragCursor the initial {@code Cursor} for this drag operation
0N/A * or {@code null} for the default cursor handling;
0N/A * see <a href="DragSourceContext.html#defaultCursor">DragSourceContext</a>
0N/A * for more details on the cursor handling mechanism during drag and drop
0N/A * @param dragImage the image to drag or {@code null}
0N/A * @param imageOffset the offset of the <code>Image</code> origin from the hotspot
0N/A * of the <code>Cursor</code> at the instant of the trigger
0N/A * @param transferable the subject data of the drag
0N/A * @param dsl the <code>DragSourceListener</code>
0N/A * @param flavorMap the <code>FlavorMap</code> to use, or <code>null</code>
0N/A * <P>
0N/A * @throws java.awt.dnd.InvalidDnDOperationException
0N/A * if the Drag and Drop
0N/A * system is unable to initiate a drag operation, or if the user
0N/A * attempts to start a drag while an existing drag operation
0N/A * is still executing
0N/A */
0N/A
0N/A public void startDrag(DragGestureEvent trigger,
0N/A Cursor dragCursor,
0N/A Image dragImage,
0N/A Point imageOffset,
0N/A Transferable transferable,
0N/A DragSourceListener dsl,
0N/A FlavorMap flavorMap) throws InvalidDnDOperationException {
0N/A
0N/A SunDragSourceContextPeer.setDragDropInProgress(true);
0N/A
0N/A try {
0N/A if (flavorMap != null) this.flavorMap = flavorMap;
0N/A
0N/A DragSourceContextPeer dscp = Toolkit.getDefaultToolkit().createDragSourceContextPeer(trigger);
0N/A
0N/A DragSourceContext dsc = createDragSourceContext(dscp,
0N/A trigger,
0N/A dragCursor,
0N/A dragImage,
0N/A imageOffset,
0N/A transferable,
0N/A dsl
0N/A );
0N/A
0N/A if (dsc == null) {
0N/A throw new InvalidDnDOperationException();
0N/A }
0N/A
0N/A dscp.startDrag(dsc, dsc.getCursor(), dragImage, imageOffset); // may throw
0N/A } catch (RuntimeException e) {
0N/A SunDragSourceContextPeer.setDragDropInProgress(false);
0N/A throw e;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Start a drag, given the <code>DragGestureEvent</code>
0N/A * that initiated the drag, the initial
0N/A * <code>Cursor</code> to use,
0N/A * the <code>Transferable</code> subject data
0N/A * of the drag, the <code>DragSourceListener</code>,
0N/A * and the <code>FlavorMap</code>.
0N/A * <P>
0N/A * @param trigger the <code>DragGestureEvent</code> that
0N/A * initiated the drag
0N/A * @param dragCursor the initial {@code Cursor} for this drag operation
0N/A * or {@code null} for the default cursor handling;
0N/A * see <a href="DragSourceContext.html#defaultCursor">DragSourceContext</a>
0N/A * for more details on the cursor handling mechanism during drag and drop
0N/A * @param transferable the subject data of the drag
0N/A * @param dsl the <code>DragSourceListener</code>
0N/A * @param flavorMap the <code>FlavorMap</code> to use or <code>null</code>
0N/A * <P>
0N/A * @throws java.awt.dnd.InvalidDnDOperationException
0N/A * if the Drag and Drop
0N/A * system is unable to initiate a drag operation, or if the user
0N/A * attempts to start a drag while an existing drag operation
0N/A * is still executing
0N/A */
0N/A
0N/A public void startDrag(DragGestureEvent trigger,
0N/A Cursor dragCursor,
0N/A Transferable transferable,
0N/A DragSourceListener dsl,
0N/A FlavorMap flavorMap) throws InvalidDnDOperationException {
0N/A startDrag(trigger, dragCursor, null, null, transferable, dsl, flavorMap);
0N/A }
0N/A
0N/A /**
0N/A * Start a drag, given the <code>DragGestureEvent</code>
0N/A * that initiated the drag, the initial <code>Cursor</code>
0N/A * to use,
0N/A * the <code>Image</code> to drag,
0N/A * the offset of the <code>Image</code> origin
0N/A * from the hotspot of the <code>Cursor</code>
0N/A * at the instant of the trigger,
0N/A * the subject data of the drag, and
0N/A * the <code>DragSourceListener</code>.
0N/A * <P>
0N/A * @param trigger the <code>DragGestureEvent</code> that initiated the drag
0N/A * @param dragCursor the initial {@code Cursor} for this drag operation
0N/A * or {@code null} for the default cursor handling;
0N/A * see <a href="DragSourceContext.html#defaultCursor">DragSourceContext</a>
0N/A * for more details on the cursor handling mechanism during drag and drop
0N/A * @param dragImage the <code>Image</code> to drag or <code>null</code>
0N/A * @param dragOffset the offset of the <code>Image</code> origin from the hotspot
0N/A * of the <code>Cursor</code> at the instant of the trigger
0N/A * @param transferable the subject data of the drag
0N/A * @param dsl the <code>DragSourceListener</code>
0N/A * <P>
0N/A * @throws java.awt.dnd.InvalidDnDOperationException
0N/A * if the Drag and Drop
0N/A * system is unable to initiate a drag operation, or if the user
0N/A * attempts to start a drag while an existing drag operation
0N/A * is still executing
0N/A */
0N/A
0N/A public void startDrag(DragGestureEvent trigger,
0N/A Cursor dragCursor,
0N/A Image dragImage,
0N/A Point dragOffset,
0N/A Transferable transferable,
0N/A DragSourceListener dsl) throws InvalidDnDOperationException {
0N/A startDrag(trigger, dragCursor, dragImage, dragOffset, transferable, dsl, null);
0N/A }
0N/A
0N/A /**
0N/A * Start a drag, given the <code>DragGestureEvent</code>
0N/A * that initiated the drag, the initial
0N/A * <code>Cursor</code> to
0N/A * use,
0N/A * the <code>Transferable</code> subject data
0N/A * of the drag, and the <code>DragSourceListener</code>.
0N/A * <P>
0N/A * @param trigger the <code>DragGestureEvent</code> that initiated the drag
0N/A * @param dragCursor the initial {@code Cursor} for this drag operation
0N/A * or {@code null} for the default cursor handling;
0N/A * see <a href="DragSourceContext.html#defaultCursor">DragSourceContext</a> class
0N/A * for more details on the cursor handling mechanism during drag and drop
0N/A * @param transferable the subject data of the drag
0N/A * @param dsl the <code>DragSourceListener</code>
0N/A * <P>
0N/A * @throws java.awt.dnd.InvalidDnDOperationException
0N/A * if the Drag and Drop
0N/A * system is unable to initiate a drag operation, or if the user
0N/A * attempts to start a drag while an existing drag operation
0N/A * is still executing
0N/A */
0N/A
0N/A public void startDrag(DragGestureEvent trigger,
0N/A Cursor dragCursor,
0N/A Transferable transferable,
0N/A DragSourceListener dsl) throws InvalidDnDOperationException {
0N/A startDrag(trigger, dragCursor, null, null, transferable, dsl, null);
0N/A }
0N/A
0N/A /**
0N/A * Creates the {@code DragSourceContext} to handle the current drag
0N/A * operation.
0N/A * <p>
0N/A * To incorporate a new <code>DragSourceContext</code>
0N/A * subclass, subclass <code>DragSource</code> and
0N/A * override this method.
0N/A * <p>
0N/A * If <code>dragImage</code> is <code>null</code>, no image is used
0N/A * to represent the drag over feedback for this drag operation, but
0N/A * <code>NullPointerException</code> is not thrown.
0N/A * <p>
0N/A * If <code>dsl</code> is <code>null</code>, no drag source listener
0N/A * is registered with the created <code>DragSourceContext</code>,
0N/A * but <code>NullPointerException</code> is not thrown.
0N/A *
0N/A * @param dscp The <code>DragSourceContextPeer</code> for this drag
0N/A * @param dgl The <code>DragGestureEvent</code> that triggered the
0N/A * drag
0N/A * @param dragCursor The initial {@code Cursor} for this drag operation
0N/A * or {@code null} for the default cursor handling;
0N/A * see <a href="DragSourceContext.html#defaultCursor">DragSourceContext</a> class
0N/A * for more details on the cursor handling mechanism during drag and drop
0N/A * @param dragImage The <code>Image</code> to drag or <code>null</code>
0N/A * @param imageOffset The offset of the <code>Image</code> origin from the
0N/A * hotspot of the cursor at the instant of the trigger
0N/A * @param t The subject data of the drag
0N/A * @param dsl The <code>DragSourceListener</code>
0N/A *
0N/A * @return the <code>DragSourceContext</code>
0N/A *
0N/A * @throws NullPointerException if <code>dscp</code> is <code>null</code>
0N/A * @throws NullPointerException if <code>dgl</code> is <code>null</code>
0N/A * @throws NullPointerException if <code>dragImage</code> is not
0N/A * <code>null</code> and <code>imageOffset</code> is <code>null</code>
0N/A * @throws NullPointerException if <code>t</code> is <code>null</code>
0N/A * @throws IllegalArgumentException if the <code>Component</code>
0N/A * associated with the trigger event is <code>null</code>.
0N/A * @throws IllegalArgumentException if the <code>DragSource</code> for the
0N/A * trigger event is <code>null</code>.
0N/A * @throws IllegalArgumentException if the drag action for the
0N/A * trigger event is <code>DnDConstants.ACTION_NONE</code>.
0N/A * @throws IllegalArgumentException if the source actions for the
0N/A * <code>DragGestureRecognizer</code> associated with the trigger
0N/A * event are equal to <code>DnDConstants.ACTION_NONE</code>.
0N/A */
0N/A
0N/A protected DragSourceContext createDragSourceContext(DragSourceContextPeer dscp, DragGestureEvent dgl, Cursor dragCursor, Image dragImage, Point imageOffset, Transferable t, DragSourceListener dsl) {
0N/A return new DragSourceContext(dscp, dgl, dragCursor, dragImage, imageOffset, t, dsl);
0N/A }
0N/A
0N/A /**
0N/A * This method returns the
0N/A * <code>FlavorMap</code> for this <code>DragSource</code>.
0N/A * <P>
0N/A * @return the <code>FlavorMap</code> for this <code>DragSource</code>
0N/A */
0N/A
0N/A public FlavorMap getFlavorMap() { return flavorMap; }
0N/A
0N/A /**
0N/A * Creates a new <code>DragGestureRecognizer</code>
0N/A * that implements the specified
0N/A * abstract subclass of
0N/A * <code>DragGestureRecognizer</code>, and
0N/A * sets the specified <code>Component</code>
0N/A * and <code>DragGestureListener</code> on
0N/A * the newly created object.
0N/A * <P>
0N/A * @param recognizerAbstractClass the requested abstract type
0N/A * @param actions the permitted source drag actions
0N/A * @param c the <code>Component</code> target
0N/A * @param dgl the <code>DragGestureListener</code> to notify
0N/A * <P>
0N/A * @return the new <code>DragGestureRecognizer</code> or <code>null</code>
0N/A * if the <code>Toolkit.createDragGestureRecognizer</code> method
0N/A * has no implementation available for
0N/A * the requested <code>DragGestureRecognizer</code>
0N/A * subclass and returns <code>null</code>
0N/A */
0N/A
0N/A public <T extends DragGestureRecognizer> T
0N/A createDragGestureRecognizer(Class<T> recognizerAbstractClass,
0N/A Component c, int actions,
0N/A DragGestureListener dgl)
0N/A {
0N/A return Toolkit.getDefaultToolkit().createDragGestureRecognizer(recognizerAbstractClass, this, c, actions, dgl);
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Creates a new <code>DragGestureRecognizer</code>
0N/A * that implements the default
0N/A * abstract subclass of <code>DragGestureRecognizer</code>
0N/A * for this <code>DragSource</code>,
0N/A * and sets the specified <code>Component</code>
0N/A * and <code>DragGestureListener</code> on the
0N/A * newly created object.
0N/A *
0N/A * For this <code>DragSource</code>
0N/A * the default is <code>MouseDragGestureRecognizer</code>.
0N/A * <P>
0N/A * @param c the <code>Component</code> target for the recognizer
0N/A * @param actions the permitted source actions
0N/A * @param dgl the <code>DragGestureListener</code> to notify
0N/A * <P>
0N/A * @return the new <code>DragGestureRecognizer</code> or <code>null</code>
0N/A * if the <code>Toolkit.createDragGestureRecognizer</code> method
0N/A * has no implementation available for
0N/A * the requested <code>DragGestureRecognizer</code>
0N/A * subclass and returns <code>null</code>
0N/A */
0N/A
0N/A public DragGestureRecognizer createDefaultDragGestureRecognizer(Component c, int actions, DragGestureListener dgl) {
0N/A return Toolkit.getDefaultToolkit().createDragGestureRecognizer(MouseDragGestureRecognizer.class, this, c, actions, dgl);
0N/A }
0N/A
0N/A /**
0N/A * Adds the specified <code>DragSourceListener</code> to this
0N/A * <code>DragSource</code> to receive drag source events during drag
0N/A * operations intiated with this <code>DragSource</code>.
0N/A * If a <code>null</code> listener is specified, no action is taken and no
0N/A * exception is thrown.
0N/A *
0N/A * @param dsl the <code>DragSourceListener</code> to add
0N/A *
0N/A * @see #removeDragSourceListener
0N/A * @see #getDragSourceListeners
0N/A * @since 1.4
0N/A */
0N/A public void addDragSourceListener(DragSourceListener dsl) {
0N/A if (dsl != null) {
0N/A synchronized (this) {
0N/A listener = DnDEventMulticaster.add(listener, dsl);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Removes the specified <code>DragSourceListener</code> from this
0N/A * <code>DragSource</code>.
0N/A * If a <code>null</code> listener is specified, no action is taken and no
0N/A * exception is thrown.
0N/A * If the listener specified by the argument was not previously added to
0N/A * this <code>DragSource</code>, no action is taken and no exception
0N/A * is thrown.
0N/A *
0N/A * @param dsl the <code>DragSourceListener</code> to remove
0N/A *
0N/A * @see #addDragSourceListener
0N/A * @see #getDragSourceListeners
0N/A * @since 1.4
0N/A */
0N/A public void removeDragSourceListener(DragSourceListener dsl) {
0N/A if (dsl != null) {
0N/A synchronized (this) {
0N/A listener = DnDEventMulticaster.remove(listener, dsl);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Gets all the <code>DragSourceListener</code>s
0N/A * registered with this <code>DragSource</code>.
0N/A *
0N/A * @return all of this <code>DragSource</code>'s
0N/A * <code>DragSourceListener</code>s or an empty array if no
0N/A * such listeners are currently registered
0N/A *
0N/A * @see #addDragSourceListener
0N/A * @see #removeDragSourceListener
0N/A * @since 1.4
0N/A */
0N/A public DragSourceListener[] getDragSourceListeners() {
0N/A return (DragSourceListener[])getListeners(DragSourceListener.class);
0N/A }
0N/A
0N/A /**
0N/A * Adds the specified <code>DragSourceMotionListener</code> to this
0N/A * <code>DragSource</code> to receive drag motion events during drag
0N/A * operations intiated with this <code>DragSource</code>.
0N/A * If a <code>null</code> listener is specified, no action is taken and no
0N/A * exception is thrown.
0N/A *
0N/A * @param dsml the <code>DragSourceMotionListener</code> to add
0N/A *
0N/A * @see #removeDragSourceMotionListener
0N/A * @see #getDragSourceMotionListeners
0N/A * @since 1.4
0N/A */
0N/A public void addDragSourceMotionListener(DragSourceMotionListener dsml) {
0N/A if (dsml != null) {
0N/A synchronized (this) {
0N/A motionListener = DnDEventMulticaster.add(motionListener, dsml);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Removes the specified <code>DragSourceMotionListener</code> from this
0N/A * <code>DragSource</code>.
0N/A * If a <code>null</code> listener is specified, no action is taken and no
0N/A * exception is thrown.
0N/A * If the listener specified by the argument was not previously added to
0N/A * this <code>DragSource</code>, no action is taken and no exception
0N/A * is thrown.
0N/A *
0N/A * @param dsml the <code>DragSourceMotionListener</code> to remove
0N/A *
0N/A * @see #addDragSourceMotionListener
0N/A * @see #getDragSourceMotionListeners
0N/A * @since 1.4
0N/A */
0N/A public void removeDragSourceMotionListener(DragSourceMotionListener dsml) {
0N/A if (dsml != null) {
0N/A synchronized (this) {
0N/A motionListener = DnDEventMulticaster.remove(motionListener, dsml);
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Gets all of the <code>DragSourceMotionListener</code>s
0N/A * registered with this <code>DragSource</code>.
0N/A *
0N/A * @return all of this <code>DragSource</code>'s
0N/A * <code>DragSourceMotionListener</code>s or an empty array if no
0N/A * such listeners are currently registered
0N/A *
0N/A * @see #addDragSourceMotionListener
0N/A * @see #removeDragSourceMotionListener
0N/A * @since 1.4
0N/A */
0N/A public DragSourceMotionListener[] getDragSourceMotionListeners() {
0N/A return (DragSourceMotionListener[])
0N/A getListeners(DragSourceMotionListener.class);
0N/A }
0N/A
0N/A /**
0N/A * Gets all the objects currently registered as
0N/A * <code><em>Foo</em>Listener</code>s upon this <code>DragSource</code>.
0N/A * <code><em>Foo</em>Listener</code>s are registered using the
0N/A * <code>add<em>Foo</em>Listener</code> method.
0N/A *
0N/A * @param listenerType the type of listeners requested; this parameter
0N/A * should specify an interface that descends from
0N/A * <code>java.util.EventListener</code>
0N/A * @return an array of all objects registered as
0N/A * <code><em>Foo</em>Listener</code>s on this
0N/A * <code>DragSource</code>, or an empty array if no such listeners
0N/A * have been added
0N/A * @exception <code>ClassCastException</code> if <code>listenerType</code>
0N/A * doesn't specify a class or interface that implements
0N/A * <code>java.util.EventListener</code>
0N/A *
0N/A * @see #getDragSourceListeners
0N/A * @see #getDragSourceMotionListeners
0N/A * @since 1.4
0N/A */
0N/A public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
0N/A EventListener l = null;
0N/A if (listenerType == DragSourceListener.class) {
0N/A l = listener;
0N/A } else if (listenerType == DragSourceMotionListener.class) {
0N/A l = motionListener;
0N/A }
0N/A return DnDEventMulticaster.getListeners(l, listenerType);
0N/A }
0N/A
0N/A /**
0N/A * This method calls <code>dragEnter</code> on the
0N/A * <code>DragSourceListener</code>s registered with this
0N/A * <code>DragSource</code>, and passes them the specified
0N/A * <code>DragSourceDragEvent</code>.
0N/A *
0N/A * @param dsde the <code>DragSourceDragEvent</code>
0N/A */
0N/A void processDragEnter(DragSourceDragEvent dsde) {
0N/A DragSourceListener dsl = listener;
0N/A if (dsl != null) {
0N/A dsl.dragEnter(dsde);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * This method calls <code>dragOver</code> on the
0N/A * <code>DragSourceListener</code>s registered with this
0N/A * <code>DragSource</code>, and passes them the specified
0N/A * <code>DragSourceDragEvent</code>.
0N/A *
0N/A * @param dsde the <code>DragSourceDragEvent</code>
0N/A */
0N/A void processDragOver(DragSourceDragEvent dsde) {
0N/A DragSourceListener dsl = listener;
0N/A if (dsl != null) {
0N/A dsl.dragOver(dsde);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * This method calls <code>dropActionChanged</code> on the
0N/A * <code>DragSourceListener</code>s registered with this
0N/A * <code>DragSource</code>, and passes them the specified
0N/A * <code>DragSourceDragEvent</code>.
0N/A *
0N/A * @param dsde the <code>DragSourceDragEvent</code>
0N/A */
0N/A void processDropActionChanged(DragSourceDragEvent dsde) {
0N/A DragSourceListener dsl = listener;
0N/A if (dsl != null) {
0N/A dsl.dropActionChanged(dsde);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * This method calls <code>dragExit</code> on the
0N/A * <code>DragSourceListener</code>s registered with this
0N/A * <code>DragSource</code>, and passes them the specified
0N/A * <code>DragSourceEvent</code>.
0N/A *
0N/A * @param dse the <code>DragSourceEvent</code>
0N/A */
0N/A void processDragExit(DragSourceEvent dse) {
0N/A DragSourceListener dsl = listener;
0N/A if (dsl != null) {
0N/A dsl.dragExit(dse);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * This method calls <code>dragDropEnd</code> on the
0N/A * <code>DragSourceListener</code>s registered with this
0N/A * <code>DragSource</code>, and passes them the specified
0N/A * <code>DragSourceDropEvent</code>.
0N/A *
0N/A * @param dsde the <code>DragSourceEvent</code>
0N/A */
0N/A void processDragDropEnd(DragSourceDropEvent dsde) {
0N/A DragSourceListener dsl = listener;
0N/A if (dsl != null) {
0N/A dsl.dragDropEnd(dsde);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * This method calls <code>dragMouseMoved</code> on the
0N/A * <code>DragSourceMotionListener</code>s registered with this
0N/A * <code>DragSource</code>, and passes them the specified
0N/A * <code>DragSourceDragEvent</code>.
0N/A *
0N/A * @param dsde the <code>DragSourceEvent</code>
0N/A */
0N/A void processDragMouseMoved(DragSourceDragEvent dsde) {
0N/A DragSourceMotionListener dsml = motionListener;
0N/A if (dsml != null) {
0N/A dsml.dragMouseMoved(dsde);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Serializes this <code>DragSource</code>. This method first performs
0N/A * default serialization. Next, it writes out this object's
0N/A * <code>FlavorMap</code> if and only if it can be serialized. If not,
0N/A * <code>null</code> is written instead. Next, it writes out
0N/A * <code>Serializable</code> listeners registered with this
0N/A * object. Listeners are written in a <code>null</code>-terminated sequence
0N/A * of 0 or more pairs. The pair consists of a <code>String</code> and an
0N/A * <code>Object</code>; the <code>String</code> indicates the type of the
0N/A * <code>Object</code> and is one of the following:
0N/A * <ul>
0N/A * <li><code>dragSourceListenerK</code> indicating a
0N/A * <code>DragSourceListener</code> object;
0N/A * <li><code>dragSourceMotionListenerK</code> indicating a
0N/A * <code>DragSourceMotionListener</code> object.
0N/A * </ul>
0N/A *
0N/A * @serialData Either a <code>FlavorMap</code> instance, or
0N/A * <code>null</code>, followed by a <code>null</code>-terminated
0N/A * sequence of 0 or more pairs; the pair consists of a
0N/A * <code>String</code> and an <code>Object</code>; the
0N/A * <code>String</code> indicates the type of the <code>Object</code>
0N/A * and is one of the following:
0N/A * <ul>
0N/A * <li><code>dragSourceListenerK</code> indicating a
0N/A * <code>DragSourceListener</code> object;
0N/A * <li><code>dragSourceMotionListenerK</code> indicating a
0N/A * <code>DragSourceMotionListener</code> object.
0N/A * </ul>.
0N/A * @since 1.4
0N/A */
0N/A private void writeObject(ObjectOutputStream s) throws IOException {
0N/A s.defaultWriteObject();
0N/A
0N/A s.writeObject(SerializationTester.test(flavorMap) ? flavorMap : null);
0N/A
0N/A DnDEventMulticaster.save(s, dragSourceListenerK, listener);
0N/A DnDEventMulticaster.save(s, dragSourceMotionListenerK, motionListener);
0N/A s.writeObject(null);
0N/A }
0N/A
0N/A /**
0N/A * Deserializes this <code>DragSource</code>. This method first performs
0N/A * default deserialization. Next, this object's <code>FlavorMap</code> is
0N/A * deserialized by using the next object in the stream.
0N/A * If the resulting <code>FlavorMap</code> is <code>null</code>, this
0N/A * object's <code>FlavorMap</code> is set to the default FlavorMap for
0N/A * this thread's <code>ClassLoader</code>.
0N/A * Next, this object's listeners are deserialized by reading a
0N/A * <code>null</code>-terminated sequence of 0 or more key/value pairs
0N/A * from the stream:
0N/A * <ul>
0N/A * <li>If a key object is a <code>String</code> equal to
0N/A * <code>dragSourceListenerK</code>, a <code>DragSourceListener</code> is
0N/A * deserialized using the corresponding value object and added to this
0N/A * <code>DragSource</code>.
0N/A * <li>If a key object is a <code>String</code> equal to
0N/A * <code>dragSourceMotionListenerK</code>, a
0N/A * <code>DragSourceMotionListener</code> is deserialized using the
0N/A * corresponding value object and added to this <code>DragSource</code>.
0N/A * <li>Otherwise, the key/value pair is skipped.
0N/A * </ul>
0N/A *
0N/A * @see java.awt.datatransfer.SystemFlavorMap#getDefaultFlavorMap
0N/A * @since 1.4
0N/A */
0N/A private void readObject(ObjectInputStream s)
0N/A throws ClassNotFoundException, IOException {
0N/A s.defaultReadObject();
0N/A
0N/A // 'flavorMap' was written explicitly
0N/A flavorMap = (FlavorMap)s.readObject();
0N/A
0N/A // Implementation assumes 'flavorMap' is never null.
0N/A if (flavorMap == null) {
0N/A flavorMap = SystemFlavorMap.getDefaultFlavorMap();
0N/A }
0N/A
0N/A Object keyOrNull;
0N/A while (null != (keyOrNull = s.readObject())) {
0N/A String key = ((String)keyOrNull).intern();
0N/A
0N/A if (dragSourceListenerK == key) {
0N/A addDragSourceListener((DragSourceListener)(s.readObject()));
0N/A } else if (dragSourceMotionListenerK == key) {
0N/A addDragSourceMotionListener(
0N/A (DragSourceMotionListener)(s.readObject()));
0N/A } else {
0N/A // skip value for unrecognized key
0N/A s.readObject();
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the drag gesture motion threshold. The drag gesture motion threshold
0N/A * defines the recommended behavior for {@link MouseDragGestureRecognizer}s.
0N/A * <p>
0N/A * If the system property <code>awt.dnd.drag.threshold</code> is set to
0N/A * a positive integer, this method returns the value of the system property;
0N/A * otherwise if a pertinent desktop property is available and supported by
0N/A * the implementation of the Java platform, this method returns the value of
0N/A * that property; otherwise this method returns some default value.
0N/A * The pertinent desktop property can be queried using
0N/A * <code>java.awt.Toolkit.getDesktopProperty("DnD.gestureMotionThreshold")</code>.
0N/A *
0N/A * @return the drag gesture motion threshold
0N/A * @see MouseDragGestureRecognizer
0N/A * @since 1.5
0N/A */
0N/A public static int getDragThreshold() {
0N/A int ts = ((Integer)AccessController.doPrivileged(
0N/A new GetIntegerAction("awt.dnd.drag.threshold", 0))).intValue();
0N/A if (ts > 0) {
0N/A return ts;
0N/A } else {
0N/A Integer td = (Integer)Toolkit.getDefaultToolkit().
0N/A getDesktopProperty("DnD.gestureMotionThreshold");
0N/A if (td != null) {
0N/A return td.intValue();
0N/A }
0N/A }
0N/A return 5;
0N/A }
0N/A
0N/A /*
0N/A * fields
0N/A */
0N/A
0N/A private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap();
0N/A
0N/A private transient DragSourceListener listener;
0N/A
0N/A private transient DragSourceMotionListener motionListener;
0N/A}