1 /* Copyright (C) 1999, 2000, 2002 Free Software Foundation
3 This file is part of GNU Classpath.
5 GNU Classpath is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 GNU Classpath is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNU Classpath; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 As a special exception, if you link this library with other files to
21 produce an executable, this library does not by itself cause the
22 resulting executable to be covered by the GNU General Public License.
23 This exception does not however invalidate any other reasons why the
24 executable file might be covered by the GNU General Public License. */
29 import java.awt.event.*;
30 import java.util.EventListener;
31 import java.io.ObjectOutputStream;
33 /* Written using on-line Java 2 Platform Standard Edition v1.3 API
34 * Specification, as well as "The Java Class Libraries", 2nd edition
35 * (Addison-Wesley, 1998).
36 * Status: Believed complete and correct to J2SE 1.3, except for
37 * serialization support methods, save() and saveInternal(), which are
42 * This class is used to implement a chain of event handlers. Dispatching
43 * using this class is thread safe. Here is a quick example of how to
44 * add and delete listeners using this class. For this example, we will
45 * assume are firing <code>AdjustableEvent</code>'s. However, this
46 * same approach is useful for all events in the <code>java.awt.event</code>
47 * package, and more if this class is subclassed.
50 * AdjustmentListener al;
53 * addAdjustmentListener(AdjustmentListener listener)
55 * al = AWTEventMulticaster.add(al, listener);
59 * removeAdjustmentListener(AdjustmentListener listener)
61 * al = AWTEventMulticaster.remove(al, listener);
65 * When it come time to process an event, simply call <code>al</code>,
66 * assuming it is not <code>null</code>.
68 * The first time <code>add</code> is called it is passed
69 * <code>null</code> and <code>listener</code> as its arguments. This
70 * starts building the chain. This class returns <code>listener</code>
71 * which becomes the new <code>al</code>. The next time, <code>add</code>
72 * is called with <code>al</code> and <code>listener</code> and the
73 * new listener is then chained to the old.
75 * @author Bryce McKinlay
76 * @author Aaron M. Renn (arenn@urbanophile.com)
78 public class AWTEventMulticaster implements ComponentListener,
79 ContainerListener, FocusListener, KeyListener, MouseListener,
80 MouseMotionListener, WindowListener, ActionListener, ItemListener,
81 AdjustmentListener, TextListener, InputMethodListener, HierarchyListener,
82 HierarchyBoundsListener
85 * A variable in the event chain.
87 protected final EventListener a;
90 * A variable in the event chain
92 protected final EventListener b;
95 * Initializes a new instance of <code>AWTEventMulticaster</code> with
96 * the specified event listener parameters.
98 * @param a The "a" listener object.
99 * @param b The "b" listener object.
101 protected AWTEventMulticaster(EventListener a,
109 * Chain <code>EventListener</code> b to a.
111 * @param a - Listener to chain to.
112 * @param b - Listener to chain.
114 * @return Latest entry in the chain.
116 protected static EventListener addInternal(EventListener a, EventListener b)
122 else return new AWTEventMulticaster(a, b);
126 * Removes the listener <code>old</code> from the listener <code>lis</code>.
128 * @param lis The listener to remove <code>old</code> from.
129 * @param old The listener to remove.
131 * @return The resulting listener after the remove operation.
133 protected static EventListener removeInternal(EventListener l,
138 else if (l instanceof AWTEventMulticaster)
140 AWTEventMulticaster mc = (AWTEventMulticaster) l;
141 return mc.remove(oldl);
147 * Removes the specified object from this multicaster object. If the
148 * object to remove is not part of this multicaster, then the remove
149 * method on the parent multicaster (if it exists) is called and a
150 * new multicaster object is returned based on that object and this
151 * multicaster's non-parent object.
153 * @param old The object to remove from this multicaster.
155 * @return The resulting multicaster with the specified listener removed.
157 protected EventListener remove(EventListener oldl)
159 // If oldl is an immediate child, return the other child.
165 // If a and/or b are Multicaster's, search them recursively.
166 if (a instanceof AWTEventMulticaster)
168 AWTEventMulticaster mc = (AWTEventMulticaster) a;
169 EventListener newa = mc.remove(oldl);
171 return new AWTEventMulticaster (newa, b);
173 if (b instanceof AWTEventMulticaster)
175 AWTEventMulticaster mc = (AWTEventMulticaster) a;
176 EventListener newb = mc.remove(oldl);
178 return new AWTEventMulticaster (a, newb);
181 // oldl was not found.
186 * Chain <code>ActionListener</code> b to a.
188 * @param a - Listener to chain to.
189 * @param b - Listener to chain.
191 * @return Latest entry in the chain.
193 public static ActionListener add(ActionListener a, ActionListener b)
195 return (ActionListener) addInternal(a, b);
199 * Chain <code>AdjustmentListener</code> b to a.
201 * @param a - Listener to chain to.
202 * @param b - Listener to chain.
204 * @return Latest entry in the chain.
206 public static AdjustmentListener add(AdjustmentListener a,
207 AdjustmentListener b)
209 return (AdjustmentListener) addInternal(a, b);
213 * Chain <code>ComponentListener</code> b to a.
215 * @param a - Listener to chain to.
216 * @param b - Listener to chain.
218 * @return Latest entry in the chain.
220 public static ComponentListener add(ComponentListener a, ComponentListener b)
222 return (ComponentListener) addInternal(a, b);
226 * Chain <code>ContainerListener</code> b to a.
228 * @param a - Listener to chain to.
229 * @param b - Listener to chain.
231 * @return Latest entry in the chain.
233 public static ContainerListener add(ContainerListener a, ContainerListener b)
235 return (ContainerListener) addInternal(a, b);
239 * Chain <code>FocusListener</code> b to a.
241 * @param a - Listener to chain to.
242 * @param b - Listener to chain.
244 * @return Latest entry in the chain.
246 public static FocusListener add(FocusListener a, FocusListener b)
248 return (FocusListener) addInternal(a, b);
251 public static HierarchyBoundsListener add(HierarchyBoundsListener a,
252 HierarchyBoundsListener b)
254 return (HierarchyBoundsListener) addInternal(a, b);
257 public static HierarchyListener add(HierarchyListener a, HierarchyListener b)
259 return (HierarchyListener) addInternal(a, b);
262 public static InputMethodListener add(InputMethodListener a,
263 InputMethodListener b)
265 return (InputMethodListener) addInternal(a, b);
269 * Chain <code>ItemListener</code> b to a.
271 * @param a - Listener to chain to.
272 * @param b - Listener to chain.
274 * @return Latest entry in the chain.
276 public static ItemListener add(ItemListener a, ItemListener b)
278 return (ItemListener) addInternal(a, b);
282 * Chain <code>KeyListener</code> b to a.
284 * @param a - Listener to chain to.
285 * @param b - Listener to chain.
287 * @return Latest entry in the chain.
289 public static KeyListener add(KeyListener a, KeyListener b)
291 return (KeyListener) addInternal(a, b);
295 * Chain <code>MouseListener</code> b to a.
297 * @param a - Listener to chain to.
298 * @param b - Listener to chain.
300 * @return Latest entry in the chain.
302 public static MouseListener add(MouseListener a, MouseListener b)
304 return (MouseListener) addInternal(a, b);
308 * Chain <code>MouseMotionListener</code> b to a.
310 * @param a - Listener to chain to.
311 * @param b - Listener to chain.
313 * @return Latest entry in the chain.
315 public static MouseMotionListener add(MouseMotionListener a,
316 MouseMotionListener b)
318 return (MouseMotionListener) addInternal(a, b);
322 * Chain <code>AdjustmentListener</code> b to a.
324 * @param a - Listener to chain to.
325 * @param b - Listener to chain.
327 * @return Latest entry in the chain.
329 public static TextListener add(TextListener a, TextListener b)
331 return (TextListener) addInternal(a, b);
335 * Chain <code>WindowListener</code> b to a.
337 * @param a - Listener to chain to.
338 * @param b - Listener to chain.
340 * @return Latest entry in the chain.
342 public static WindowListener add(WindowListener a, WindowListener b)
344 return (WindowListener) addInternal(a, b);
348 * Removes the listener <code>old</code> from the listener <code>lis</code>.
350 * @param lis The listener to remove <code>old</code> from.
351 * @param old The listener to remove.
353 * @return The resulting listener after the remove operation.
355 public static ActionListener remove(ActionListener l, ActionListener oldl)
357 return (ActionListener) removeInternal(l, oldl);
361 * Removes the listener <code>old</code> from the listener <code>lis</code>.
363 * @param lis The listener to remove <code>old</code> from.
364 * @param old The listener to remove.
366 * @return The resulting listener after the remove operation.
368 public static AdjustmentListener remove(AdjustmentListener l,
369 AdjustmentListener oldl)
371 return (AdjustmentListener) removeInternal(l, oldl);
375 * Removes the listener <code>old</code> from the listener <code>lis</code>.
377 * @param lis The listener to remove <code>old</code> from.
378 * @param old The listener to remove.
380 * @return The resulting listener after the remove operation.
382 public static ComponentListener remove(ComponentListener l,
383 ComponentListener oldl)
385 return (ComponentListener) removeInternal(l, oldl);
389 * Removes the listener <code>old</code> from the listener <code>lis</code>.
391 * @param lis The listener to remove <code>old</code> from.
392 * @param old The listener to remove.
394 * @return The resulting listener after the remove operation.
396 public static ContainerListener remove(ContainerListener l,
397 ContainerListener oldl)
399 return (ContainerListener) removeInternal(l, oldl);
403 * Removes the listener <code>old</code> from the listener <code>lis</code>.
405 * @param lis The listener to remove <code>old</code> from.
406 * @param old The listener to remove.
408 * @return The resulting listener after the remove operation.
410 public static FocusListener remove(FocusListener l, FocusListener oldl)
412 return (FocusListener) removeInternal(l, oldl);
415 public static HierarchyBoundsListener remove(HierarchyBoundsListener l,
416 HierarchyBoundsListener oldl)
418 return (HierarchyBoundsListener) removeInternal(l, oldl);
421 public static HierarchyListener remove(HierarchyListener l,
422 HierarchyListener oldl)
424 return (HierarchyListener) removeInternal(l, oldl);
427 public static InputMethodListener remove(InputMethodListener l,
428 InputMethodListener oldl)
430 return (InputMethodListener) removeInternal(l, oldl);
434 * Removes the listener <code>old</code> from the listener <code>lis</code>.
436 * @param lis The listener to remove <code>old</code> from.
437 * @param old The listener to remove.
439 * @return The resulting listener after the remove operation.
441 public static ItemListener remove(ItemListener l, ItemListener oldl)
443 return (ItemListener) removeInternal(l, oldl);
447 * Removes the listener <code>old</code> from the listener <code>lis</code>.
449 * @param lis The listener to remove <code>old</code> from.
450 * @param old The listener to remove.
452 * @return The resulting listener after the remove operation.
454 public static KeyListener remove(KeyListener l, KeyListener oldl)
456 return (KeyListener) removeInternal(l, oldl);
460 * Removes the listener <code>old</code> from the listener <code>lis</code>.
462 * @param lis The listener to remove <code>old</code> from.
463 * @param old The listener to remove.
465 * @return The resulting listener after the remove operation.
467 public static MouseListener remove(MouseListener l, MouseListener oldl)
469 return (MouseListener) removeInternal(l, oldl);
473 * Removes the listener <code>old</code> from the listener <code>lis</code>.
475 * @param lis The listener to remove <code>old</code> from.
476 * @param old The listener to remove.
478 * @return The resulting listener after the remove operation.
480 public static MouseMotionListener remove(MouseMotionListener l,
481 MouseMotionListener oldl)
483 return (MouseMotionListener) removeInternal(l, oldl);
487 * Removes the listener <code>old</code> from the listener <code>lis</code>.
489 * @param lis The listener to remove <code>old</code> from.
490 * @param old The listener to remove.
492 * @return The resulting listener after the remove operation.
494 public static TextListener remove(TextListener l, TextListener oldl)
496 return (TextListener) removeInternal(l, oldl);
500 * Removes the listener <code>old</code> from the listener <code>lis</code>.
502 * @param lis The listener to remove <code>old</code> from.
503 * @param old The listener to remove.
505 * @return The resulting listener after the remove operation.
507 public static WindowListener remove(WindowListener l, WindowListener oldl)
509 return (WindowListener) removeInternal(l, oldl);
513 * Handles this event by dispatching it to the "a" and "b" listener
516 * @param event The event to handle.
518 public void actionPerformed(ActionEvent e)
520 ((ActionListener) a).actionPerformed(e);
521 ((ActionListener) b).actionPerformed(e);
525 * Handles this event by dispatching it to the "a" and "b" listener
528 * @param event The event to handle.
530 public void adjustmentValueChanged(AdjustmentEvent e)
532 ((AdjustmentListener) a).adjustmentValueChanged(e);
533 ((AdjustmentListener) b).adjustmentValueChanged(e);
537 * Handles this event by dispatching it to the "a" and "b" listener
540 * @param event The event to handle.
542 public void componentHidden(ComponentEvent e)
544 ((ComponentListener) a).componentHidden(e);
545 ((ComponentListener) b).componentHidden(e);
549 * Handles this event by dispatching it to the "a" and "b" listener
552 * @param event The event to handle.
554 public void componentMoved(ComponentEvent e)
556 ((ComponentListener) a).componentMoved(e);
557 ((ComponentListener) b).componentMoved(e);
561 * Handles this event by dispatching it to the "a" and "b" listener
564 * @param event The event to handle.
566 public void componentResized(ComponentEvent e)
568 ((ComponentListener) a).componentResized(e);
569 ((ComponentListener) b).componentResized(e);
573 * Handles this event by dispatching it to the "a" and "b" listener
576 * @param event The event to handle.
578 public void componentShown(ComponentEvent e)
580 ((ComponentListener) a).componentShown(e);
581 ((ComponentListener) b).componentShown(e);
585 * Handles this event by dispatching it to the "a" and "b" listener
588 * @param event The event to handle.
590 public void componentAdded(ContainerEvent e)
592 ((ContainerListener) a).componentAdded(e);
593 ((ContainerListener) b).componentAdded(e);
597 * Handles this event by dispatching it to the "a" and "b" listener
600 * @param event The event to handle.
602 public void componentRemoved(ContainerEvent e)
604 ((ContainerListener) a).componentRemoved(e);
605 ((ContainerListener) b).componentRemoved(e);
609 * Handles this event by dispatching it to the "a" and "b" listener
612 * @param event The event to handle.
614 public void focusGained(FocusEvent e)
616 ((FocusListener) a).focusGained(e);
617 ((FocusListener) b).focusGained(e);
621 * Handles this event by dispatching it to the "a" and "b" listener
624 * @param event The event to handle.
626 public void focusLost(FocusEvent e)
628 ((FocusListener) a).focusLost(e);
629 ((FocusListener) b).focusLost(e);
633 * Handles this event by dispatching it to the "a" and "b" listener
636 * @param event The event to handle.
638 public void ancestorMoved(HierarchyEvent e)
640 ((HierarchyBoundsListener) a).ancestorMoved(e);
641 ((HierarchyBoundsListener) b).ancestorMoved(e);
645 * Handles this event by dispatching it to the "a" and "b" listener
648 * @param event The event to handle.
650 public void ancestorResized(HierarchyEvent e)
652 ((HierarchyBoundsListener) a).ancestorResized(e);
653 ((HierarchyBoundsListener) b).ancestorResized(e);
657 * Handles this event by dispatching it to the "a" and "b" listener
660 * @param event The event to handle.
662 public void hierarchyChanged(HierarchyEvent e)
664 ((HierarchyListener) a).hierarchyChanged(e);
665 ((HierarchyListener) b).hierarchyChanged(e);
669 * Handles this event by dispatching it to the "a" and "b" listener
672 * @param event The event to handle.
674 public void caretPositionChanged(InputMethodEvent e)
676 ((InputMethodListener) a).caretPositionChanged(e);
677 ((InputMethodListener) b).caretPositionChanged(e);
681 * Handles this event by dispatching it to the "a" and "b" listener
684 * @param event The event to handle.
686 public void inputMethodTextChanged(InputMethodEvent e)
688 ((InputMethodListener) a).inputMethodTextChanged(e);
689 ((InputMethodListener) b).inputMethodTextChanged(e);
693 * Handles this event by dispatching it to the "a" and "b" listener
696 * @param event The event to handle.
698 public void itemStateChanged(ItemEvent e)
700 ((ItemListener) a).itemStateChanged(e);
701 ((ItemListener) b).itemStateChanged(e);
705 * Handles this event by dispatching it to the "a" and "b" listener
708 * @param event The event to handle.
710 public void keyPressed(KeyEvent e)
712 ((KeyListener) a).keyPressed(e);
713 ((KeyListener) b).keyPressed(e);
717 * Handles this event by dispatching it to the "a" and "b" listener
720 * @param event The event to handle.
722 public void keyReleased(KeyEvent e)
724 ((KeyListener) a).keyReleased(e);
725 ((KeyListener) b).keyReleased(e);
729 * Handles this event by dispatching it to the "a" and "b" listener
732 * @param event The event to handle.
734 public void keyTyped(KeyEvent e)
736 ((KeyListener) a).keyTyped(e);
737 ((KeyListener) b).keyTyped(e);
741 * Handles this event by dispatching it to the "a" and "b" listener
744 * @param event The event to handle.
746 public void mouseClicked(MouseEvent e)
748 ((MouseListener) a).mouseClicked(e);
749 ((MouseListener) b).mouseClicked(e);
753 * Handles this event by dispatching it to the "a" and "b" listener
756 * @param event The event to handle.
758 public void mouseEntered(MouseEvent e)
760 ((MouseListener) a).mouseEntered(e);
761 ((MouseListener) b).mouseEntered(e);
765 * Handles this event by dispatching it to the "a" and "b" listener
768 * @param event The event to handle.
770 public void mouseExited(MouseEvent e)
772 ((MouseListener) a).mouseExited(e);
773 ((MouseListener) b).mouseExited(e);
777 * Handles this event by dispatching it to the "a" and "b" listener
780 * @param event The event to handle.
782 public void mousePressed(MouseEvent e)
784 ((MouseListener) a).mousePressed(e);
785 ((MouseListener) b).mousePressed(e);
789 * Handles this event by dispatching it to the "a" and "b" listener
792 * @param event The event to handle.
794 public void mouseReleased(MouseEvent e)
796 ((MouseListener) a).mouseReleased(e);
797 ((MouseListener) b).mouseReleased(e);
801 * Handles this event by dispatching it to the "a" and "b" listener
804 * @param event The event to handle.
806 public void mouseDragged(MouseEvent e)
808 ((MouseMotionListener) a).mouseDragged(e);
809 ((MouseMotionListener) b).mouseDragged(e);
813 * Handles this event by dispatching it to the "a" and "b" listener
816 * @param event The event to handle.
818 public void mouseMoved(MouseEvent e)
820 ((MouseMotionListener) a).mouseMoved(e);
821 ((MouseMotionListener) b).mouseMoved(e);
825 * Handles this event by dispatching it to the "a" and "b" listener
828 * @param event The event to handle.
830 public void textValueChanged(TextEvent e)
832 ((TextListener) a).textValueChanged(e);
833 ((TextListener) b).textValueChanged(e);
837 * Handles this event by dispatching it to the "a" and "b" listener
840 * @param event The event to handle.
842 public void windowActivated(WindowEvent e)
844 ((WindowListener) a).windowActivated(e);
845 ((WindowListener) b).windowActivated(e);
849 * Handles this event by dispatching it to the "a" and "b" listener
852 * @param event The event to handle.
854 public void windowClosed(WindowEvent e)
856 ((WindowListener) a).windowClosed(e);
857 ((WindowListener) b).windowClosed(e);
861 * Handles this event by dispatching it to the "a" and "b" listener
864 * @param event The event to handle.
866 public void windowClosing(WindowEvent e)
868 ((WindowListener) a).windowClosing(e);
869 ((WindowListener) b).windowClosing(e);
873 * Handles this event by dispatching it to the "a" and "b" listener
876 * @param event The event to handle.
878 public void windowDeactivated(WindowEvent e)
880 ((WindowListener) a).windowDeactivated(e);
881 ((WindowListener) b).windowDeactivated(e);
885 * Handles this event by dispatching it to the "a" and "b" listener
888 * @param event The event to handle.
890 public void windowDeiconified(WindowEvent e)
892 ((WindowListener) a).windowDeiconified(e);
893 ((WindowListener) b).windowDeiconified(e);
897 * Handles this event by dispatching it to the "a" and "b" listener
900 * @param event The event to handle.
902 public void windowIconified(WindowEvent e)
904 ((WindowListener) a).windowIconified(e);
905 ((WindowListener) b).windowIconified(e);
909 * Handles this event by dispatching it to the "a" and "b" listener
912 * @param event The event to handle.
914 public void windowOpened(WindowEvent e)
916 ((WindowListener) a).windowOpened(e);
917 ((WindowListener) b).windowOpened(e);
920 protected static void save(ObjectOutputStream s, String k, EventListener l)
922 throw new RuntimeException("Not Implemented");
925 protected void saveInternal(ObjectOutputStream s, String k)
927 throw new RuntimeException("Not Implemented");