1 /*
2 * Copyright 2001-2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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</code> 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</code> and <code>b</code>
48 * should not be <code>null</code>, though implementations may vary in
49 * choosing whether or not to throw <code>NullPointerException</code>
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</code> by invoking
61 * <code>dragEnter</code> on listener-a and listener-b.
62 *
63 * @param dsde the <code>DragSourceDragEvent</code>
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</code> by invoking
72 * <code>dragOver</code> on listener-a and listener-b.
73 *
74 * @param e the <code>DragSourceDragEvent</code>
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</code> by invoking
83 * <code>dropActionChanged</code> on listener-a and listener-b.
84 *
85 * @param dsde the <code>DragSourceDragEvent</code>
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</code> by invoking
94 * <code>dragExit</code> on listener-a and listener-b.
95 *
96 * @param dse the <code>DragSourceEvent</code>
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</code> by invoking
105 * <code>dragDropEnd</code> on listener-a and listener-b.
106 *
107 * @param dsde the <code>DragSourceDropEvent</code>
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</code> by invoking
116 * <code>dragMouseMoved</code> on listener-a and listener-b.
117 *
118 * @param dsde the <code>DragSourceDragEvent</code>
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 public static DragSourceMotionListener add(DragSourceMotionListener a,
145 DragSourceMotionListener b) {
146 return (DragSourceMotionListener)addInternal(a, b);
147 }
148
149 /**
150 * Removes the old drag-source-listener from drag-source-listener-l
151 * and returns the resulting multicast listener.
152 *
153 * @param l drag-source-listener-l
154 * @param oldl the drag-source-listener being removed
155 */
156 public static DragSourceListener remove(DragSourceListener l,
157 DragSourceListener oldl) {
158 return (DragSourceListener)removeInternal(l, oldl);
159 }
160
161 /**
162 * Removes the old drag-source-motion-listener from
163 * drag-source-motion-listener-l and returns the resulting multicast
164 * listener.
165 *
166 * @param l drag-source-motion-listener-l
167 * @param ol the drag-source-motion-listener being removed
168 */
169 public static DragSourceMotionListener remove(DragSourceMotionListener l,
170 DragSourceMotionListener ol) {
171 return (DragSourceMotionListener)removeInternal(l, ol);
172 }
173
174 /**
175 * Returns the resulting multicast listener from adding listener-a
176 * and listener-b together.
177 * If listener-a is null, it returns listener-b;
178 * If listener-b is null, it returns listener-a
179 * If neither are null, then it creates and returns
180 * a new AWTEventMulticaster instance which chains a with b.
181 * @param a event listener-a
182 * @param b event listener-b
183 */
184 protected static EventListener addInternal(EventListener a, EventListener b) {
185 if (a == null) return b;
186 if (b == null) return a;
187 return new DnDEventMulticaster(a, b);
188 }
189
190 /**
191 * Removes a listener from this multicaster and returns the
192 * resulting multicast listener.
193 * @param oldl the listener to be removed
194 */
195 protected EventListener remove(EventListener oldl) {
196 if (oldl == a) return b;
197 if (oldl == b) return a;
198 EventListener a2 = removeInternal(a, oldl);
199 EventListener b2 = removeInternal(b, oldl);
200 if (a2 == a && b2 == b) {
201 return this; // it's not here
202 }
203 return addInternal(a2, b2);
204 }
205
206 /**
207 * Returns the resulting multicast listener after removing the
208 * old listener from listener-l.
209 * If listener-l equals the old listener OR listener-l is null,
210 * returns null.
211 * Else if listener-l is an instance of AWTEventMulticaster,
212 * then it removes the old listener from it.
213 * Else, returns listener l.
214 * @param l the listener being removed from
215 * @param oldl the listener being removed
216 */
217 protected static EventListener removeInternal(EventListener l, EventListener oldl) {
218 if (l == oldl || l == null) {
219 return null;
220 } else if (l instanceof DnDEventMulticaster) {
221 return ((DnDEventMulticaster)l).remove(oldl);
222 } else {
223 return l; // it's not here
224 }
225 }
226
227 protected static void save(ObjectOutputStream s, String k, EventListener l)
228 throws IOException {
229 AWTEventMulticaster.save(s, k, l);
230 }
231 }