001: /*
002: * @(#)AWTEventMulticaster.java 1.19 03/11/25
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027: package java.awt;
028:
029: import java.awt.event.*;
030: import java.util.EventListener;
031: import java.io.Serializable;
032: import java.io.ObjectOutputStream;
033: import java.io.IOException;
034: import java.lang.reflect.Array;
035:
036: /**
037: * A class which implements efficient and thread-safe multi-cast event
038: * dispatching for the AWT events defined in the java.awt.event package.
039: * This class will manage an immutable structure consisting of a chain of
040: * event listeners and will dispatch events to those listeners. Because
041: * the structure is immutable, it is safe to use this API to add/remove
042: * listeners during the process of an event dispatch operation.
043: *
044: * An example of how this class could be used to implement a new
045: * component which fires "action" events:
046: *
047: * <pre><code>
048: * public myComponent extends Component {
049: * ActionListener actionListener = null;
050: *
051: * public void addActionListener(ActionListener l) {
052: * actionListener = AWTEventMulticaster.add(actionListener, l);
053: * }
054: * public void removeActionListener(ActionListener l) {
055: * actionListener = AWTEventMulticaster.remove(actionListener, l);
056: * }
057: * public void processEvent(AWTEvent e) {
058: * // when event occurs which causes "action" semantic
059: * if (actionListener != null) {
060: * actionListener.actionPerformed(new ActionEvent());
061: * }
062: * }
063: * </code></pre>
064: *
065: * @version 1.17, 08/19/02
066: * @author John Rose
067: * @author Amy Fowler
068: */
069:
070: public class AWTEventMulticaster implements ComponentListener,
071: ContainerListener, FocusListener, KeyListener, MouseListener,
072: MouseMotionListener, WindowListener, WindowFocusListener,
073: ActionListener, ItemListener, AdjustmentListener,
074: InputMethodListener, TextListener, MouseWheelListener {
075: protected final EventListener a, b;
076:
077: /**
078: * Creates an event multicaster instance which chains listener-a
079: * with listener-b.
080: * @param a listener-a
081: * @param b listener-b
082: */
083: protected AWTEventMulticaster(EventListener a, EventListener b) {
084: this .a = a;
085: this .b = b;
086: }
087:
088: /**
089: * Removes a listener from this multicaster and returns the
090: * resulting multicast listener.
091: * @param oldl the listener to be removed
092: */
093: protected EventListener remove(EventListener oldl) {
094: if (oldl == a)
095: return b;
096: if (oldl == b)
097: return a;
098: EventListener a2 = removeInternal(a, oldl);
099: EventListener b2 = removeInternal(b, oldl);
100: if (a2 == a && b2 == b) {
101: return this ; // it's not here
102: }
103: return addInternal(a2, b2);
104: }
105:
106: /**
107: * Handles the componentResized event by invoking the
108: * componentResized methods on listener-a and listener-b.
109: * @param e the component event
110: */
111: public void componentResized(ComponentEvent e) {
112: ((ComponentListener) a).componentResized(e);
113: ((ComponentListener) b).componentResized(e);
114: }
115:
116: /**
117: * Handles the componentMoved event by invoking the
118: * componentMoved methods on listener-a and listener-b.
119: * @param e the component event
120: */
121: public void componentMoved(ComponentEvent e) {
122: ((ComponentListener) a).componentMoved(e);
123: ((ComponentListener) b).componentMoved(e);
124: }
125:
126: /**
127: * Handles the componentShown event by invoking the
128: * componentShown methods on listener-a and listener-b.
129: * @param e the component event
130: */
131: public void componentShown(ComponentEvent e) {
132: ((ComponentListener) a).componentShown(e);
133: ((ComponentListener) b).componentShown(e);
134: }
135:
136: /**
137: * Handles the componentHidden event by invoking the
138: * componentHidden methods on listener-a and listener-b.
139: * @param e the component event
140: */
141: public void componentHidden(ComponentEvent e) {
142: ((ComponentListener) a).componentHidden(e);
143: ((ComponentListener) b).componentHidden(e);
144: }
145:
146: /**
147: * Handles the componentAdded container event by invoking the
148: * componentAdded methods on listener-a and listener-b.
149: * @param e the component event
150: */
151: public void componentAdded(ContainerEvent e) {
152: ((ContainerListener) a).componentAdded(e);
153: ((ContainerListener) b).componentAdded(e);
154: }
155:
156: /**
157: * Handles the componentRemoved container event by invoking the
158: * componentRemoved methods on listener-a and listener-b.
159: * @param e the component event
160: */
161: public void componentRemoved(ContainerEvent e) {
162: ((ContainerListener) a).componentRemoved(e);
163: ((ContainerListener) b).componentRemoved(e);
164: }
165:
166: /**
167: * Handles the focusGained event by invoking the
168: * focusGained methods on listener-a and listener-b.
169: * @param e the focus event
170: */
171: public void focusGained(FocusEvent e) {
172: ((FocusListener) a).focusGained(e);
173: ((FocusListener) b).focusGained(e);
174: }
175:
176: /**
177: * Handles the focusLost event by invoking the
178: * focusLost methods on listener-a and listener-b.
179: * @param e the focus event
180: */
181: public void focusLost(FocusEvent e) {
182: ((FocusListener) a).focusLost(e);
183: ((FocusListener) b).focusLost(e);
184: }
185:
186: /**
187: * Handles the keyTyped event by invoking the
188: * keyTyped methods on listener-a and listener-b.
189: * @param e the key event
190: */
191: public void keyTyped(KeyEvent e) {
192: ((KeyListener) a).keyTyped(e);
193: ((KeyListener) b).keyTyped(e);
194: }
195:
196: /**
197: * Handles the keyPressed event by invoking the
198: * keyPressed methods on listener-a and listener-b.
199: * @param e the key event
200: */
201: public void keyPressed(KeyEvent e) {
202: ((KeyListener) a).keyPressed(e);
203: ((KeyListener) b).keyPressed(e);
204: }
205:
206: /**
207: * Handles the keyReleased event by invoking the
208: * keyReleased methods on listener-a and listener-b.
209: * @param e the key event
210: */
211: public void keyReleased(KeyEvent e) {
212: ((KeyListener) a).keyReleased(e);
213: ((KeyListener) b).keyReleased(e);
214: }
215:
216: /**
217: * Handles the mouseClicked event by invoking the
218: * mouseClicked methods on listener-a and listener-b.
219: * @param e the mouse event
220: */
221: public void mouseClicked(MouseEvent e) {
222: ((MouseListener) a).mouseClicked(e);
223: ((MouseListener) b).mouseClicked(e);
224: }
225:
226: /**
227: * Handles the mousePressed event by invoking the
228: * mousePressed methods on listener-a and listener-b.
229: * @param e the mouse event
230: */
231: public void mousePressed(MouseEvent e) {
232: ((MouseListener) a).mousePressed(e);
233: ((MouseListener) b).mousePressed(e);
234: }
235:
236: /**
237: * Handles the mouseReleased event by invoking the
238: * mouseReleased methods on listener-a and listener-b.
239: * @param e the mouse event
240: */
241: public void mouseReleased(MouseEvent e) {
242: ((MouseListener) a).mouseReleased(e);
243: ((MouseListener) b).mouseReleased(e);
244: }
245:
246: /**
247: * Handles the mouseEntered event by invoking the
248: * mouseEntered methods on listener-a and listener-b.
249: * @param e the mouse event
250: */
251: public void mouseEntered(MouseEvent e) {
252: ((MouseListener) a).mouseEntered(e);
253: ((MouseListener) b).mouseEntered(e);
254: }
255:
256: /**
257: * Handles the mouseExited event by invoking the
258: * mouseExited methods on listener-a and listener-b.
259: * @param e the mouse event
260: */
261: public void mouseExited(MouseEvent e) {
262: ((MouseListener) a).mouseExited(e);
263: ((MouseListener) b).mouseExited(e);
264: }
265:
266: /**
267: * Handles the mouseDragged event by invoking the
268: * mouseDragged methods on listener-a and listener-b.
269: * @param e the mouse event
270: */
271: public void mouseDragged(MouseEvent e) {
272: ((MouseMotionListener) a).mouseDragged(e);
273: ((MouseMotionListener) b).mouseDragged(e);
274: }
275:
276: /**
277: * Handles the mouseMoved event by invoking the
278: * mouseMoved methods on listener-a and listener-b.
279: * @param e the mouse event
280: */
281: public void mouseMoved(MouseEvent e) {
282: ((MouseMotionListener) a).mouseMoved(e);
283: ((MouseMotionListener) b).mouseMoved(e);
284: }
285:
286: /**
287: * Handles the windowOpened event by invoking the
288: * windowOpened methods on listener-a and listener-b.
289: * @param e the window event
290: */
291: public void windowOpened(WindowEvent e) {
292: ((WindowListener) a).windowOpened(e);
293: ((WindowListener) b).windowOpened(e);
294: }
295:
296: /**
297: * Handles the windowClosing event by invoking the
298: * windowClosing methods on listener-a and listener-b.
299: * @param e the window event
300: */
301: public void windowClosing(WindowEvent e) {
302: ((WindowListener) a).windowClosing(e);
303: ((WindowListener) b).windowClosing(e);
304: }
305:
306: /**
307: * Handles the windowClosed event by invoking the
308: * windowClosed methods on listener-a and listener-b.
309: * @param e the window event
310: */
311: public void windowClosed(WindowEvent e) {
312: ((WindowListener) a).windowClosed(e);
313: ((WindowListener) b).windowClosed(e);
314: }
315:
316: /**
317: * Handles the windowIconified event by invoking the
318: * windowIconified methods on listener-a and listener-b.
319: * @param e the window event
320: */
321: public void windowIconified(WindowEvent e) {
322: ((WindowListener) a).windowIconified(e);
323: ((WindowListener) b).windowIconified(e);
324: }
325:
326: /**
327: * Handles the windowDeiconfied event by invoking the
328: * windowDeiconified methods on listener-a and listener-b.
329: * @param e the window event
330: */
331: public void windowDeiconified(WindowEvent e) {
332: ((WindowListener) a).windowDeiconified(e);
333: ((WindowListener) b).windowDeiconified(e);
334: }
335:
336: /**
337: * Handles the windowActivated event by invoking the
338: * windowActivated methods on listener-a and listener-b.
339: * @param e the window event
340: */
341: public void windowActivated(WindowEvent e) {
342: ((WindowListener) a).windowActivated(e);
343: ((WindowListener) b).windowActivated(e);
344: }
345:
346: /**
347: * Handles the windowDeactivated event by invoking the
348: * windowDeactivated methods on listener-a and listener-b.
349: * @param e the window event
350: */
351: public void windowDeactivated(WindowEvent e) {
352: ((WindowListener) a).windowDeactivated(e);
353: ((WindowListener) b).windowDeactivated(e);
354: }
355:
356: /**
357: * Handles the windowGainedFocus event by invoking the windowGainedFocus
358: * methods on listener-a and listener-b.
359: * @param e the window event
360: */
361: public void windowGainedFocus(WindowEvent e) {
362: ((WindowFocusListener) a).windowGainedFocus(e);
363: ((WindowFocusListener) b).windowGainedFocus(e);
364: }
365:
366: /**
367: * Handles the windowLostFocus event by invoking the windowLostFocus
368: * methods on listener-a and listener-b.
369: * @param e the window event
370: */
371: public void windowLostFocus(WindowEvent e) {
372: ((WindowFocusListener) a).windowLostFocus(e);
373: ((WindowFocusListener) b).windowLostFocus(e);
374: }
375:
376: /**
377: * Handles the actionPerformed event by invoking the
378: * actionPerformed methods on listener-a and listener-b.
379: * @param e the action event
380: */
381: public void actionPerformed(ActionEvent e) {
382: ((ActionListener) a).actionPerformed(e);
383: ((ActionListener) b).actionPerformed(e);
384: }
385:
386: /**
387: * Handles the itemStateChanged event by invoking the
388: * itemStateChanged methods on listener-a and listener-b.
389: * @param e the item event
390: */
391: public void itemStateChanged(ItemEvent e) {
392: ((ItemListener) a).itemStateChanged(e);
393: ((ItemListener) b).itemStateChanged(e);
394: }
395:
396: /**
397: * Handles the adjustmentValueChanged event by invoking the
398: * adjustmentValueChanged methods on listener-a and listener-b.
399: * @param e the adjustment event
400: */
401: public void adjustmentValueChanged(AdjustmentEvent e) {
402: ((AdjustmentListener) a).adjustmentValueChanged(e);
403: ((AdjustmentListener) b).adjustmentValueChanged(e);
404: }
405:
406: public void textValueChanged(TextEvent e) {
407: ((TextListener) a).textValueChanged(e);
408: ((TextListener) b).textValueChanged(e);
409: }
410:
411: /**
412: * Handles the inputMethodTextChanged event by invoking the
413: * inputMethodTextChanged methods on listener-a and listener-b.
414: * @param e the item event
415: */
416: public void inputMethodTextChanged(InputMethodEvent e) {
417: ((InputMethodListener) a).inputMethodTextChanged(e);
418: ((InputMethodListener) b).inputMethodTextChanged(e);
419: }
420:
421: /**
422: * Handles the caretPositionChanged event by invoking the
423: * caretPositionChanged methods on listener-a and listener-b.
424: * @param e the item event
425: */
426: public void caretPositionChanged(InputMethodEvent e) {
427: ((InputMethodListener) a).caretPositionChanged(e);
428: ((InputMethodListener) b).caretPositionChanged(e);
429: }
430:
431: /**
432: * Handles the mouseWheelMoved event by invoking the
433: * mouseWheelMoved methods on listener-a and listener-b.
434: * @param e the mouse event
435: * @since 1.4
436: */
437: public void mouseWheelMoved(MouseWheelEvent e) {
438: ((MouseWheelListener) a).mouseWheelMoved(e);
439: ((MouseWheelListener) b).mouseWheelMoved(e);
440: }
441:
442: /**
443: * Adds component-listener-a with component-listener-b and
444: * returns the resulting multicast listener.
445: * @param a component-listener-a
446: * @param b component-listener-b
447: */
448: public static ComponentListener add(ComponentListener a,
449: ComponentListener b) {
450: return (ComponentListener) addInternal(a, b);
451: }
452:
453: /**
454: * Adds container-listener-a with container-listener-b and
455: * returns the resulting multicast listener.
456: * @param a container-listener-a
457: * @param b container-listener-b
458: */
459: public static ContainerListener add(ContainerListener a,
460: ContainerListener b) {
461: return (ContainerListener) addInternal(a, b);
462: }
463:
464: /**
465: * Adds focus-listener-a with focus-listener-b and
466: * returns the resulting multicast listener.
467: * @param a focus-listener-a
468: * @param b focus-listener-b
469: */
470: public static FocusListener add(FocusListener a, FocusListener b) {
471: return (FocusListener) addInternal(a, b);
472: }
473:
474: /**
475: * Adds key-listener-a with key-listener-b and
476: * returns the resulting multicast listener.
477: * @param a key-listener-a
478: * @param b key-listener-b
479: */
480: public static KeyListener add(KeyListener a, KeyListener b) {
481: return (KeyListener) addInternal(a, b);
482: }
483:
484: /**
485: * Adds input-method-listener-a with input-method-listener-b and
486: * returns the resulting multicast listener.
487: * @param a input-method-listener-a
488: * @param b input-method-listener-b
489: */
490: public static InputMethodListener add(InputMethodListener a,
491: InputMethodListener b) {
492: return (InputMethodListener) addInternal(a, b);
493: }
494:
495: /**
496: * Adds mouse-listener-a with mouse-listener-b and
497: * returns the resulting multicast listener.
498: * @param a mouse-listener-a
499: * @param b mouse-listener-b
500: */
501: public static MouseListener add(MouseListener a, MouseListener b) {
502: return (MouseListener) addInternal(a, b);
503: }
504:
505: /**
506: * Adds mouse-motion-listener-a with mouse-motion-listener-b and
507: * returns the resulting multicast listener.
508: * @param a mouse-motion-listener-a
509: * @param b mouse-motion-listener-b
510: */
511: public static MouseMotionListener add(MouseMotionListener a,
512: MouseMotionListener b) {
513: return (MouseMotionListener) addInternal(a, b);
514: }
515:
516: /**
517: * Adds window-listener-a with window-listener-b and
518: * returns the resulting multicast listener.
519: * @param a window-listener-a
520: * @param b window-listener-b
521: */
522: public static WindowListener add(WindowListener a, WindowListener b) {
523: return (WindowListener) addInternal(a, b);
524: }
525:
526: /**
527: * Adds window-focus-listener-a with window-focus-listener-b
528: * and returns the resulting multicast listener.
529: * @param a window-focus-listener-a
530: * @param b window-focus-listener-b
531: */
532: public static WindowFocusListener add(WindowFocusListener a,
533: WindowFocusListener b) {
534: return (WindowFocusListener) addInternal(a, b);
535: }
536:
537: /**
538: * Adds action-listener-a with action-listener-b and
539: * returns the resulting multicast listener.
540: * @param a action-listener-a
541: * @param b action-listener-b
542: */
543: public static ActionListener add(ActionListener a, ActionListener b) {
544: return (ActionListener) addInternal(a, b);
545: }
546:
547: /**
548: * Adds item-listener-a with item-listener-b and
549: * returns the resulting multicast listener.
550: * @param a item-listener-a
551: * @param b item-listener-b
552: */
553: public static ItemListener add(ItemListener a, ItemListener b) {
554: return (ItemListener) addInternal(a, b);
555: }
556:
557: /**
558: * Adds adjustment-listener-a with adjustment-listener-b and
559: * returns the resulting multicast listener.
560: * @param a adjustment-listener-a
561: * @param b adjustment-listener-b
562: */
563: public static AdjustmentListener add(AdjustmentListener a,
564: AdjustmentListener b) {
565: return (AdjustmentListener) addInternal(a, b);
566: }
567:
568: public static TextListener add(TextListener a, TextListener b) {
569: return (TextListener) addInternal(a, b);
570: }
571:
572: /**
573: * Adds mouse-wheel-listener-a with mouse-wheel-listener-b and
574: * returns the resulting multicast listener.
575: * @param a mouse-wheel-listener-a
576: * @param b mouse-wheel-listener-b
577: * @since 1.4
578: */
579: public static MouseWheelListener add(MouseWheelListener a,
580: MouseWheelListener b) {
581: return (MouseWheelListener) addInternal(a, b);
582: }
583:
584: /**
585: * Removes the old component-listener from component-listener-l and
586: * returns the resulting multicast listener.
587: * @param l component-listener-l
588: * @param oldl the component-listener being removed
589: */
590: public static ComponentListener remove(ComponentListener l,
591: ComponentListener oldl) {
592: return (ComponentListener) removeInternal(l, oldl);
593: }
594:
595: /**
596: * Removes the old container-listener from container-listener-l and
597: * returns the resulting multicast listener.
598: * @param l container-listener-l
599: * @param oldl the container-listener being removed
600: */
601: public static ContainerListener remove(ContainerListener l,
602: ContainerListener oldl) {
603: return (ContainerListener) removeInternal(l, oldl);
604: }
605:
606: /**
607: * Removes the old focus-listener from focus-listener-l and
608: * returns the resulting multicast listener.
609: * @param l focus-listener-l
610: * @param oldl the focus-listener being removed
611: */
612: public static FocusListener remove(FocusListener l,
613: FocusListener oldl) {
614: return (FocusListener) removeInternal(l, oldl);
615: }
616:
617: /**
618: * Removes the old key-listener from key-listener-l and
619: * returns the resulting multicast listener.
620: * @param l key-listener-l
621: * @param oldl the key-listener being removed
622: */
623: public static KeyListener remove(KeyListener l, KeyListener oldl) {
624: return (KeyListener) removeInternal(l, oldl);
625: }
626:
627: /**
628: * Removes the old input-method-listener from input-method-listener-l and
629: * returns the resulting multicast listener.
630: * @param l input-method-listener-l
631: * @param oldl the input-method-listener being removed
632: */
633: public static InputMethodListener remove(InputMethodListener l,
634: InputMethodListener oldl) {
635: return (InputMethodListener) removeInternal(l, oldl);
636: }
637:
638: /**
639: * Removes the old mouse-listener from mouse-listener-l and
640: * returns the resulting multicast listener.
641: * @param l mouse-listener-l
642: * @param oldl the mouse-listener being removed
643: */
644: public static MouseListener remove(MouseListener l,
645: MouseListener oldl) {
646: return (MouseListener) removeInternal(l, oldl);
647: }
648:
649: /**
650: * Removes the old mouse-motion-listener from mouse-motion-listener-l
651: * and returns the resulting multicast listener.
652: * @param l mouse-motion-listener-l
653: * @param oldl the mouse-motion-listener being removed
654: */
655: public static MouseMotionListener remove(MouseMotionListener l,
656: MouseMotionListener oldl) {
657: return (MouseMotionListener) removeInternal(l, oldl);
658: }
659:
660: /**
661: * Removes the old window-listener from window-listener-l and
662: * returns the resulting multicast listener.
663: * @param l window-listener-l
664: * @param oldl the window-listener being removed
665: */
666: public static WindowListener remove(WindowListener l,
667: WindowListener oldl) {
668: return (WindowListener) removeInternal(l, oldl);
669: }
670:
671: /**
672: * Removes the old window-focus-listener from window-focus-listener-l
673: * and returns the resulting multicast listener.
674: * @param l window-focus-listener-l
675: * @param oldl the window-focus-listener being removed
676: */
677: public static WindowFocusListener remove(WindowFocusListener l,
678: WindowFocusListener oldl) {
679: return (WindowFocusListener) removeInternal(l, oldl);
680: }
681:
682: /**
683: * Removes the old action-listener from action-listener-l and
684: * returns the resulting multicast listener.
685: * @param l action-listener-l
686: * @param oldl the action-listener being removed
687: */
688: public static ActionListener remove(ActionListener l,
689: ActionListener oldl) {
690: return (ActionListener) removeInternal(l, oldl);
691: }
692:
693: /**
694: * Removes the old item-listener from item-listener-l and
695: * returns the resulting multicast listener.
696: * @param l item-listener-l
697: * @param oldl the item-listener being removed
698: */
699: public static ItemListener remove(ItemListener l, ItemListener oldl) {
700: return (ItemListener) removeInternal(l, oldl);
701: }
702:
703: /**
704: * Removes the old adjustment-listener from adjustment-listener-l and
705: * returns the resulting multicast listener.
706: * @param l adjustment-listener-l
707: * @param oldl the adjustment-listener being removed
708: */
709: public static AdjustmentListener remove(AdjustmentListener l,
710: AdjustmentListener oldl) {
711: return (AdjustmentListener) removeInternal(l, oldl);
712: }
713:
714: public static TextListener remove(TextListener l, TextListener oldl) {
715: return (TextListener) removeInternal(l, oldl);
716: }
717:
718: /**
719: * Removes the old mouse-wheel-listener from mouse-wheel-listener-l
720: * and returns the resulting multicast listener.
721: * @param l mouse-wheel-listener-l
722: * @param oldl the mouse-wheel-listener being removed
723: * @since 1.4
724: */
725: public static MouseWheelListener remove(MouseWheelListener l,
726: MouseWheelListener oldl) {
727: return (MouseWheelListener) removeInternal(l, oldl);
728: }
729:
730: /**
731: * Returns the resulting multicast listener from adding listener-a
732: * and listener-b together.
733: * If listener-a is null, it returns listener-b;
734: * If listener-b is null, it returns listener-a
735: * If neither are null, then it creates and returns
736: * a new AWTEventMulticaster instance which chains a with b.
737: * @param a event listener-a
738: * @param b event listener-b
739: */
740: protected static EventListener addInternal(EventListener a,
741: EventListener b) {
742: if (a == null)
743: return b;
744: if (b == null)
745: return a;
746: return new AWTEventMulticaster(a, b);
747: }
748:
749: /**
750: * Returns the resulting multicast listener after removing the
751: * old listener from listener-l.
752: * If listener-l equals the old listener OR listener-l is null,
753: * returns null.
754: * Else if listener-l is an instance of AWTEventMulticaster,
755: * then it removes the old listener from it.
756: * Else, returns listener l.
757: * @param l the listener being removed from
758: * @param oldl the listener being removed
759: */
760: protected static EventListener removeInternal(EventListener l,
761: EventListener oldl) {
762: if (l == oldl || l == null) {
763: return null;
764: } else if (l instanceof AWTEventMulticaster) {
765: return ((AWTEventMulticaster) l).remove(oldl);
766: } else {
767: return l; // it's not here
768: }
769: }
770:
771: /* Serialization support.
772: */
773:
774: protected void saveInternal(ObjectOutputStream s, String k)
775: throws IOException {
776: if (a instanceof AWTEventMulticaster) {
777: ((AWTEventMulticaster) a).saveInternal(s, k);
778: } else if (a instanceof Serializable) {
779: s.writeObject(k);
780: s.writeObject(a);
781: }
782: if (b instanceof AWTEventMulticaster) {
783: ((AWTEventMulticaster) b).saveInternal(s, k);
784: } else if (b instanceof Serializable) {
785: s.writeObject(k);
786: s.writeObject(b);
787: }
788: }
789:
790: protected static void save(ObjectOutputStream s, String k,
791: EventListener l) throws IOException {
792: if (l == null) {
793: return;
794: } else if (l instanceof AWTEventMulticaster) {
795: ((AWTEventMulticaster) l).saveInternal(s, k);
796: } else if (l instanceof Serializable) {
797: s.writeObject(k);
798: s.writeObject(l);
799: }
800: }
801:
802: /**
803: * Returns an array of all the objects chained as
804: * <code><em>Foo</em>Listener</code>s by the specified
805: * <code>java.util.EventListener</code>.
806: * <code><em>Foo</em>Listener</code>s are chained by the
807: * <code>AWTEventMulticaster</code> using the
808: * <code>add<em>Foo</em>Listener</code> method.
809: * If a <code>null</code> listener is specified, this method returns an
810: * empty array. If the specified listener is not an instance of
811: * <code>AWTEventMulticaster</code>, this method returns an array which
812: * contains only the specified listener. If no such listeners are chanined,
813: * this method returns an empty array.
814: *
815: * @param l the specified <code>java.util.EventListener</code>
816: * @param listenerType the type of listeners requested; this parameter
817: * should specify an interface that descends from
818: * <code>java.util.EventListener</code>
819: * @return an array of all objects chained as
820: * <code><em>Foo</em>Listener</code>s by the specified multicast
821: * listener, or an empty array if no such listeners have been
822: * chained by the specified multicast listener
823: * @exception ClassCastException if <code>listenerType</code>
824: * doesn't specify a class or interface that implements
825: * <code>java.util.EventListener</code>
826: *
827: * @since 1.4
828: */
829: public static EventListener[] getListeners(EventListener l,
830: Class listenerType) {
831: int n = getListenerCount(l, listenerType);
832: EventListener[] result = (EventListener[]) Array.newInstance(
833: listenerType, n);
834: populateListenerArray(result, l, 0);
835: return result;
836: }
837:
838: /*
839: * Recursive method which returns a count of the number of listeners in
840: * EventListener, handling the (common) case of l actually being an
841: * AWTEventMulticaster. Additionally, only listeners of type listenerType
842: * are counted. Method modified to fix bug 4513402. -bchristi
843: */
844: private static int getListenerCount(EventListener l,
845: Class listenerType) {
846: if (l instanceof AWTEventMulticaster) {
847: AWTEventMulticaster mc = (AWTEventMulticaster) l;
848: return getListenerCount(mc.a, listenerType)
849: + getListenerCount(mc.b, listenerType);
850: } else {
851: // Only count listeners of correct type
852: return listenerType.isInstance(l) ? 1 : 0;
853: }
854: }
855:
856: /*
857: * Recusive method which populates EventListener array a with EventListeners * from l. l is usually an AWTEventMulticaster. Bug 4513402 revealed that
858: * if l differed in type from the element type of a, an ArrayStoreException
859: * would occur. Now l is only inserted into a if it's of the appropriate
860: * type. -bchristi
861: */
862: private static int populateListenerArray(EventListener[] a,
863: EventListener l, int index) {
864: if (l instanceof AWTEventMulticaster) {
865: AWTEventMulticaster mc = (AWTEventMulticaster) l;
866: int lhs = populateListenerArray(a, mc.a, index);
867: return populateListenerArray(a, mc.b, lhs);
868: } else if (a.getClass().getComponentType().isInstance(l)) {
869: a[index] = l;
870: return index + 1;
871: }
872: // Skip nulls, instances of wrong class
873: else {
874: return index;
875: }
876: }
877: }
|