1 /*
   2  * Copyright (c) 2001, 2014, 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 package java.awt.dnd;
  26 
  27 import java.awt.AWTEventMulticaster;
  28 import java.io.ObjectOutputStream;
  29 import java.io.IOException;
  30 import java.util.EventListener;
  31 
  32 
  33 /**
  34  * A class extends {@code AWTEventMulticaster} to implement efficient and
  35  * thread-safe multi-cast event dispatching for the drag-and-drop events defined
  36  * in the java.awt.dnd package.
  37  *
  38  * @since       1.4
  39  * @see AWTEventMulticaster
  40  */
  41 
  42 class DnDEventMulticaster extends AWTEventMulticaster
  43     implements DragSourceListener, DragSourceMotionListener {
  44 
  45     /**
  46      * Creates an event multicaster instance which chains listener-a
  47      * with listener-b. Input parameters {@code a} and {@code b}
  48      * should not be {@code null}, though implementations may vary in
  49      * choosing whether or not to throw {@code NullPointerException}
  50      * in that case.
  51      *
  52      * @param a listener-a
  53      * @param b listener-b
  54      */
  55     protected DnDEventMulticaster(EventListener a, EventListener b) {
  56         super(a,b);
  57     }
  58 
  59     /**
  60      * Handles the {@code DragSourceDragEvent} by invoking
  61      * {@code dragEnter} on listener-a and listener-b.
  62      *
  63      * @param dsde the {@code DragSourceDragEvent}
  64      */
  65     public void dragEnter(DragSourceDragEvent dsde) {
  66         ((DragSourceListener)a).dragEnter(dsde);
  67         ((DragSourceListener)b).dragEnter(dsde);
  68     }
  69 
  70     /**
  71      * Handles the {@code DragSourceDragEvent} by invoking
  72      * {@code dragOver} on listener-a and listener-b.
  73      *
  74      * @param dsde the {@code DragSourceDragEvent}
  75      */
  76     public void dragOver(DragSourceDragEvent dsde) {
  77         ((DragSourceListener)a).dragOver(dsde);
  78         ((DragSourceListener)b).dragOver(dsde);
  79     }
  80 
  81     /**
  82      * Handles the {@code DragSourceDragEvent} by invoking
  83      * {@code dropActionChanged} on listener-a and listener-b.
  84      *
  85      * @param dsde the {@code DragSourceDragEvent}
  86      */
  87     public void dropActionChanged(DragSourceDragEvent dsde) {
  88         ((DragSourceListener)a).dropActionChanged(dsde);
  89         ((DragSourceListener)b).dropActionChanged(dsde);
  90     }
  91 
  92     /**
  93      * Handles the {@code DragSourceEvent} by invoking
  94      * {@code dragExit} on listener-a and listener-b.
  95      *
  96      * @param dse the {@code DragSourceEvent}
  97      */
  98     public void dragExit(DragSourceEvent dse) {
  99         ((DragSourceListener)a).dragExit(dse);
 100         ((DragSourceListener)b).dragExit(dse);
 101     }
 102 
 103     /**
 104      * Handles the {@code DragSourceDropEvent} by invoking
 105      * {@code dragDropEnd} on listener-a and listener-b.
 106      *
 107      * @param dsde the {@code DragSourceDropEvent}
 108      */
 109     public void dragDropEnd(DragSourceDropEvent dsde) {
 110         ((DragSourceListener)a).dragDropEnd(dsde);
 111         ((DragSourceListener)b).dragDropEnd(dsde);
 112     }
 113 
 114     /**
 115      * Handles the {@code DragSourceDragEvent} by invoking
 116      * {@code dragMouseMoved} on listener-a and listener-b.
 117      *
 118      * @param dsde the {@code DragSourceDragEvent}
 119      */
 120     public void dragMouseMoved(DragSourceDragEvent dsde) {
 121         ((DragSourceMotionListener)a).dragMouseMoved(dsde);
 122         ((DragSourceMotionListener)b).dragMouseMoved(dsde);
 123     }
 124 
 125     /**
 126      * Adds drag-source-listener-a with drag-source-listener-b and
 127      * returns the resulting multicast listener.
 128      *
 129      * @param a drag-source-listener-a
 130      * @param b drag-source-listener-b
 131      */
 132     public static DragSourceListener add(DragSourceListener a,
 133                                          DragSourceListener b) {
 134         return (DragSourceListener)addInternal(a, b);
 135     }
 136 
 137     /**
 138      * Adds drag-source-motion-listener-a with drag-source-motion-listener-b and
 139      * returns the resulting multicast listener.
 140      *
 141      * @param a drag-source-motion-listener-a
 142      * @param b drag-source-motion-listener-b
 143      */
 144     @SuppressWarnings("overloads")
 145     public static DragSourceMotionListener add(DragSourceMotionListener a,
 146                                                DragSourceMotionListener b) {
 147         return (DragSourceMotionListener)addInternal(a, b);
 148     }
 149 
 150     /**
 151      * Removes the old drag-source-listener from drag-source-listener-l
 152      * and returns the resulting multicast listener.
 153      *
 154      * @param l drag-source-listener-l
 155      * @param oldl the drag-source-listener being removed
 156      */
 157     public static DragSourceListener remove(DragSourceListener l,
 158                                             DragSourceListener oldl) {
 159         return (DragSourceListener)removeInternal(l, oldl);
 160     }
 161 
 162     /**
 163      * Removes the old drag-source-motion-listener from
 164      * drag-source-motion-listener-l and returns the resulting multicast
 165      * listener.
 166      *
 167      * @param l drag-source-motion-listener-l
 168      * @param ol the drag-source-motion-listener being removed
 169      */
 170     @SuppressWarnings("overloads")
 171     public static DragSourceMotionListener remove(DragSourceMotionListener l,
 172                                                   DragSourceMotionListener ol) {
 173         return (DragSourceMotionListener)removeInternal(l, ol);
 174     }
 175 
 176     /**
 177      * Returns the resulting multicast listener from adding listener-a
 178      * and listener-b together.
 179      * If listener-a is null, it returns listener-b;
 180      * If listener-b is null, it returns listener-a
 181      * If neither are null, then it creates and returns
 182      * a new AWTEventMulticaster instance which chains a with b.
 183      * @param a event listener-a
 184      * @param b event listener-b
 185      */
 186     protected static EventListener addInternal(EventListener a, EventListener b) {
 187         if (a == null)  return b;
 188         if (b == null)  return a;
 189         return new DnDEventMulticaster(a, b);
 190     }
 191 
 192     /**
 193      * Removes a listener from this multicaster and returns the
 194      * resulting multicast listener.
 195      * @param oldl the listener to be removed
 196      */
 197     protected EventListener remove(EventListener oldl) {
 198         if (oldl == a)  return b;
 199         if (oldl == b)  return a;
 200         EventListener a2 = removeInternal(a, oldl);
 201         EventListener b2 = removeInternal(b, oldl);
 202         if (a2 == a && b2 == b) {
 203             return this;        // it's not here
 204         }
 205         return addInternal(a2, b2);
 206     }
 207 
 208     /**
 209      * Returns the resulting multicast listener after removing the
 210      * old listener from listener-l.
 211      * If listener-l equals the old listener OR listener-l is null,
 212      * returns null.
 213      * Else if listener-l is an instance of AWTEventMulticaster,
 214      * then it removes the old listener from it.
 215      * Else, returns listener l.
 216      * @param l the listener being removed from
 217      * @param oldl the listener being removed
 218      */
 219     protected static EventListener removeInternal(EventListener l, EventListener oldl) {
 220         if (l == oldl || l == null) {
 221             return null;
 222         } else if (l instanceof DnDEventMulticaster) {
 223             return ((DnDEventMulticaster)l).remove(oldl);
 224         } else {
 225             return l;           // it's not here
 226         }
 227     }
 228 
 229     protected static void save(ObjectOutputStream s, String k, EventListener l)
 230       throws IOException {
 231         AWTEventMulticaster.save(s, k, l);
 232     }
 233 }
--- EOF ---