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      */
DnDEventMulticaster(EventListener a, EventListener b)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      */
dragEnter(DragSourceDragEvent dsde)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      */
dragOver(DragSourceDragEvent dsde)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      */
dropActionChanged(DragSourceDragEvent dsde)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      */
dragExit(DragSourceEvent dse)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      */
dragDropEnd(DragSourceDropEvent dsde)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      */
dragMouseMoved(DragSourceDragEvent dsde)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      */
add(DragSourceListener a, DragSourceListener b)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")
add(DragSourceMotionListener a, DragSourceMotionListener b)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      */
remove(DragSourceListener l, DragSourceListener oldl)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")
remove(DragSourceMotionListener l, DragSourceMotionListener ol)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      */
addInternal(EventListener a, EventListener b)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      */
remove(EventListener oldl)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      */
removeInternal(EventListener l, EventListener oldl)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 
save(ObjectOutputStream s, String k, EventListener l)229     protected static void save(ObjectOutputStream s, String k, EventListener l)
230       throws IOException {
231         AWTEventMulticaster.save(s, k, l);
232     }
233 }
234