History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/awt/AWTEventMulticaster.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/awt/AWTEventMulticaster.java+1032−0
@@ -0,0 +1,1032 @@
1+/*
2+ * Copyright (c) 1996, 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+package java.awt;
26+
27+import java.awt.event.*;
28+import java.lang.reflect.Array;
29+import java.util.EventListener;
30+import java.io.Serializable;
31+import java.io.ObjectOutputStream;
32+import java.io.IOException;
33+import java.util.EventListener;
34+
35+
36+/**
37+ * {@code AWTEventMulticaster} implements efficient and thread-safe multi-cast
38+ * event dispatching for the AWT events defined in the {@code java.awt.event}
39+ * package.
40+ * <p>
41+ * The following example illustrates how to use this class:
42+ *
43+ * <pre><code>
44+ * public myComponent extends Component {
45+ * ActionListener actionListener = null;
46+ *
47+ * public synchronized void addActionListener(ActionListener l) {
48+ * actionListener = AWTEventMulticaster.add(actionListener, l);
49+ * }
50+ * public synchronized void removeActionListener(ActionListener l) {
51+ * actionListener = AWTEventMulticaster.remove(actionListener, l);
52+ * }
53+ * public void processEvent(AWTEvent e) {
54+ * // when event occurs which causes "action" semantic
55+ * ActionListener listener = actionListener;
56+ * if (listener != null) {
57+ * listener.actionPerformed(new ActionEvent());
58+ * }
59+ * }
60+ * }
61+ * </code></pre>
62+ * The important point to note is the first argument to the {@code
63+ * add} and {@code remove} methods is the field maintaining the
64+ * listeners. In addition you must assign the result of the {@code add}
65+ * and {@code remove} methods to the field maintaining the listeners.
66+ * <p>
67+ * {@code AWTEventMulticaster} is implemented as a pair of {@code
68+ * EventListeners} that are set at construction time. {@code
69+ * AWTEventMulticaster} is immutable. The {@code add} and {@code
70+ * remove} methods do not alter {@code AWTEventMulticaster} in
71+ * anyway. If necessary, a new {@code AWTEventMulticaster} is
72+ * created. In this way it is safe to add and remove listeners during
73+ * the process of an event dispatching. However, event listeners
74+ * added during the process of an event dispatch operation are not
75+ * notified of the event currently being dispatched.
76+ * <p>
77+ * All of the {@code add} methods allow {@code null} arguments. If the
78+ * first argument is {@code null}, the second argument is returned. If
79+ * the first argument is not {@code null} and the second argument is
80+ * {@code null}, the first argument is returned. If both arguments are
81+ * {@code non-null}, a new {@code AWTEventMulticaster} is created using
82+ * the two arguments and returned.
83+ * <p>
84+ * For the {@code remove} methods that take two arguments, the following is
85+ * returned:
86+ * <ul>
87+ * <li>{@code null}, if the first argument is {@code null}, or
88+ * the arguments are equal, by way of {@code ==}.
89+ * <li>the first argument, if the first argument is not an instance of
90+ * {@code AWTEventMulticaster}.
91+ * <li>result of invoking {@code remove(EventListener)} on the
92+ * first argument, supplying the second argument to the
93+ * {@code remove(EventListener)} method.
94+ * </ul>
95+ * <p>Swing makes use of
96+ * {@link javax.swing.event.EventListenerList EventListenerList} for
97+ * similar logic. Refer to it for details.
98+ *
99+ * @see javax.swing.event.EventListenerList
100+ *
101+ * @author John Rose
102+ * @author Amy Fowler
103+ * @since 1.1
104+ */
105+
106+public class AWTEventMulticaster implements
107+ ComponentListener, ContainerListener, FocusListener, KeyListener,
108+ MouseListener, MouseMotionListener, WindowListener, WindowFocusListener,
109+ WindowStateListener, ActionListener, ItemListener, AdjustmentListener,
110+ TextListener, InputMethodListener, HierarchyListener,
111+ HierarchyBoundsListener, MouseWheelListener {
112+
113+ protected final EventListener a, b;
114+
115+ /**
116+ * Creates an event multicaster instance which chains listener-a
117+ * with listener-b. Input parameters <code>a</code> and <code>b</code>
118+ * should not be <code>null</code>, though implementations may vary in
119+ * choosing whether or not to throw <code>NullPointerException</code>
120+ * in that case.
121+ * @param a listener-a
122+ * @param b listener-b
123+ */
124+ protected AWTEventMulticaster(EventListener a, EventListener b) {
125+ this.a = a; this.b = b;
126+ }
127+
128+ /**
129+ * Removes a listener from this multicaster.
130+ * <p>
131+ * The returned multicaster contains all the listeners in this
132+ * multicaster with the exception of all occurrences of {@code oldl}.
133+ * If the resulting multicaster contains only one regular listener
134+ * the regular listener may be returned. If the resulting multicaster
135+ * is empty, then {@code null} may be returned instead.
136+ * <p>
137+ * No exception is thrown if {@code oldl} is {@code null}.
138+ *
139+ * @param oldl the listener to be removed
140+ * @return resulting listener
141+ */
142+ protected EventListener remove(EventListener oldl) {
143+ if (oldl == a) return b;
144+ if (oldl == b) return a;
145+ EventListener a2 = removeInternal(a, oldl);
146+ EventListener b2 = removeInternal(b, oldl);
147+ if (a2 == a && b2 == b) {
148+ return this; // it's not here
149+ }
150+ return addInternal(a2, b2);
151+ }
152+
153+ /**
154+ * Handles the componentResized event by invoking the
155+ * componentResized methods on listener-a and listener-b.
156+ * @param e the component event
157+ */
158+ public void componentResized(ComponentEvent e) {
159+ ((ComponentListener)a).componentResized(e);
160+ ((ComponentListener)b).componentResized(e);
161+ }
162+
163+ /**
164+ * Handles the componentMoved event by invoking the
165+ * componentMoved methods on listener-a and listener-b.
166+ * @param e the component event
167+ */
168+ public void componentMoved(ComponentEvent e) {
169+ ((ComponentListener)a).componentMoved(e);
170+ ((ComponentListener)b).componentMoved(e);
171+ }
172+
173+ /**
174+ * Handles the componentShown event by invoking the
175+ * componentShown methods on listener-a and listener-b.
176+ * @param e the component event
177+ */
178+ public void componentShown(ComponentEvent e) {
179+ ((ComponentListener)a).componentShown(e);
180+ ((ComponentListener)b).componentShown(e);
181+ }
182+
183+ /**
184+ * Handles the componentHidden event by invoking the
185+ * componentHidden methods on listener-a and listener-b.
186+ * @param e the component event
187+ */
188+ public void componentHidden(ComponentEvent e) {
189+ ((ComponentListener)a).componentHidden(e);
190+ ((ComponentListener)b).componentHidden(e);
191+ }
192+
193+ /**
194+ * Handles the componentAdded container event by invoking the
195+ * componentAdded methods on listener-a and listener-b.
196+ * @param e the component event
197+ */
198+ public void componentAdded(ContainerEvent e) {
199+ ((ContainerListener)a).componentAdded(e);
200+ ((ContainerListener)b).componentAdded(e);
201+ }
202+
203+ /**
204+ * Handles the componentRemoved container event by invoking the
205+ * componentRemoved methods on listener-a and listener-b.
206+ * @param e the component event
207+ */
208+ public void componentRemoved(ContainerEvent e) {
209+ ((ContainerListener)a).componentRemoved(e);
210+ ((ContainerListener)b).componentRemoved(e);
211+ }
212+
213+ /**
214+ * Handles the focusGained event by invoking the
215+ * focusGained methods on listener-a and listener-b.
216+ * @param e the focus event
217+ */
218+ public void focusGained(FocusEvent e) {
219+ ((FocusListener)a).focusGained(e);
220+ ((FocusListener)b).focusGained(e);
221+ }
222+
223+ /**
224+ * Handles the focusLost event by invoking the
225+ * focusLost methods on listener-a and listener-b.
226+ * @param e the focus event
227+ */
228+ public void focusLost(FocusEvent e) {
229+ ((FocusListener)a).focusLost(e);
230+ ((FocusListener)b).focusLost(e);
231+ }
232+
233+ /**
234+ * Handles the keyTyped event by invoking the
235+ * keyTyped methods on listener-a and listener-b.
236+ * @param e the key event
237+ */
238+ public void keyTyped(KeyEvent e) {
239+ ((KeyListener)a).keyTyped(e);
240+ ((KeyListener)b).keyTyped(e);
241+ }
242+
243+ /**
244+ * Handles the keyPressed event by invoking the
245+ * keyPressed methods on listener-a and listener-b.
246+ * @param e the key event
247+ */
248+ public void keyPressed(KeyEvent e) {
249+ ((KeyListener)a).keyPressed(e);
250+ ((KeyListener)b).keyPressed(e);
251+ }
252+
253+ /**
254+ * Handles the keyReleased event by invoking the
255+ * keyReleased methods on listener-a and listener-b.
256+ * @param e the key event
257+ */
258+ public void keyReleased(KeyEvent e) {
259+ ((KeyListener)a).keyReleased(e);
260+ ((KeyListener)b).keyReleased(e);
261+ }
262+
263+ /**
264+ * Handles the mouseClicked event by invoking the
265+ * mouseClicked methods on listener-a and listener-b.
266+ * @param e the mouse event
267+ */
268+ public void mouseClicked(MouseEvent e) {
269+ ((MouseListener)a).mouseClicked(e);
270+ ((MouseListener)b).mouseClicked(e);
271+ }
272+
273+ /**
274+ * Handles the mousePressed event by invoking the
275+ * mousePressed methods on listener-a and listener-b.
276+ * @param e the mouse event
277+ */
278+ public void mousePressed(MouseEvent e) {
279+ ((MouseListener)a).mousePressed(e);
280+ ((MouseListener)b).mousePressed(e);
281+ }
282+
283+ /**
284+ * Handles the mouseReleased event by invoking the
285+ * mouseReleased methods on listener-a and listener-b.
286+ * @param e the mouse event
287+ */
288+ public void mouseReleased(MouseEvent e) {
289+ ((MouseListener)a).mouseReleased(e);
290+ ((MouseListener)b).mouseReleased(e);
291+ }
292+
293+ /**
294+ * Handles the mouseEntered event by invoking the
295+ * mouseEntered methods on listener-a and listener-b.
296+ * @param e the mouse event
297+ */
298+ public void mouseEntered(MouseEvent e) {
299+ ((MouseListener)a).mouseEntered(e);
300+ ((MouseListener)b).mouseEntered(e);
301+ }
302+
303+ /**
304+ * Handles the mouseExited event by invoking the
305+ * mouseExited methods on listener-a and listener-b.
306+ * @param e the mouse event
307+ */
308+ public void mouseExited(MouseEvent e) {
309+ ((MouseListener)a).mouseExited(e);
310+ ((MouseListener)b).mouseExited(e);
311+ }
312+
313+ /**
314+ * Handles the mouseDragged event by invoking the
315+ * mouseDragged methods on listener-a and listener-b.
316+ * @param e the mouse event
317+ */
318+ public void mouseDragged(MouseEvent e) {
319+ ((MouseMotionListener)a).mouseDragged(e);
320+ ((MouseMotionListener)b).mouseDragged(e);
321+ }
322+
323+ /**
324+ * Handles the mouseMoved event by invoking the
325+ * mouseMoved methods on listener-a and listener-b.
326+ * @param e the mouse event
327+ */
328+ public void mouseMoved(MouseEvent e) {
329+ ((MouseMotionListener)a).mouseMoved(e);
330+ ((MouseMotionListener)b).mouseMoved(e);
331+ }
332+
333+ /**
334+ * Handles the windowOpened event by invoking the
335+ * windowOpened methods on listener-a and listener-b.
336+ * @param e the window event
337+ */
338+ public void windowOpened(WindowEvent e) {
339+ ((WindowListener)a).windowOpened(e);
340+ ((WindowListener)b).windowOpened(e);
341+ }
342+
343+ /**
344+ * Handles the windowClosing event by invoking the
345+ * windowClosing methods on listener-a and listener-b.
346+ * @param e the window event
347+ */
348+ public void windowClosing(WindowEvent e) {
349+ ((WindowListener)a).windowClosing(e);
350+ ((WindowListener)b).windowClosing(e);
351+ }
352+
353+ /**
354+ * Handles the windowClosed event by invoking the
355+ * windowClosed methods on listener-a and listener-b.
356+ * @param e the window event
357+ */
358+ public void windowClosed(WindowEvent e) {
359+ ((WindowListener)a).windowClosed(e);
360+ ((WindowListener)b).windowClosed(e);
361+ }
362+
363+ /**
364+ * Handles the windowIconified event by invoking the
365+ * windowIconified methods on listener-a and listener-b.
366+ * @param e the window event
367+ */
368+ public void windowIconified(WindowEvent e) {
369+ ((WindowListener)a).windowIconified(e);
370+ ((WindowListener)b).windowIconified(e);
371+ }
372+
373+ /**
374+ * Handles the windowDeiconfied event by invoking the
375+ * windowDeiconified methods on listener-a and listener-b.
376+ * @param e the window event
377+ */
378+ public void windowDeiconified(WindowEvent e) {
379+ ((WindowListener)a).windowDeiconified(e);
380+ ((WindowListener)b).windowDeiconified(e);
381+ }
382+
383+ /**
384+ * Handles the windowActivated event by invoking the
385+ * windowActivated methods on listener-a and listener-b.
386+ * @param e the window event
387+ */
388+ public void windowActivated(WindowEvent e) {
389+ ((WindowListener)a).windowActivated(e);
390+ ((WindowListener)b).windowActivated(e);
391+ }
392+
393+ /**
394+ * Handles the windowDeactivated event by invoking the
395+ * windowDeactivated methods on listener-a and listener-b.
396+ * @param e the window event
397+ */
398+ public void windowDeactivated(WindowEvent e) {
399+ ((WindowListener)a).windowDeactivated(e);
400+ ((WindowListener)b).windowDeactivated(e);
401+ }
402+
403+ /**
404+ * Handles the windowStateChanged event by invoking the
405+ * windowStateChanged methods on listener-a and listener-b.
406+ * @param e the window event
407+ * @since 1.4
408+ */
409+ public void windowStateChanged(WindowEvent e) {
410+ ((WindowStateListener)a).windowStateChanged(e);
411+ ((WindowStateListener)b).windowStateChanged(e);
412+ }
413+
414+
415+ /**
416+ * Handles the windowGainedFocus event by invoking the windowGainedFocus
417+ * methods on listener-a and listener-b.
418+ * @param e the window event
419+ * @since 1.4
420+ */
421+ public void windowGainedFocus(WindowEvent e) {
422+ ((WindowFocusListener)a).windowGainedFocus(e);
423+ ((WindowFocusListener)b).windowGainedFocus(e);
424+ }
425+
426+ /**
427+ * Handles the windowLostFocus event by invoking the windowLostFocus
428+ * methods on listener-a and listener-b.
429+ * @param e the window event
430+ * @since 1.4
431+ */
432+ public void windowLostFocus(WindowEvent e) {
433+ ((WindowFocusListener)a).windowLostFocus(e);
434+ ((WindowFocusListener)b).windowLostFocus(e);
435+ }
436+
437+ /**
438+ * Handles the actionPerformed event by invoking the
439+ * actionPerformed methods on listener-a and listener-b.
440+ * @param e the action event
441+ */
442+ public void actionPerformed(ActionEvent e) {
443+ ((ActionListener)a).actionPerformed(e);
444+ ((ActionListener)b).actionPerformed(e);
445+ }
446+
447+ /**
448+ * Handles the itemStateChanged event by invoking the
449+ * itemStateChanged methods on listener-a and listener-b.
450+ * @param e the item event
451+ */
452+ public void itemStateChanged(ItemEvent e) {
453+ ((ItemListener)a).itemStateChanged(e);
454+ ((ItemListener)b).itemStateChanged(e);
455+ }
456+
457+ /**
458+ * Handles the adjustmentValueChanged event by invoking the
459+ * adjustmentValueChanged methods on listener-a and listener-b.
460+ * @param e the adjustment event
461+ */
462+ public void adjustmentValueChanged(AdjustmentEvent e) {
463+ ((AdjustmentListener)a).adjustmentValueChanged(e);
464+ ((AdjustmentListener)b).adjustmentValueChanged(e);
465+ }
466+ public void textValueChanged(TextEvent e) {
467+ ((TextListener)a).textValueChanged(e);
468+ ((TextListener)b).textValueChanged(e);
469+ }
470+
471+ /**
472+ * Handles the inputMethodTextChanged event by invoking the
473+ * inputMethodTextChanged methods on listener-a and listener-b.
474+ * @param e the item event
475+ */
476+ public void inputMethodTextChanged(InputMethodEvent e) {
477+ ((InputMethodListener)a).inputMethodTextChanged(e);
478+ ((InputMethodListener)b).inputMethodTextChanged(e);
479+ }
480+
481+ /**
482+ * Handles the caretPositionChanged event by invoking the
483+ * caretPositionChanged methods on listener-a and listener-b.
484+ * @param e the item event
485+ */
486+ public void caretPositionChanged(InputMethodEvent e) {
487+ ((InputMethodListener)a).caretPositionChanged(e);
488+ ((InputMethodListener)b).caretPositionChanged(e);
489+ }
490+
491+ /**
492+ * Handles the hierarchyChanged event by invoking the
493+ * hierarchyChanged methods on listener-a and listener-b.
494+ * @param e the item event
495+ * @since 1.3
496+ */
497+ public void hierarchyChanged(HierarchyEvent e) {
498+ ((HierarchyListener)a).hierarchyChanged(e);
499+ ((HierarchyListener)b).hierarchyChanged(e);
500+ }
501+
502+ /**
503+ * Handles the ancestorMoved event by invoking the
504+ * ancestorMoved methods on listener-a and listener-b.
505+ * @param e the item event
506+ * @since 1.3
507+ */
508+ public void ancestorMoved(HierarchyEvent e) {
509+ ((HierarchyBoundsListener)a).ancestorMoved(e);
510+ ((HierarchyBoundsListener)b).ancestorMoved(e);
511+ }
512+
513+ /**
514+ * Handles the ancestorResized event by invoking the
515+ * ancestorResized methods on listener-a and listener-b.
516+ * @param e the item event
517+ * @since 1.3
518+ */
519+ public void ancestorResized(HierarchyEvent e) {
520+ ((HierarchyBoundsListener)a).ancestorResized(e);
521+ ((HierarchyBoundsListener)b).ancestorResized(e);
522+ }
523+
524+ /**
525+ * Handles the mouseWheelMoved event by invoking the
526+ * mouseWheelMoved methods on listener-a and listener-b.
527+ * @param e the mouse event
528+ * @since 1.4
529+ */
530+ public void mouseWheelMoved(MouseWheelEvent e) {
531+ ((MouseWheelListener)a).mouseWheelMoved(e);
532+ ((MouseWheelListener)b).mouseWheelMoved(e);
533+ }
534+
535+ /**
536+ * Adds component-listener-a with component-listener-b and
537+ * returns the resulting multicast listener.
538+ * @param a component-listener-a
539+ * @param b component-listener-b
540+ */
541+ public static ComponentListener add(ComponentListener a, ComponentListener b) {
542+ return (ComponentListener)addInternal(a, b);
543+ }
544+
545+ /**
546+ * Adds container-listener-a with container-listener-b and
547+ * returns the resulting multicast listener.
548+ * @param a container-listener-a
549+ * @param b container-listener-b
550+ */
551+ public static ContainerListener add(ContainerListener a, ContainerListener b) {
552+ return (ContainerListener)addInternal(a, b);
553+ }
554+
555+ /**
556+ * Adds focus-listener-a with focus-listener-b and
557+ * returns the resulting multicast listener.
558+ * @param a focus-listener-a
559+ * @param b focus-listener-b
560+ */
561+ public static FocusListener add(FocusListener a, FocusListener b) {
562+ return (FocusListener)addInternal(a, b);
563+ }
564+
565+ /**
566+ * Adds key-listener-a with key-listener-b and
567+ * returns the resulting multicast listener.
568+ * @param a key-listener-a
569+ * @param b key-listener-b
570+ */
571+ public static KeyListener add(KeyListener a, KeyListener b) {
572+ return (KeyListener)addInternal(a, b);
573+ }
574+
575+ /**
576+ * Adds mouse-listener-a with mouse-listener-b and
577+ * returns the resulting multicast listener.
578+ * @param a mouse-listener-a
579+ * @param b mouse-listener-b
580+ */
581+ public static MouseListener add(MouseListener a, MouseListener b) {
582+ return (MouseListener)addInternal(a, b);
583+ }
584+
585+ /**
586+ * Adds mouse-motion-listener-a with mouse-motion-listener-b and
587+ * returns the resulting multicast listener.
588+ * @param a mouse-motion-listener-a
589+ * @param b mouse-motion-listener-b
590+ */
591+ public static MouseMotionListener add(MouseMotionListener a, MouseMotionListener b) {
592+ return (MouseMotionListener)addInternal(a, b);
593+ }
594+
595+ /**
596+ * Adds window-listener-a with window-listener-b and
597+ * returns the resulting multicast listener.
598+ * @param a window-listener-a
599+ * @param b window-listener-b
600+ */
601+ public static WindowListener add(WindowListener a, WindowListener b) {
602+ return (WindowListener)addInternal(a, b);
603+ }
604+
605+ /**
606+ * Adds window-state-listener-a with window-state-listener-b
607+ * and returns the resulting multicast listener.
608+ * @param a window-state-listener-a
609+ * @param b window-state-listener-b
610+ * @since 1.4
611+ */
612+ public static WindowStateListener add(WindowStateListener a,
613+ WindowStateListener b) {
614+ return (WindowStateListener)addInternal(a, b);
615+ }
616+
617+ /**
618+ * Adds window-focus-listener-a with window-focus-listener-b
619+ * and returns the resulting multicast listener.
620+ * @param a window-focus-listener-a
621+ * @param b window-focus-listener-b
622+ * @since 1.4
623+ */
624+ public static WindowFocusListener add(WindowFocusListener a,
625+ WindowFocusListener b) {
626+ return (WindowFocusListener)addInternal(a, b);
627+ }
628+
629+ /**
630+ * Adds action-listener-a with action-listener-b and
631+ * returns the resulting multicast listener.
632+ * @param a action-listener-a
633+ * @param b action-listener-b
634+ */
635+ public static ActionListener add(ActionListener a, ActionListener b) {
636+ return (ActionListener)addInternal(a, b);
637+ }
638+
639+ /**
640+ * Adds item-listener-a with item-listener-b and
641+ * returns the resulting multicast listener.
642+ * @param a item-listener-a
643+ * @param b item-listener-b
644+ */
645+ public static ItemListener add(ItemListener a, ItemListener b) {
646+ return (ItemListener)addInternal(a, b);
647+ }
648+
649+ /**
650+ * Adds adjustment-listener-a with adjustment-listener-b and
651+ * returns the resulting multicast listener.
652+ * @param a adjustment-listener-a
653+ * @param b adjustment-listener-b
654+ */
655+ public static AdjustmentListener add(AdjustmentListener a, AdjustmentListener b) {
656+ return (AdjustmentListener)addInternal(a, b);
657+ }
658+ public static TextListener add(TextListener a, TextListener b) {
659+ return (TextListener)addInternal(a, b);
660+ }
661+
662+ /**
663+ * Adds input-method-listener-a with input-method-listener-b and
664+ * returns the resulting multicast listener.
665+ * @param a input-method-listener-a
666+ * @param b input-method-listener-b
667+ */
668+ public static InputMethodListener add(InputMethodListener a, InputMethodListener b) {
669+ return (InputMethodListener)addInternal(a, b);
670+ }
671+
672+ /**
673+ * Adds hierarchy-listener-a with hierarchy-listener-b and
674+ * returns the resulting multicast listener.
675+ * @param a hierarchy-listener-a
676+ * @param b hierarchy-listener-b
677+ * @since 1.3
678+ */
679+ public static HierarchyListener add(HierarchyListener a, HierarchyListener b) {
680+ return (HierarchyListener)addInternal(a, b);
681+ }
682+
683+ /**
684+ * Adds hierarchy-bounds-listener-a with hierarchy-bounds-listener-b and
685+ * returns the resulting multicast listener.
686+ * @param a hierarchy-bounds-listener-a
687+ * @param b hierarchy-bounds-listener-b
688+ * @since 1.3
689+ */
690+ public static HierarchyBoundsListener add(HierarchyBoundsListener a, HierarchyBoundsListener b) {
691+ return (HierarchyBoundsListener)addInternal(a, b);
692+ }
693+
694+ /**
695+ * Adds mouse-wheel-listener-a with mouse-wheel-listener-b and
696+ * returns the resulting multicast listener.
697+ * @param a mouse-wheel-listener-a
698+ * @param b mouse-wheel-listener-b
699+ * @since 1.4
700+ */
701+ public static MouseWheelListener add(MouseWheelListener a,
702+ MouseWheelListener b) {
703+ return (MouseWheelListener)addInternal(a, b);
704+ }
705+
706+ /**
707+ * Removes the old component-listener from component-listener-l and
708+ * returns the resulting multicast listener.
709+ * @param l component-listener-l
710+ * @param oldl the component-listener being removed
711+ */
712+ public static ComponentListener remove(ComponentListener l, ComponentListener oldl) {
713+ return (ComponentListener) removeInternal(l, oldl);
714+ }
715+
716+ /**
717+ * Removes the old container-listener from container-listener-l and
718+ * returns the resulting multicast listener.
719+ * @param l container-listener-l
720+ * @param oldl the container-listener being removed
721+ */
722+ public static ContainerListener remove(ContainerListener l, ContainerListener oldl) {
723+ return (ContainerListener) removeInternal(l, oldl);
724+ }
725+
726+ /**
727+ * Removes the old focus-listener from focus-listener-l and
728+ * returns the resulting multicast listener.
729+ * @param l focus-listener-l
730+ * @param oldl the focus-listener being removed
731+ */
732+ public static FocusListener remove(FocusListener l, FocusListener oldl) {
733+ return (FocusListener) removeInternal(l, oldl);
734+ }
735+
736+ /**
737+ * Removes the old key-listener from key-listener-l and
738+ * returns the resulting multicast listener.
739+ * @param l key-listener-l
740+ * @param oldl the key-listener being removed
741+ */
742+ public static KeyListener remove(KeyListener l, KeyListener oldl) {
743+ return (KeyListener) removeInternal(l, oldl);
744+ }
745+
746+ /**
747+ * Removes the old mouse-listener from mouse-listener-l and
748+ * returns the resulting multicast listener.
749+ * @param l mouse-listener-l
750+ * @param oldl the mouse-listener being removed
751+ */
752+ public static MouseListener remove(MouseListener l, MouseListener oldl) {
753+ return (MouseListener) removeInternal(l, oldl);
754+ }
755+
756+ /**
757+ * Removes the old mouse-motion-listener from mouse-motion-listener-l
758+ * and returns the resulting multicast listener.
759+ * @param l mouse-motion-listener-l
760+ * @param oldl the mouse-motion-listener being removed
761+ */
762+ public static MouseMotionListener remove(MouseMotionListener l, MouseMotionListener oldl) {
763+ return (MouseMotionListener) removeInternal(l, oldl);
764+ }
765+
766+ /**
767+ * Removes the old window-listener from window-listener-l and
768+ * returns the resulting multicast listener.
769+ * @param l window-listener-l
770+ * @param oldl the window-listener being removed
771+ */
772+ public static WindowListener remove(WindowListener l, WindowListener oldl) {
773+ return (WindowListener) removeInternal(l, oldl);
774+ }
775+
776+ /**
777+ * Removes the old window-state-listener from window-state-listener-l
778+ * and returns the resulting multicast listener.
779+ * @param l window-state-listener-l
780+ * @param oldl the window-state-listener being removed
781+ * @since 1.4
782+ */
783+ public static WindowStateListener remove(WindowStateListener l,
784+ WindowStateListener oldl) {
785+ return (WindowStateListener) removeInternal(l, oldl);
786+ }
787+
788+ /**
789+ * Removes the old window-focus-listener from window-focus-listener-l
790+ * and returns the resulting multicast listener.
791+ * @param l window-focus-listener-l
792+ * @param oldl the window-focus-listener being removed
793+ * @since 1.4
794+ */
795+ public static WindowFocusListener remove(WindowFocusListener l,
796+ WindowFocusListener oldl) {
797+ return (WindowFocusListener) removeInternal(l, oldl);
798+ }
799+
800+ /**
801+ * Removes the old action-listener from action-listener-l and
802+ * returns the resulting multicast listener.
803+ * @param l action-listener-l
804+ * @param oldl the action-listener being removed
805+ */
806+ public static ActionListener remove(ActionListener l, ActionListener oldl) {
807+ return (ActionListener) removeInternal(l, oldl);
808+ }
809+
810+ /**
811+ * Removes the old item-listener from item-listener-l and
812+ * returns the resulting multicast listener.
813+ * @param l item-listener-l
814+ * @param oldl the item-listener being removed
815+ */
816+ public static ItemListener remove(ItemListener l, ItemListener oldl) {
817+ return (ItemListener) removeInternal(l, oldl);
818+ }
819+
820+ /**
821+ * Removes the old adjustment-listener from adjustment-listener-l and
822+ * returns the resulting multicast listener.
823+ * @param l adjustment-listener-l
824+ * @param oldl the adjustment-listener being removed
825+ */
826+ public static AdjustmentListener remove(AdjustmentListener l, AdjustmentListener oldl) {
827+ return (AdjustmentListener) removeInternal(l, oldl);
828+ }
829+ public static TextListener remove(TextListener l, TextListener oldl) {
830+ return (TextListener) removeInternal(l, oldl);
831+ }
832+
833+ /**
834+ * Removes the old input-method-listener from input-method-listener-l and
835+ * returns the resulting multicast listener.
836+ * @param l input-method-listener-l
837+ * @param oldl the input-method-listener being removed
838+ */
839+ public static InputMethodListener remove(InputMethodListener l, InputMethodListener oldl) {
840+ return (InputMethodListener) removeInternal(l, oldl);
841+ }
842+
843+ /**
844+ * Removes the old hierarchy-listener from hierarchy-listener-l and
845+ * returns the resulting multicast listener.
846+ * @param l hierarchy-listener-l
847+ * @param oldl the hierarchy-listener being removed
848+ * @since 1.3
849+ */
850+ public static HierarchyListener remove(HierarchyListener l, HierarchyListener oldl) {
851+ return (HierarchyListener) removeInternal(l, oldl);
852+ }
853+
854+ /**
855+ * Removes the old hierarchy-bounds-listener from
856+ * hierarchy-bounds-listener-l and returns the resulting multicast
857+ * listener.
858+ * @param l hierarchy-bounds-listener-l
859+ * @param oldl the hierarchy-bounds-listener being removed
860+ * @since 1.3
861+ */
862+ public static HierarchyBoundsListener remove(HierarchyBoundsListener l, HierarchyBoundsListener oldl) {
863+ return (HierarchyBoundsListener) removeInternal(l, oldl);
864+ }
865+
866+ /**
867+ * Removes the old mouse-wheel-listener from mouse-wheel-listener-l
868+ * and returns the resulting multicast listener.
869+ * @param l mouse-wheel-listener-l
870+ * @param oldl the mouse-wheel-listener being removed
871+ * @since 1.4
872+ */
873+ public static MouseWheelListener remove(MouseWheelListener l,
874+ MouseWheelListener oldl) {
875+ return (MouseWheelListener) removeInternal(l, oldl);
876+ }
877+
878+ /**
879+ * Returns the resulting multicast listener from adding listener-a
880+ * and listener-b together.
881+ * If listener-a is null, it returns listener-b;
882+ * If listener-b is null, it returns listener-a
883+ * If neither are null, then it creates and returns
884+ * a new AWTEventMulticaster instance which chains a with b.
885+ * @param a event listener-a
886+ * @param b event listener-b
887+ */
888+ protected static EventListener addInternal(EventListener a, EventListener b) {
889+ if (a == null) return b;
890+ if (b == null) return a;
891+ return new AWTEventMulticaster(a, b);
892+ }
893+
894+ /**
895+ * Returns the resulting multicast listener after removing the
896+ * old listener from listener-l.
897+ * If listener-l equals the old listener OR listener-l is null,
898+ * returns null.
899+ * Else if listener-l is an instance of AWTEventMulticaster,
900+ * then it removes the old listener from it.
901+ * Else, returns listener l.
902+ * @param l the listener being removed from
903+ * @param oldl the listener being removed
904+ */
905+ protected static EventListener removeInternal(EventListener l, EventListener oldl) {
906+ if (l == oldl || l == null) {
907+ return null;
908+ } else if (l instanceof AWTEventMulticaster) {
909+ return ((AWTEventMulticaster)l).remove(oldl);
910+ } else {
911+ return l; // it's not here
912+ }
913+ }
914+
915+
916+ /* Serialization support.
917+ */
918+
919+ protected void saveInternal(ObjectOutputStream s, String k) throws IOException {
920+ if (a instanceof AWTEventMulticaster) {
921+ ((AWTEventMulticaster)a).saveInternal(s, k);
922+ }
923+ else if (a instanceof Serializable) {
924+ s.writeObject(k);
925+ s.writeObject(a);
926+ }
927+
928+ if (b instanceof AWTEventMulticaster) {
929+ ((AWTEventMulticaster)b).saveInternal(s, k);
930+ }
931+ else if (b instanceof Serializable) {
932+ s.writeObject(k);
933+ s.writeObject(b);
934+ }
935+ }
936+
937+ protected static void save(ObjectOutputStream s, String k, EventListener l) throws IOException {
938+ if (l == null) {
939+ return;
940+ }
941+ else if (l instanceof AWTEventMulticaster) {
942+ ((AWTEventMulticaster)l).saveInternal(s, k);
943+ }
944+ else if (l instanceof Serializable) {
945+ s.writeObject(k);
946+ s.writeObject(l);
947+ }
948+ }
949+
950+ /*
951+ * Recursive method which returns a count of the number of listeners in
952+ * EventListener, handling the (common) case of l actually being an
953+ * AWTEventMulticaster. Additionally, only listeners of type listenerType
954+ * are counted. Method modified to fix bug 4513402. -bchristi
955+ */
956+ private static int getListenerCount(EventListener l, Class listenerType) {
957+ if (l instanceof AWTEventMulticaster) {
958+ AWTEventMulticaster mc = (AWTEventMulticaster)l;
959+ return getListenerCount(mc.a, listenerType) +
960+ getListenerCount(mc.b, listenerType);
961+ }
962+ else {
963+ // Only count listeners of correct type
964+ return listenerType.isInstance(l) ? 1 : 0;
965+ }
966+ }
967+
968+ /*
969+ * Recusive method which populates EventListener array a with EventListeners
970+ * from l. l is usually an AWTEventMulticaster. Bug 4513402 revealed that
971+ * if l differed in type from the element type of a, an ArrayStoreException
972+ * would occur. Now l is only inserted into a if it's of the appropriate
973+ * type. -bchristi
974+ */
975+ private static int populateListenerArray(EventListener[] a, EventListener l, int index) {
976+ if (l instanceof AWTEventMulticaster) {
977+ AWTEventMulticaster mc = (AWTEventMulticaster)l;
978+ int lhs = populateListenerArray(a, mc.a, index);
979+ return populateListenerArray(a, mc.b, lhs);
980+ }
981+ else if (a.getClass().getComponentType().isInstance(l)) {
982+ a[index] = l;
983+ return index + 1;
984+ }
985+ // Skip nulls, instances of wrong class
986+ else {
987+ return index;
988+ }
989+ }
990+
991+ /**
992+ * Returns an array of all the objects chained as
993+ * <code><em>Foo</em>Listener</code>s by the specified
994+ * <code>java.util.EventListener</code>.
995+ * <code><em>Foo</em>Listener</code>s are chained by the
996+ * <code>AWTEventMulticaster</code> using the
997+ * <code>add<em>Foo</em>Listener</code> method.
998+ * If a <code>null</code> listener is specified, this method returns an
999+ * empty array. If the specified listener is not an instance of
1000+ * <code>AWTEventMulticaster</code>, this method returns an array which
1001+ * contains only the specified listener. If no such listeners are chanined,
1002+ * this method returns an empty array.
1003+ *
1004+ * @param l the specified <code>java.util.EventListener</code>
1005+ * @param listenerType the type of listeners requested; this parameter
1006+ * should specify an interface that descends from
1007+ * <code>java.util.EventListener</code>
1008+ * @return an array of all objects chained as
1009+ * <code><em>Foo</em>Listener</code>s by the specified multicast
1010+ * listener, or an empty array if no such listeners have been
1011+ * chained by the specified multicast listener
1012+ * @exception NullPointerException if the specified
1013+ * {@code listenertype} parameter is {@code null}
1014+ * @exception ClassCastException if <code>listenerType</code>
1015+ * doesn't specify a class or interface that implements
1016+ * <code>java.util.EventListener</code>
1017+ *
1018+ * @since 1.4
1019+ */
1020+ public static <T extends EventListener> T[]
1021+ getListeners(EventListener l, Class<T> listenerType)
1022+ {
1023+ if (listenerType == null) {
1024+ throw new NullPointerException ("Listener type should not be null");
1025+ }
1026+
1027+ int n = getListenerCount(l, listenerType);
1028+ T[] result = (T[])Array.newInstance(listenerType, n);
1029+ populateListenerArray(result, l, 0);
1030+ return result;
1031+ }
1032+}