Home » openjdk-7 » java » awt » dnd » [javadoc | source]

    1   /*
    2    * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package java.awt.dnd;
   27   
   28   import java.awt.Component;
   29   import java.awt.Cursor;
   30   import java.awt.GraphicsEnvironment;
   31   import java.awt.HeadlessException;
   32   import java.awt.Image;
   33   import java.awt.Point;
   34   import java.awt.Toolkit;
   35   import java.awt.datatransfer.FlavorMap;
   36   import java.awt.datatransfer.SystemFlavorMap;
   37   import java.awt.datatransfer.Transferable;
   38   import java.awt.dnd.peer.DragSourceContextPeer;
   39   import java.io.IOException;
   40   import java.io.ObjectInputStream;
   41   import java.io.ObjectOutputStream;
   42   import java.io.Serializable;
   43   import java.security.AccessController;
   44   import java.util.EventListener;
   45   import sun.awt.dnd.SunDragSourceContextPeer;
   46   import sun.security.action.GetIntegerAction;
   47   
   48   
   49   /**
   50    * The <code>DragSource</code> is the entity responsible
   51    * for the initiation of the Drag
   52    * and Drop operation, and may be used in a number of scenarios:
   53    * <UL>
   54    * <LI>1 default instance per JVM for the lifetime of that JVM.
   55    * <LI>1 instance per class of potential Drag Initiator object (e.g
   56    * TextField). [implementation dependent]
   57    * <LI>1 per instance of a particular
   58    * <code>Component</code>, or application specific
   59    * object associated with a <code>Component</code>
   60    * instance in the GUI. [implementation dependent]
   61    * <LI>Some other arbitrary association. [implementation dependent]
   62    *</UL>
   63    *
   64    * Once the <code>DragSource</code> is
   65    * obtained, a <code>DragGestureRecognizer</code> should
   66    * also be obtained to associate the <code>DragSource</code>
   67    * with a particular
   68    * <code>Component</code>.
   69    * <P>
   70    * The initial interpretation of the user's gesture,
   71    * and the subsequent starting of the drag operation
   72    * are the responsibility of the implementing
   73    * <code>Component</code>, which is usually
   74    * implemented by a <code>DragGestureRecognizer</code>.
   75    *<P>
   76    * When a drag gesture occurs, the
   77    * <code>DragSource</code>'s
   78    * startDrag() method shall be
   79    * invoked in order to cause processing
   80    * of the user's navigational
   81    * gestures and delivery of Drag and Drop
   82    * protocol notifications. A
   83    * <code>DragSource</code> shall only
   84    * permit a single Drag and Drop operation to be
   85    * current at any one time, and shall
   86    * reject any further startDrag() requests
   87    * by throwing an <code>IllegalDnDOperationException</code>
   88    * until such time as the extant operation is complete.
   89    * <P>
   90    * The startDrag() method invokes the
   91    * createDragSourceContext() method to
   92    * instantiate an appropriate
   93    * <code>DragSourceContext</code>
   94    * and associate the <code>DragSourceContextPeer</code>
   95    * with that.
   96    * <P>
   97    * If the Drag and Drop System is
   98    * unable to initiate a drag operation for
   99    * some reason, the startDrag() method throws
  100    * a <code>java.awt.dnd.InvalidDnDOperationException</code>
  101    * to signal such a condition. Typically this
  102    * exception is thrown when the underlying platform
  103    * system is either not in a state to
  104    * initiate a drag, or the parameters specified are invalid.
  105    * <P>
  106    * Note that during the drag, the
  107    * set of operations exposed by the source
  108    * at the start of the drag operation may not change
  109    * until the operation is complete.
  110    * The operation(s) are constant for the
  111    * duration of the operation with respect to the
  112    * <code>DragSource</code>.
  113    *
  114    * @since 1.2
  115    */
  116   
  117   public class DragSource implements Serializable {
  118   
  119       private static final long serialVersionUID = 6236096958971414066L;
  120   
  121       /*
  122        * load a system default cursor
  123        */
  124   
  125       private static Cursor load(String name) {
  126           if (GraphicsEnvironment.isHeadless()) {
  127               return null;
  128           }
  129   
  130           try {
  131               return (Cursor)Toolkit.getDefaultToolkit().getDesktopProperty(name);
  132           } catch (Exception e) {
  133               e.printStackTrace();
  134   
  135               throw new RuntimeException("failed to load system cursor: " + name + " : " + e.getMessage());
  136           }
  137       }
  138   
  139   
  140       /**
  141        * The default <code>Cursor</code> to use with a copy operation indicating
  142        * that a drop is currently allowed. <code>null</code> if
  143        * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
  144        *
  145        * @see java.awt.GraphicsEnvironment#isHeadless
  146        */
  147       public static final Cursor DefaultCopyDrop =
  148           load("DnD.Cursor.CopyDrop");
  149   
  150       /**
  151        * The default <code>Cursor</code> to use with a move operation indicating
  152        * that a drop is currently allowed. <code>null</code> if
  153        * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
  154        *
  155        * @see java.awt.GraphicsEnvironment#isHeadless
  156        */
  157       public static final Cursor DefaultMoveDrop =
  158           load("DnD.Cursor.MoveDrop");
  159   
  160       /**
  161        * The default <code>Cursor</code> to use with a link operation indicating
  162        * that a drop is currently allowed. <code>null</code> if
  163        * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
  164        *
  165        * @see java.awt.GraphicsEnvironment#isHeadless
  166        */
  167       public static final Cursor DefaultLinkDrop =
  168           load("DnD.Cursor.LinkDrop");
  169   
  170       /**
  171        * The default <code>Cursor</code> to use with a copy operation indicating
  172        * that a drop is currently not allowed. <code>null</code> if
  173        * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
  174        *
  175        * @see java.awt.GraphicsEnvironment#isHeadless
  176        */
  177       public static final Cursor DefaultCopyNoDrop =
  178           load("DnD.Cursor.CopyNoDrop");
  179   
  180       /**
  181        * The default <code>Cursor</code> to use with a move operation indicating
  182        * that a drop is currently not allowed. <code>null</code> if
  183        * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
  184        *
  185        * @see java.awt.GraphicsEnvironment#isHeadless
  186        */
  187       public static final Cursor DefaultMoveNoDrop =
  188           load("DnD.Cursor.MoveNoDrop");
  189   
  190       /**
  191        * The default <code>Cursor</code> to use with a link operation indicating
  192        * that a drop is currently not allowed. <code>null</code> if
  193        * <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>.
  194        *
  195        * @see java.awt.GraphicsEnvironment#isHeadless
  196        */
  197       public static final Cursor DefaultLinkNoDrop =
  198           load("DnD.Cursor.LinkNoDrop");
  199   
  200       private static final DragSource dflt =
  201           (GraphicsEnvironment.isHeadless()) ? null : new DragSource();
  202   
  203       /**
  204        * Internal constants for serialization.
  205        */
  206       static final String dragSourceListenerK = "dragSourceL";
  207       static final String dragSourceMotionListenerK = "dragSourceMotionL";
  208   
  209       /**
  210        * Gets the <code>DragSource</code> object associated with
  211        * the underlying platform.
  212        *
  213        * @return the platform DragSource
  214        * @exception HeadlessException if GraphicsEnvironment.isHeadless()
  215        *            returns true
  216        * @see java.awt.GraphicsEnvironment#isHeadless
  217        */
  218       public static DragSource getDefaultDragSource() {
  219           if (GraphicsEnvironment.isHeadless()) {
  220               throw new HeadlessException();
  221           } else {
  222               return dflt;
  223           }
  224       }
  225   
  226       /**
  227        * Reports
  228        * whether or not drag
  229        * <code>Image</code> support
  230        * is available on the underlying platform.
  231        * <P>
  232        * @return if the Drag Image support is available on this platform
  233        */
  234   
  235       public static boolean isDragImageSupported() {
  236           Toolkit t = Toolkit.getDefaultToolkit();
  237   
  238           Boolean supported;
  239   
  240           try {
  241               supported = (Boolean)Toolkit.getDefaultToolkit().getDesktopProperty("DnD.isDragImageSupported");
  242   
  243               return supported.booleanValue();
  244           } catch (Exception e) {
  245               return false;
  246           }
  247       }
  248   
  249       /**
  250        * Creates a new <code>DragSource</code>.
  251        *
  252        * @exception HeadlessException if GraphicsEnvironment.isHeadless()
  253        *            returns true
  254        * @see java.awt.GraphicsEnvironment#isHeadless
  255        */
  256       public DragSource() throws HeadlessException {
  257           if (GraphicsEnvironment.isHeadless()) {
  258               throw new HeadlessException();
  259           }
  260       }
  261   
  262       /**
  263        * Start a drag, given the <code>DragGestureEvent</code>
  264        * that initiated the drag, the initial
  265        * <code>Cursor</code> to use,
  266        * the <code>Image</code> to drag,
  267        * the offset of the <code>Image</code> origin
  268        * from the hotspot of the <code>Cursor</code> at
  269        * the instant of the trigger,
  270        * the <code>Transferable</code> subject data
  271        * of the drag, the <code>DragSourceListener</code>,
  272        * and the <code>FlavorMap</code>.
  273        * <P>
  274        * @param trigger        the <code>DragGestureEvent</code> that initiated the drag
  275        * @param dragCursor     the initial {@code Cursor} for this drag operation
  276        *                       or {@code null} for the default cursor handling;
  277        *                       see <a href="DragSourceContext.html#defaultCursor">DragSourceContext</a>
  278        *                       for more details on the cursor handling mechanism during drag and drop
  279        * @param dragImage      the image to drag or {@code null}
  280        * @param imageOffset    the offset of the <code>Image</code> origin from the hotspot
  281        *                       of the <code>Cursor</code> at the instant of the trigger
  282        * @param transferable   the subject data of the drag
  283        * @param dsl            the <code>DragSourceListener</code>
  284        * @param flavorMap      the <code>FlavorMap</code> to use, or <code>null</code>
  285        * <P>
  286        * @throws java.awt.dnd.InvalidDnDOperationException
  287        *    if the Drag and Drop
  288        *    system is unable to initiate a drag operation, or if the user
  289        *    attempts to start a drag while an existing drag operation
  290        *    is still executing
  291        */
  292   
  293       public void startDrag(DragGestureEvent   trigger,
  294                             Cursor             dragCursor,
  295                             Image              dragImage,
  296                             Point              imageOffset,
  297                             Transferable       transferable,
  298                             DragSourceListener dsl,
  299                             FlavorMap          flavorMap) throws InvalidDnDOperationException {
  300   
  301           SunDragSourceContextPeer.setDragDropInProgress(true);
  302   
  303           try {
  304               if (flavorMap != null) this.flavorMap = flavorMap;
  305   
  306               DragSourceContextPeer dscp = Toolkit.getDefaultToolkit().createDragSourceContextPeer(trigger);
  307   
  308               DragSourceContext     dsc = createDragSourceContext(dscp,
  309                                                                   trigger,
  310                                                                   dragCursor,
  311                                                                   dragImage,
  312                                                                   imageOffset,
  313                                                                   transferable,
  314                                                                   dsl
  315                                                                   );
  316   
  317               if (dsc == null) {
  318                   throw new InvalidDnDOperationException();
  319               }
  320   
  321               dscp.startDrag(dsc, dsc.getCursor(), dragImage, imageOffset); // may throw
  322           } catch (RuntimeException e) {
  323               SunDragSourceContextPeer.setDragDropInProgress(false);
  324               throw e;
  325           }
  326       }
  327   
  328       /**
  329        * Start a drag, given the <code>DragGestureEvent</code>
  330        * that initiated the drag, the initial
  331        * <code>Cursor</code> to use,
  332        * the <code>Transferable</code> subject data
  333        * of the drag, the <code>DragSourceListener</code>,
  334        * and the <code>FlavorMap</code>.
  335        * <P>
  336        * @param trigger        the <code>DragGestureEvent</code> that
  337        * initiated the drag
  338        * @param dragCursor     the initial {@code Cursor} for this drag operation
  339        *                       or {@code null} for the default cursor handling;
  340        *                       see <a href="DragSourceContext.html#defaultCursor">DragSourceContext</a>
  341        *                       for more details on the cursor handling mechanism during drag and drop
  342        * @param transferable   the subject data of the drag
  343        * @param dsl            the <code>DragSourceListener</code>
  344        * @param flavorMap      the <code>FlavorMap</code> to use or <code>null</code>
  345        * <P>
  346        * @throws java.awt.dnd.InvalidDnDOperationException
  347        *    if the Drag and Drop
  348        *    system is unable to initiate a drag operation, or if the user
  349        *    attempts to start a drag while an existing drag operation
  350        *    is still executing
  351        */
  352   
  353       public void startDrag(DragGestureEvent   trigger,
  354                             Cursor             dragCursor,
  355                             Transferable       transferable,
  356                             DragSourceListener dsl,
  357                             FlavorMap          flavorMap) throws InvalidDnDOperationException {
  358           startDrag(trigger, dragCursor, null, null, transferable, dsl, flavorMap);
  359       }
  360   
  361       /**
  362        * Start a drag, given the <code>DragGestureEvent</code>
  363        * that initiated the drag, the initial <code>Cursor</code>
  364        * to use,
  365        * the <code>Image</code> to drag,
  366        * the offset of the <code>Image</code> origin
  367        * from the hotspot of the <code>Cursor</code>
  368        * at the instant of the trigger,
  369        * the subject data of the drag, and
  370        * the <code>DragSourceListener</code>.
  371        * <P>
  372        * @param trigger           the <code>DragGestureEvent</code> that initiated the drag
  373        * @param dragCursor     the initial {@code Cursor} for this drag operation
  374        *                       or {@code null} for the default cursor handling;
  375        *                       see <a href="DragSourceContext.html#defaultCursor">DragSourceContext</a>
  376        *                       for more details on the cursor handling mechanism during drag and drop
  377        * @param dragImage         the <code>Image</code> to drag or <code>null</code>
  378        * @param dragOffset        the offset of the <code>Image</code> origin from the hotspot
  379        *                          of the <code>Cursor</code> at the instant of the trigger
  380        * @param transferable      the subject data of the drag
  381        * @param dsl               the <code>DragSourceListener</code>
  382        * <P>
  383        * @throws java.awt.dnd.InvalidDnDOperationException
  384        *    if the Drag and Drop
  385        *    system is unable to initiate a drag operation, or if the user
  386        *    attempts to start a drag while an existing drag operation
  387        *    is still executing
  388        */
  389   
  390       public void startDrag(DragGestureEvent   trigger,
  391                             Cursor             dragCursor,
  392                             Image              dragImage,
  393                             Point              dragOffset,
  394                             Transferable       transferable,
  395                             DragSourceListener dsl) throws InvalidDnDOperationException {
  396           startDrag(trigger, dragCursor, dragImage, dragOffset, transferable, dsl, null);
  397       }
  398   
  399       /**
  400        * Start a drag, given the <code>DragGestureEvent</code>
  401        * that initiated the drag, the initial
  402        * <code>Cursor</code> to
  403        * use,
  404        * the <code>Transferable</code> subject data
  405        * of the drag, and the <code>DragSourceListener</code>.
  406        * <P>
  407        * @param trigger           the <code>DragGestureEvent</code> that initiated the drag
  408        * @param dragCursor     the initial {@code Cursor} for this drag operation
  409        *                       or {@code null} for the default cursor handling;
  410        *                       see <a href="DragSourceContext.html#defaultCursor">DragSourceContext</a> class
  411        *                       for more details on the cursor handling mechanism during drag and drop
  412        * @param transferable      the subject data of the drag
  413        * @param dsl               the <code>DragSourceListener</code>
  414        * <P>
  415        * @throws java.awt.dnd.InvalidDnDOperationException
  416        *    if the Drag and Drop
  417        *    system is unable to initiate a drag operation, or if the user
  418        *    attempts to start a drag while an existing drag operation
  419        *    is still executing
  420        */
  421   
  422       public void startDrag(DragGestureEvent   trigger,
  423                             Cursor             dragCursor,
  424                             Transferable       transferable,
  425                             DragSourceListener dsl) throws InvalidDnDOperationException {
  426           startDrag(trigger, dragCursor, null, null, transferable, dsl, null);
  427       }
  428   
  429       /**
  430        * Creates the {@code DragSourceContext} to handle the current drag
  431        * operation.
  432        * <p>
  433        * To incorporate a new <code>DragSourceContext</code>
  434        * subclass, subclass <code>DragSource</code> and
  435        * override this method.
  436        * <p>
  437        * If <code>dragImage</code> is <code>null</code>, no image is used
  438        * to represent the drag over feedback for this drag operation, but
  439        * <code>NullPointerException</code> is not thrown.
  440        * <p>
  441        * If <code>dsl</code> is <code>null</code>, no drag source listener
  442        * is registered with the created <code>DragSourceContext</code>,
  443        * but <code>NullPointerException</code> is not thrown.
  444        *
  445        * @param dscp          The <code>DragSourceContextPeer</code> for this drag
  446        * @param dgl           The <code>DragGestureEvent</code> that triggered the
  447        *                      drag
  448        * @param dragCursor     The initial {@code Cursor} for this drag operation
  449        *                       or {@code null} for the default cursor handling;
  450        *                       see <a href="DragSourceContext.html#defaultCursor">DragSourceContext</a> class
  451        *                       for more details on the cursor handling mechanism during drag and drop
  452        * @param dragImage     The <code>Image</code> to drag or <code>null</code>
  453        * @param imageOffset   The offset of the <code>Image</code> origin from the
  454        *                      hotspot of the cursor at the instant of the trigger
  455        * @param t             The subject data of the drag
  456        * @param dsl           The <code>DragSourceListener</code>
  457        *
  458        * @return the <code>DragSourceContext</code>
  459        *
  460        * @throws NullPointerException if <code>dscp</code> is <code>null</code>
  461        * @throws NullPointerException if <code>dgl</code> is <code>null</code>
  462        * @throws NullPointerException if <code>dragImage</code> is not
  463        *    <code>null</code> and <code>imageOffset</code> is <code>null</code>
  464        * @throws NullPointerException if <code>t</code> is <code>null</code>
  465        * @throws IllegalArgumentException if the <code>Component</code>
  466        *         associated with the trigger event is <code>null</code>.
  467        * @throws IllegalArgumentException if the <code>DragSource</code> for the
  468        *         trigger event is <code>null</code>.
  469        * @throws IllegalArgumentException if the drag action for the
  470        *         trigger event is <code>DnDConstants.ACTION_NONE</code>.
  471        * @throws IllegalArgumentException if the source actions for the
  472        *         <code>DragGestureRecognizer</code> associated with the trigger
  473        *         event are equal to <code>DnDConstants.ACTION_NONE</code>.
  474        */
  475   
  476       protected DragSourceContext createDragSourceContext(DragSourceContextPeer dscp, DragGestureEvent dgl, Cursor dragCursor, Image dragImage, Point imageOffset, Transferable t, DragSourceListener dsl) {
  477           return new DragSourceContext(dscp, dgl, dragCursor, dragImage, imageOffset, t, dsl);
  478       }
  479   
  480       /**
  481        * This method returns the
  482        * <code>FlavorMap</code> for this <code>DragSource</code>.
  483        * <P>
  484        * @return the <code>FlavorMap</code> for this <code>DragSource</code>
  485        */
  486   
  487       public FlavorMap getFlavorMap() { return flavorMap; }
  488   
  489       /**
  490        * Creates a new <code>DragGestureRecognizer</code>
  491        * that implements the specified
  492        * abstract subclass of
  493        * <code>DragGestureRecognizer</code>, and
  494        * sets the specified <code>Component</code>
  495        * and <code>DragGestureListener</code> on
  496        * the newly created object.
  497        * <P>
  498        * @param recognizerAbstractClass the requested abstract type
  499        * @param actions                 the permitted source drag actions
  500        * @param c                       the <code>Component</code> target
  501        * @param dgl        the <code>DragGestureListener</code> to notify
  502        * <P>
  503        * @return the new <code>DragGestureRecognizer</code> or <code>null</code>
  504        *    if the <code>Toolkit.createDragGestureRecognizer</code> method
  505        *    has no implementation available for
  506        *    the requested <code>DragGestureRecognizer</code>
  507        *    subclass and returns <code>null</code>
  508        */
  509   
  510       public <T extends DragGestureRecognizer> T
  511           createDragGestureRecognizer(Class<T> recognizerAbstractClass,
  512                                       Component c, int actions,
  513                                       DragGestureListener dgl)
  514       {
  515           return Toolkit.getDefaultToolkit().createDragGestureRecognizer(recognizerAbstractClass, this, c, actions, dgl);
  516       }
  517   
  518   
  519       /**
  520        * Creates a new <code>DragGestureRecognizer</code>
  521        * that implements the default
  522        * abstract subclass of <code>DragGestureRecognizer</code>
  523        * for this <code>DragSource</code>,
  524        * and sets the specified <code>Component</code>
  525        * and <code>DragGestureListener</code> on the
  526        * newly created object.
  527        *
  528        * For this <code>DragSource</code>
  529        * the default is <code>MouseDragGestureRecognizer</code>.
  530        * <P>
  531        * @param c       the <code>Component</code> target for the recognizer
  532        * @param actions the permitted source actions
  533        * @param dgl     the <code>DragGestureListener</code> to notify
  534        * <P>
  535        * @return the new <code>DragGestureRecognizer</code> or <code>null</code>
  536        *    if the <code>Toolkit.createDragGestureRecognizer</code> method
  537        *    has no implementation available for
  538        *    the requested <code>DragGestureRecognizer</code>
  539        *    subclass and returns <code>null</code>
  540        */
  541   
  542       public DragGestureRecognizer createDefaultDragGestureRecognizer(Component c, int actions, DragGestureListener dgl) {
  543           return Toolkit.getDefaultToolkit().createDragGestureRecognizer(MouseDragGestureRecognizer.class, this, c, actions, dgl);
  544       }
  545   
  546       /**
  547        * Adds the specified <code>DragSourceListener</code> to this
  548        * <code>DragSource</code> to receive drag source events during drag
  549        * operations intiated with this <code>DragSource</code>.
  550        * If a <code>null</code> listener is specified, no action is taken and no
  551        * exception is thrown.
  552        *
  553        * @param dsl the <code>DragSourceListener</code> to add
  554        *
  555        * @see      #removeDragSourceListener
  556        * @see      #getDragSourceListeners
  557        * @since 1.4
  558        */
  559       public void addDragSourceListener(DragSourceListener dsl) {
  560           if (dsl != null) {
  561               synchronized (this) {
  562                   listener = DnDEventMulticaster.add(listener, dsl);
  563               }
  564           }
  565       }
  566   
  567       /**
  568        * Removes the specified <code>DragSourceListener</code> from this
  569        * <code>DragSource</code>.
  570        * If a <code>null</code> listener is specified, no action is taken and no
  571        * exception is thrown.
  572        * If the listener specified by the argument was not previously added to
  573        * this <code>DragSource</code>, no action is taken and no exception
  574        * is thrown.
  575        *
  576        * @param dsl the <code>DragSourceListener</code> to remove
  577        *
  578        * @see      #addDragSourceListener
  579        * @see      #getDragSourceListeners
  580        * @since 1.4
  581        */
  582       public void removeDragSourceListener(DragSourceListener dsl) {
  583           if (dsl != null) {
  584               synchronized (this) {
  585                   listener = DnDEventMulticaster.remove(listener, dsl);
  586               }
  587           }
  588       }
  589   
  590       /**
  591        * Gets all the <code>DragSourceListener</code>s
  592        * registered with this <code>DragSource</code>.
  593        *
  594        * @return all of this <code>DragSource</code>'s
  595        *         <code>DragSourceListener</code>s or an empty array if no
  596        *         such listeners are currently registered
  597        *
  598        * @see      #addDragSourceListener
  599        * @see      #removeDragSourceListener
  600        * @since    1.4
  601        */
  602       public DragSourceListener[] getDragSourceListeners() {
  603           return (DragSourceListener[])getListeners(DragSourceListener.class);
  604       }
  605   
  606       /**
  607        * Adds the specified <code>DragSourceMotionListener</code> to this
  608        * <code>DragSource</code> to receive drag motion events during drag
  609        * operations intiated with this <code>DragSource</code>.
  610        * If a <code>null</code> listener is specified, no action is taken and no
  611        * exception is thrown.
  612        *
  613        * @param dsml the <code>DragSourceMotionListener</code> to add
  614        *
  615        * @see      #removeDragSourceMotionListener
  616        * @see      #getDragSourceMotionListeners
  617        * @since 1.4
  618        */
  619       public void addDragSourceMotionListener(DragSourceMotionListener dsml) {
  620           if (dsml != null) {
  621               synchronized (this) {
  622                   motionListener = DnDEventMulticaster.add(motionListener, dsml);
  623               }
  624           }
  625       }
  626   
  627       /**
  628        * Removes the specified <code>DragSourceMotionListener</code> from this
  629        * <code>DragSource</code>.
  630        * If a <code>null</code> listener is specified, no action is taken and no
  631        * exception is thrown.
  632        * If the listener specified by the argument was not previously added to
  633        * this <code>DragSource</code>, no action is taken and no exception
  634        * is thrown.
  635        *
  636        * @param dsml the <code>DragSourceMotionListener</code> to remove
  637        *
  638        * @see      #addDragSourceMotionListener
  639        * @see      #getDragSourceMotionListeners
  640        * @since 1.4
  641        */
  642       public void removeDragSourceMotionListener(DragSourceMotionListener dsml) {
  643           if (dsml != null) {
  644               synchronized (this) {
  645                   motionListener = DnDEventMulticaster.remove(motionListener, dsml);
  646               }
  647           }
  648       }
  649   
  650       /**
  651        * Gets all of the  <code>DragSourceMotionListener</code>s
  652        * registered with this <code>DragSource</code>.
  653        *
  654        * @return all of this <code>DragSource</code>'s
  655        *         <code>DragSourceMotionListener</code>s or an empty array if no
  656        *         such listeners are currently registered
  657        *
  658        * @see      #addDragSourceMotionListener
  659        * @see      #removeDragSourceMotionListener
  660        * @since    1.4
  661        */
  662       public DragSourceMotionListener[] getDragSourceMotionListeners() {
  663           return (DragSourceMotionListener[])
  664               getListeners(DragSourceMotionListener.class);
  665       }
  666   
  667       /**
  668        * Gets all the objects currently registered as
  669        * <code><em>Foo</em>Listener</code>s upon this <code>DragSource</code>.
  670        * <code><em>Foo</em>Listener</code>s are registered using the
  671        * <code>add<em>Foo</em>Listener</code> method.
  672        *
  673        * @param listenerType the type of listeners requested; this parameter
  674        *          should specify an interface that descends from
  675        *          <code>java.util.EventListener</code>
  676        * @return an array of all objects registered as
  677        *          <code><em>Foo</em>Listener</code>s on this
  678        *          <code>DragSource</code>, or an empty array if no such listeners
  679        *          have been added
  680        * @exception <code>ClassCastException</code> if <code>listenerType</code>
  681        *          doesn't specify a class or interface that implements
  682        *          <code>java.util.EventListener</code>
  683        *
  684        * @see #getDragSourceListeners
  685        * @see #getDragSourceMotionListeners
  686        * @since 1.4
  687        */
  688       public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
  689           EventListener l = null;
  690           if (listenerType == DragSourceListener.class) {
  691               l = listener;
  692           } else if (listenerType == DragSourceMotionListener.class) {
  693               l = motionListener;
  694           }
  695           return DnDEventMulticaster.getListeners(l, listenerType);
  696       }
  697   
  698       /**
  699        * This method calls <code>dragEnter</code> on the
  700        * <code>DragSourceListener</code>s registered with this
  701        * <code>DragSource</code>, and passes them the specified
  702        * <code>DragSourceDragEvent</code>.
  703        *
  704        * @param dsde the <code>DragSourceDragEvent</code>
  705        */
  706       void processDragEnter(DragSourceDragEvent dsde) {
  707           DragSourceListener dsl = listener;
  708           if (dsl != null) {
  709               dsl.dragEnter(dsde);
  710           }
  711       }
  712   
  713       /**
  714        * This method calls <code>dragOver</code> on the
  715        * <code>DragSourceListener</code>s registered with this
  716        * <code>DragSource</code>, and passes them the specified
  717        * <code>DragSourceDragEvent</code>.
  718        *
  719        * @param dsde the <code>DragSourceDragEvent</code>
  720        */
  721       void processDragOver(DragSourceDragEvent dsde) {
  722           DragSourceListener dsl = listener;
  723           if (dsl != null) {
  724               dsl.dragOver(dsde);
  725           }
  726       }
  727   
  728       /**
  729        * This method calls <code>dropActionChanged</code> on the
  730        * <code>DragSourceListener</code>s registered with this
  731        * <code>DragSource</code>, and passes them the specified
  732        * <code>DragSourceDragEvent</code>.
  733        *
  734        * @param dsde the <code>DragSourceDragEvent</code>
  735        */
  736       void processDropActionChanged(DragSourceDragEvent dsde) {
  737           DragSourceListener dsl = listener;
  738           if (dsl != null) {
  739               dsl.dropActionChanged(dsde);
  740           }
  741       }
  742   
  743       /**
  744        * This method calls <code>dragExit</code> on the
  745        * <code>DragSourceListener</code>s registered with this
  746        * <code>DragSource</code>, and passes them the specified
  747        * <code>DragSourceEvent</code>.
  748        *
  749        * @param dse the <code>DragSourceEvent</code>
  750        */
  751       void processDragExit(DragSourceEvent dse) {
  752           DragSourceListener dsl = listener;
  753           if (dsl != null) {
  754               dsl.dragExit(dse);
  755           }
  756       }
  757   
  758       /**
  759        * This method calls <code>dragDropEnd</code> on the
  760        * <code>DragSourceListener</code>s registered with this
  761        * <code>DragSource</code>, and passes them the specified
  762        * <code>DragSourceDropEvent</code>.
  763        *
  764        * @param dsde the <code>DragSourceEvent</code>
  765        */
  766       void processDragDropEnd(DragSourceDropEvent dsde) {
  767           DragSourceListener dsl = listener;
  768           if (dsl != null) {
  769               dsl.dragDropEnd(dsde);
  770           }
  771       }
  772   
  773       /**
  774        * This method calls <code>dragMouseMoved</code> on the
  775        * <code>DragSourceMotionListener</code>s registered with this
  776        * <code>DragSource</code>, and passes them the specified
  777        * <code>DragSourceDragEvent</code>.
  778        *
  779        * @param dsde the <code>DragSourceEvent</code>
  780        */
  781       void processDragMouseMoved(DragSourceDragEvent dsde) {
  782           DragSourceMotionListener dsml = motionListener;
  783           if (dsml != null) {
  784               dsml.dragMouseMoved(dsde);
  785           }
  786       }
  787   
  788       /**
  789        * Serializes this <code>DragSource</code>. This method first performs
  790        * default serialization. Next, it writes out this object's
  791        * <code>FlavorMap</code> if and only if it can be serialized. If not,
  792        * <code>null</code> is written instead. Next, it writes out
  793        * <code>Serializable</code> listeners registered with this
  794        * object. Listeners are written in a <code>null</code>-terminated sequence
  795        * of 0 or more pairs. The pair consists of a <code>String</code> and an
  796        * <code>Object</code>; the <code>String</code> indicates the type of the
  797        * <code>Object</code> and is one of the following:
  798        * <ul>
  799        * <li><code>dragSourceListenerK</code> indicating a
  800        *     <code>DragSourceListener</code> object;
  801        * <li><code>dragSourceMotionListenerK</code> indicating a
  802        *     <code>DragSourceMotionListener</code> object.
  803        * </ul>
  804        *
  805        * @serialData Either a <code>FlavorMap</code> instance, or
  806        *      <code>null</code>, followed by a <code>null</code>-terminated
  807        *      sequence of 0 or more pairs; the pair consists of a
  808        *      <code>String</code> and an <code>Object</code>; the
  809        *      <code>String</code> indicates the type of the <code>Object</code>
  810        *      and is one of the following:
  811        *      <ul>
  812        *      <li><code>dragSourceListenerK</code> indicating a
  813        *          <code>DragSourceListener</code> object;
  814        *      <li><code>dragSourceMotionListenerK</code> indicating a
  815        *          <code>DragSourceMotionListener</code> object.
  816        *      </ul>.
  817        * @since 1.4
  818        */
  819       private void writeObject(ObjectOutputStream s) throws IOException {
  820           s.defaultWriteObject();
  821   
  822           s.writeObject(SerializationTester.test(flavorMap) ? flavorMap : null);
  823   
  824           DnDEventMulticaster.save(s, dragSourceListenerK, listener);
  825           DnDEventMulticaster.save(s, dragSourceMotionListenerK, motionListener);
  826           s.writeObject(null);
  827       }
  828   
  829       /**
  830        * Deserializes this <code>DragSource</code>. This method first performs
  831        * default deserialization. Next, this object's <code>FlavorMap</code> is
  832        * deserialized by using the next object in the stream.
  833        * If the resulting <code>FlavorMap</code> is <code>null</code>, this
  834        * object's <code>FlavorMap</code> is set to the default FlavorMap for
  835        * this thread's <code>ClassLoader</code>.
  836        * Next, this object's listeners are deserialized by reading a
  837        * <code>null</code>-terminated sequence of 0 or more key/value pairs
  838        * from the stream:
  839        * <ul>
  840        * <li>If a key object is a <code>String</code> equal to
  841        * <code>dragSourceListenerK</code>, a <code>DragSourceListener</code> is
  842        * deserialized using the corresponding value object and added to this
  843        * <code>DragSource</code>.
  844        * <li>If a key object is a <code>String</code> equal to
  845        * <code>dragSourceMotionListenerK</code>, a
  846        * <code>DragSourceMotionListener</code> is deserialized using the
  847        * corresponding value object and added to this <code>DragSource</code>.
  848        * <li>Otherwise, the key/value pair is skipped.
  849        * </ul>
  850        *
  851        * @see java.awt.datatransfer.SystemFlavorMap#getDefaultFlavorMap
  852        * @since 1.4
  853        */
  854       private void readObject(ObjectInputStream s)
  855         throws ClassNotFoundException, IOException {
  856           s.defaultReadObject();
  857   
  858           // 'flavorMap' was written explicitly
  859           flavorMap = (FlavorMap)s.readObject();
  860   
  861           // Implementation assumes 'flavorMap' is never null.
  862           if (flavorMap == null) {
  863               flavorMap = SystemFlavorMap.getDefaultFlavorMap();
  864           }
  865   
  866           Object keyOrNull;
  867           while (null != (keyOrNull = s.readObject())) {
  868               String key = ((String)keyOrNull).intern();
  869   
  870               if (dragSourceListenerK == key) {
  871                   addDragSourceListener((DragSourceListener)(s.readObject()));
  872               } else if (dragSourceMotionListenerK == key) {
  873                   addDragSourceMotionListener(
  874                       (DragSourceMotionListener)(s.readObject()));
  875               } else {
  876                   // skip value for unrecognized key
  877                   s.readObject();
  878               }
  879           }
  880       }
  881   
  882       /**
  883        * Returns the drag gesture motion threshold. The drag gesture motion threshold
  884        * defines the recommended behavior for {@link MouseDragGestureRecognizer}s.
  885        * <p>
  886        * If the system property <code>awt.dnd.drag.threshold</code> is set to
  887        * a positive integer, this method returns the value of the system property;
  888        * otherwise if a pertinent desktop property is available and supported by
  889        * the implementation of the Java platform, this method returns the value of
  890        * that property; otherwise this method returns some default value.
  891        * The pertinent desktop property can be queried using
  892        * <code>java.awt.Toolkit.getDesktopProperty("DnD.gestureMotionThreshold")</code>.
  893        *
  894        * @return the drag gesture motion threshold
  895        * @see MouseDragGestureRecognizer
  896        * @since 1.5
  897        */
  898       public static int getDragThreshold() {
  899           int ts = ((Integer)AccessController.doPrivileged(
  900                   new GetIntegerAction("awt.dnd.drag.threshold", 0))).intValue();
  901           if (ts > 0) {
  902               return ts;
  903           } else {
  904               Integer td = (Integer)Toolkit.getDefaultToolkit().
  905                       getDesktopProperty("DnD.gestureMotionThreshold");
  906               if (td != null) {
  907                   return td.intValue();
  908               }
  909           }
  910           return 5;
  911       }
  912   
  913       /*
  914        * fields
  915        */
  916   
  917       private transient FlavorMap flavorMap = SystemFlavorMap.getDefaultFlavorMap();
  918   
  919       private transient DragSourceListener listener;
  920   
  921       private transient DragSourceMotionListener motionListener;
  922   }

Home » openjdk-7 » java » awt » dnd » [javadoc | source]