home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / awt / AWTEventMulticaster.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  22.5 KB  |  696 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)AWTEventMulticaster.java    1.18 98/09/21
  3.  *
  4.  * Copyright 1996-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. import java.awt.event.*;
  17. import java.util.EventListener;
  18. import java.io.Serializable;
  19. import java.io.ObjectOutputStream;
  20. import java.io.IOException;
  21.  
  22.  
  23. /**
  24.  * A class which implements efficient and thread-safe multi-cast event 
  25.  * dispatching for the AWT events defined in the java.awt.event package.  
  26.  * This class will manage an immutable structure consisting of a chain of 
  27.  * event listeners and will dispatch events to those listeners.  Because
  28.  * the structure is immutable, it is safe to use this API to add/remove
  29.  * listeners during the process of an event dispatch operation.
  30.  *
  31.  * An example of how this class could be used to implement a new
  32.  * component which fires "action" events:
  33.  *
  34.  * <pre><code>
  35.  * public myComponent extends Component {
  36.  *     ActionListener actionListener = null;
  37.  *
  38.  *     public void addActionListener(ActionListener l) {
  39.  *       actionListener = AWTEventMulticaster.add(actionListener, l);
  40.  *     }
  41.  *     public void removeActionListener(ActionListener l) {
  42.  *         actionListener = AWTEventMulticaster.remove(actionListener, l);
  43.  *     }
  44.  *     public void processEvent(AWTEvent e) {
  45.  *         // when event occurs which causes "action" semantic
  46.  *         if (actionListener != null) {
  47.  *             actionListener.actionPerformed(new ActionEvent());
  48.  *         }         
  49.  * }
  50.  * </code></pre>
  51.  *
  52.  * @version     1.18, 09/21/98
  53.  * @author      John Rose
  54.  * @author     Amy Fowler
  55.  */
  56.  
  57. public class AWTEventMulticaster implements 
  58.     ComponentListener, ContainerListener, FocusListener, KeyListener,
  59.     MouseListener, MouseMotionListener, WindowListener,
  60.     ActionListener, ItemListener, AdjustmentListener,
  61.     TextListener, InputMethodListener {
  62.  
  63.     protected final EventListener a, b;
  64.  
  65.     /**
  66.      * Creates an event multicaster instance which chains listener-a
  67.      * with listener-b. Input parameters <code>a</code> and <code>b</code> 
  68.      * should not be <code>null</code>, though implementations may vary in 
  69.      * choosing whether or not to throw <code>NullPointerException</code> 
  70.      * in that case.
  71.      * @param a listener-a
  72.      * @param b listener-b
  73.      */ 
  74.     protected AWTEventMulticaster(EventListener a, EventListener b) {
  75.     this.a = a; this.b = b;
  76.     }
  77.  
  78.     /**
  79.      * Removes a listener from this multicaster and returns the
  80.      * resulting multicast listener.
  81.      * @param oldl the listener to be removed
  82.      */
  83.     protected EventListener remove(EventListener oldl) {
  84.     if (oldl == a)  return b;
  85.     if (oldl == b)  return a;
  86.     EventListener a2 = removeInternal(a, oldl);
  87.     EventListener b2 = removeInternal(b, oldl);
  88.     if (a2 == a && b2 == b) {
  89.         return this;    // it's not here
  90.     }
  91.     return addInternal(a2, b2);
  92.     }
  93.  
  94.     /**
  95.      * Handles the componentResized event by invoking the
  96.      * componentResized methods on listener-a and listener-b.
  97.      * @param e the component event
  98.      */
  99.     public void componentResized(ComponentEvent e) {
  100.         ((ComponentListener)a).componentResized(e);
  101.         ((ComponentListener)b).componentResized(e);
  102.     }
  103.  
  104.     /**
  105.      * Handles the componentMoved event by invoking the
  106.      * componentMoved methods on listener-a and listener-b.
  107.      * @param e the component event
  108.      */
  109.     public void componentMoved(ComponentEvent e) {
  110.         ((ComponentListener)a).componentMoved(e);
  111.         ((ComponentListener)b).componentMoved(e);
  112.     }
  113.  
  114.     /**
  115.      * Handles the componentShown event by invoking the
  116.      * componentShown methods on listener-a and listener-b.
  117.      * @param e the component event
  118.      */
  119.     public void componentShown(ComponentEvent e) {
  120.         ((ComponentListener)a).componentShown(e);
  121.         ((ComponentListener)b).componentShown(e);
  122.     }
  123.  
  124.     /**
  125.      * Handles the componentHidden event by invoking the
  126.      * componentHidden methods on listener-a and listener-b.
  127.      * @param e the component event
  128.      */
  129.     public void componentHidden(ComponentEvent e) {
  130.         ((ComponentListener)a).componentHidden(e);
  131.         ((ComponentListener)b).componentHidden(e);
  132.     }
  133.  
  134.     /**
  135.      * Handles the componentAdded container event by invoking the
  136.      * componentAdded methods on listener-a and listener-b.
  137.      * @param e the component event
  138.      */
  139.     public void componentAdded(ContainerEvent e) {
  140.         ((ContainerListener)a).componentAdded(e);
  141.         ((ContainerListener)b).componentAdded(e);
  142.     }
  143.  
  144.     /**
  145.      * Handles the componentRemoved container event by invoking the
  146.      * componentRemoved methods on listener-a and listener-b.
  147.      * @param e the component event
  148.      */
  149.     public void componentRemoved(ContainerEvent e) {
  150.         ((ContainerListener)a).componentRemoved(e);
  151.         ((ContainerListener)b).componentRemoved(e);
  152.     }
  153.  
  154.     /**
  155.      * Handles the focusGained event by invoking the
  156.      * focusGained methods on listener-a and listener-b.
  157.      * @param e the focus event
  158.      */
  159.     public void focusGained(FocusEvent e) {
  160.         ((FocusListener)a).focusGained(e);
  161.         ((FocusListener)b).focusGained(e);
  162.     }
  163.  
  164.     /**
  165.      * Handles the focusLost event by invoking the
  166.      * focusLost methods on listener-a and listener-b.
  167.      * @param e the focus event
  168.      */
  169.     public void focusLost(FocusEvent e) {
  170.         ((FocusListener)a).focusLost(e);
  171.         ((FocusListener)b).focusLost(e);
  172.     }
  173.  
  174.     /**
  175.      * Handles the keyTyped event by invoking the
  176.      * keyTyped methods on listener-a and listener-b.
  177.      * @param e the key event
  178.      */
  179.     public void keyTyped(KeyEvent e) {
  180.         ((KeyListener)a).keyTyped(e);
  181.         ((KeyListener)b).keyTyped(e);
  182.     }
  183.  
  184.     /**
  185.      * Handles the keyPressed event by invoking the
  186.      * keyPressed methods on listener-a and listener-b.
  187.      * @param e the key event
  188.      */
  189.     public void keyPressed(KeyEvent e) {
  190.         ((KeyListener)a).keyPressed(e);
  191.         ((KeyListener)b).keyPressed(e);
  192.     }
  193.  
  194.     /**
  195.      * Handles the keyReleased event by invoking the
  196.      * keyReleased methods on listener-a and listener-b.
  197.      * @param e the key event
  198.      */
  199.     public void keyReleased(KeyEvent e) {
  200.         ((KeyListener)a).keyReleased(e);
  201.         ((KeyListener)b).keyReleased(e);
  202.     }
  203.  
  204.     /**
  205.      * Handles the mouseClicked event by invoking the
  206.      * mouseClicked methods on listener-a and listener-b.
  207.      * @param e the mouse event
  208.      */
  209.     public void mouseClicked(MouseEvent e) {
  210.         ((MouseListener)a).mouseClicked(e);
  211.         ((MouseListener)b).mouseClicked(e);
  212.     }
  213.  
  214.     /**
  215.      * Handles the mousePressed event by invoking the
  216.      * mousePressed methods on listener-a and listener-b.
  217.      * @param e the mouse event
  218.      */
  219.     public void mousePressed(MouseEvent e) {
  220.         ((MouseListener)a).mousePressed(e);
  221.         ((MouseListener)b).mousePressed(e);
  222.     }
  223.  
  224.     /**
  225.      * Handles the mouseReleased event by invoking the
  226.      * mouseReleased methods on listener-a and listener-b.
  227.      * @param e the mouse event
  228.      */
  229.     public void mouseReleased(MouseEvent e) {
  230.         ((MouseListener)a).mouseReleased(e);
  231.         ((MouseListener)b).mouseReleased(e);
  232.     }
  233.  
  234.     /**
  235.      * Handles the mouseEntered event by invoking the
  236.      * mouseEntered methods on listener-a and listener-b.
  237.      * @param e the mouse event
  238.      */
  239.     public void mouseEntered(MouseEvent e) {
  240.         ((MouseListener)a).mouseEntered(e);
  241.         ((MouseListener)b).mouseEntered(e);
  242.     }
  243.  
  244.     /**
  245.      * Handles the mouseExited event by invoking the
  246.      * mouseExited methods on listener-a and listener-b.
  247.      * @param e the mouse event
  248.      */
  249.     public void mouseExited(MouseEvent e) {
  250.         ((MouseListener)a).mouseExited(e);
  251.         ((MouseListener)b).mouseExited(e);
  252.     }
  253.  
  254.     /**
  255.      * Handles the mouseDragged event by invoking the
  256.      * mouseDragged methods on listener-a and listener-b.
  257.      * @param e the mouse event
  258.      */
  259.     public void mouseDragged(MouseEvent e) {
  260.         ((MouseMotionListener)a).mouseDragged(e);
  261.         ((MouseMotionListener)b).mouseDragged(e);
  262.     }
  263.  
  264.     /**
  265.      * Handles the mouseMoved event by invoking the
  266.      * mouseMoved methods on listener-a and listener-b.
  267.      * @param e the mouse event
  268.      */
  269.     public void mouseMoved(MouseEvent e) {
  270.         ((MouseMotionListener)a).mouseMoved(e);
  271.         ((MouseMotionListener)b).mouseMoved(e);
  272.     }
  273.  
  274.     /**
  275.      * Handles the windowOpened event by invoking the
  276.      * windowOpened methods on listener-a and listener-b.
  277.      * @param e the window event
  278.      */
  279.     public void windowOpened(WindowEvent e) {
  280.         ((WindowListener)a).windowOpened(e);
  281.         ((WindowListener)b).windowOpened(e);
  282.     }
  283.  
  284.     /**
  285.      * Handles the windowClosing event by invoking the
  286.      * windowClosing methods on listener-a and listener-b.
  287.      * @param e the window event
  288.      */
  289.     public void windowClosing(WindowEvent e) {
  290.         ((WindowListener)a).windowClosing(e);
  291.         ((WindowListener)b).windowClosing(e);
  292.     }
  293.  
  294.     /**
  295.      * Handles the windowClosed event by invoking the
  296.      * windowClosed methods on listener-a and listener-b.
  297.      * @param e the window event
  298.      */
  299.     public void windowClosed(WindowEvent e) {
  300.         ((WindowListener)a).windowClosed(e);
  301.         ((WindowListener)b).windowClosed(e);
  302.     }
  303.  
  304.     /**
  305.      * Handles the windowIconified event by invoking the
  306.      * windowIconified methods on listener-a and listener-b.
  307.      * @param e the window event
  308.      */
  309.     public void windowIconified(WindowEvent e) {
  310.         ((WindowListener)a).windowIconified(e);
  311.         ((WindowListener)b).windowIconified(e);
  312.     }
  313.  
  314.     /**
  315.      * Handles the windowDeiconfied event by invoking the
  316.      * windowDeiconified methods on listener-a and listener-b.
  317.      * @param e the window event
  318.      */
  319.     public void windowDeiconified(WindowEvent e) {
  320.         ((WindowListener)a).windowDeiconified(e);
  321.         ((WindowListener)b).windowDeiconified(e);
  322.     }
  323.  
  324.     /**
  325.      * Handles the windowActivated event by invoking the
  326.      * windowActivated methods on listener-a and listener-b.
  327.      * @param e the window event
  328.      */
  329.     public void windowActivated(WindowEvent e) {
  330.         ((WindowListener)a).windowActivated(e);
  331.         ((WindowListener)b).windowActivated(e);
  332.     }
  333.  
  334.     /**
  335.      * Handles the windowDeactivated event by invoking the
  336.      * windowDeactivated methods on listener-a and listener-b.
  337.      * @param e the window event
  338.      */
  339.     public void windowDeactivated(WindowEvent e) {
  340.         ((WindowListener)a).windowDeactivated(e);
  341.         ((WindowListener)b).windowDeactivated(e);
  342.     }
  343.  
  344.     /**
  345.      * Handles the actionPerformed event by invoking the
  346.      * actionPerformed methods on listener-a and listener-b.
  347.      * @param e the action event
  348.      */
  349.     public void actionPerformed(ActionEvent e) {
  350.         ((ActionListener)a).actionPerformed(e);
  351.         ((ActionListener)b).actionPerformed(e);
  352.     }
  353.  
  354.     /**
  355.      * Handles the itemStateChanged event by invoking the
  356.      * itemStateChanged methods on listener-a and listener-b.
  357.      * @param e the item event
  358.      */
  359.     public void itemStateChanged(ItemEvent e) {
  360.         ((ItemListener)a).itemStateChanged(e);
  361.         ((ItemListener)b).itemStateChanged(e);
  362.     }
  363.  
  364.     /**
  365.      * Handles the adjustmentValueChanged event by invoking the
  366.      * adjustmentValueChanged methods on listener-a and listener-b.
  367.      * @param e the adjustment event
  368.      */
  369.     public void adjustmentValueChanged(AdjustmentEvent e) {
  370.         ((AdjustmentListener)a).adjustmentValueChanged(e);
  371.         ((AdjustmentListener)b).adjustmentValueChanged(e);
  372.     }
  373.     public void textValueChanged(TextEvent e) {
  374.         ((TextListener)a).textValueChanged(e);
  375.         ((TextListener)b).textValueChanged(e);
  376.     }
  377.  
  378.     /**
  379.      * Handles the inputMethodTextChanged event by invoking the
  380.      * inputMethodTextChanged methods on listener-a and listener-b.
  381.      * @param e the item event
  382.      */
  383.     public void inputMethodTextChanged(InputMethodEvent e) {
  384.        ((InputMethodListener)a).inputMethodTextChanged(e);
  385.        ((InputMethodListener)b).inputMethodTextChanged(e);
  386.     }
  387.  
  388.     /**
  389.      * Handles the caretPositionChanged event by invoking the
  390.      * caretPositionChanged methods on listener-a and listener-b.
  391.      * @param e the item event
  392.      */
  393.     public void caretPositionChanged(InputMethodEvent e) {
  394.        ((InputMethodListener)a).caretPositionChanged(e);
  395.        ((InputMethodListener)b).caretPositionChanged(e);
  396.     }
  397.  
  398.     /**
  399.      * Adds component-listener-a with component-listener-b and
  400.      * returns the resulting multicast listener.
  401.      * @param a component-listener-a
  402.      * @param b component-listener-b
  403.      */
  404.     public static ComponentListener add(ComponentListener a, ComponentListener b) {
  405.         return (ComponentListener)addInternal(a, b);
  406.     }
  407.  
  408.     /**
  409.      * Adds container-listener-a with container-listener-b and
  410.      * returns the resulting multicast listener.
  411.      * @param a container-listener-a
  412.      * @param b container-listener-b
  413.      */
  414.     public static ContainerListener add(ContainerListener a, ContainerListener b) {
  415.         return (ContainerListener)addInternal(a, b);
  416.     }
  417.  
  418.     /**
  419.      * Adds focus-listener-a with focus-listener-b and
  420.      * returns the resulting multicast listener.
  421.      * @param a focus-listener-a
  422.      * @param b focus-listener-b
  423.      */
  424.     public static FocusListener add(FocusListener a, FocusListener b) {
  425.         return (FocusListener)addInternal(a, b);
  426.     }
  427.  
  428.     /**
  429.      * Adds key-listener-a with key-listener-b and
  430.      * returns the resulting multicast listener.
  431.      * @param a key-listener-a
  432.      * @param b key-listener-b
  433.      */
  434.     public static KeyListener add(KeyListener a, KeyListener b) {
  435.         return (KeyListener)addInternal(a, b);
  436.     }
  437.  
  438.     /**
  439.      * Adds mouse-listener-a with mouse-listener-b and
  440.      * returns the resulting multicast listener.
  441.      * @param a mouse-listener-a
  442.      * @param b mouse-listener-b
  443.      */
  444.     public static MouseListener add(MouseListener a, MouseListener b) {
  445.         return (MouseListener)addInternal(a, b);
  446.     }
  447.  
  448.     /**
  449.      * Adds mouse-motion-listener-a with mouse-motion-listener-b and
  450.      * returns the resulting multicast listener.
  451.      * @param a mouse-motion-listener-a
  452.      * @param b mouse-motion-listener-b
  453.      */
  454.     public static MouseMotionListener add(MouseMotionListener a, MouseMotionListener b) {
  455.         return (MouseMotionListener)addInternal(a, b);
  456.     }
  457.  
  458.     /**
  459.      * Adds window-listener-a with window-listener-b and
  460.      * returns the resulting multicast listener.
  461.      * @param a window-listener-a
  462.      * @param b window-listener-b
  463.      */
  464.     public static WindowListener add(WindowListener a, WindowListener b) {
  465.         return (WindowListener)addInternal(a, b);
  466.     }
  467.  
  468.     /**
  469.      * Adds action-listener-a with action-listener-b and
  470.      * returns the resulting multicast listener.
  471.      * @param a action-listener-a
  472.      * @param b action-listener-b
  473.      */
  474.     public static ActionListener add(ActionListener a, ActionListener b) {
  475.         return (ActionListener)addInternal(a, b);
  476.     }
  477.  
  478.     /**
  479.      * Adds item-listener-a with item-listener-b and
  480.      * returns the resulting multicast listener.
  481.      * @param a item-listener-a
  482.      * @param b item-listener-b
  483.      */
  484.     public static ItemListener add(ItemListener a, ItemListener b) {
  485.         return (ItemListener)addInternal(a, b);
  486.     }
  487.  
  488.     /**
  489.      * Adds adjustment-listener-a with adjustment-listener-b and
  490.      * returns the resulting multicast listener.
  491.      * @param a adjustment-listener-a
  492.      * @param b adjustment-listener-b
  493.      */
  494.     public static AdjustmentListener add(AdjustmentListener a, AdjustmentListener b) {
  495.         return (AdjustmentListener)addInternal(a, b);
  496.     }
  497.     public static TextListener add(TextListener a, TextListener b) {
  498.         return (TextListener)addInternal(a, b);
  499.     }
  500.  
  501.     /**
  502.      * Adds input-method-listener-a with input-method-listener-b and
  503.      * returns the resulting multicast listener.
  504.      * @param a input-method-listener-a
  505.      * @param b input-method-listener-b
  506.      */
  507.      public static InputMethodListener add(InputMethodListener a, InputMethodListener b) {
  508.         return (InputMethodListener)addInternal(a, b);
  509.      }
  510.  
  511.     /**
  512.      * Removes the old component-listener from component-listener-l and
  513.      * returns the resulting multicast listener.
  514.      * @param l component-listener-l
  515.      * @param oldl the component-listener being removed
  516.      */
  517.     public static ComponentListener remove(ComponentListener l, ComponentListener oldl) {
  518.     return (ComponentListener) removeInternal(l, oldl);
  519.     }
  520.  
  521.     /**
  522.      * Removes the old container-listener from container-listener-l and
  523.      * returns the resulting multicast listener.
  524.      * @param l container-listener-l
  525.      * @param oldl the container-listener being removed
  526.      */
  527.     public static ContainerListener remove(ContainerListener l, ContainerListener oldl) {
  528.     return (ContainerListener) removeInternal(l, oldl);
  529.     }
  530.  
  531.     /**
  532.      * Removes the old focus-listener from focus-listener-l and
  533.      * returns the resulting multicast listener.
  534.      * @param l focus-listener-l
  535.      * @param oldl the focus-listener being removed
  536.      */
  537.     public static FocusListener remove(FocusListener l, FocusListener oldl) {
  538.     return (FocusListener) removeInternal(l, oldl);
  539.     }
  540.  
  541.     /**
  542.      * Removes the old key-listener from key-listener-l and
  543.      * returns the resulting multicast listener.
  544.      * @param l key-listener-l
  545.      * @param oldl the key-listener being removed
  546.      */
  547.     public static KeyListener remove(KeyListener l, KeyListener oldl) {
  548.     return (KeyListener) removeInternal(l, oldl);
  549.     }
  550.  
  551.     /**
  552.      * Removes the old mouse-listener from mouse-listener-l and
  553.      * returns the resulting multicast listener.
  554.      * @param l mouse-listener-l
  555.      * @param oldl the mouse-listener being removed
  556.      */
  557.     public static MouseListener remove(MouseListener l, MouseListener oldl) {
  558.     return (MouseListener) removeInternal(l, oldl);
  559.     }
  560.  
  561.     /**
  562.      * Removes the old mouse-motion-listener from mouse-motion-listener-l 
  563.      * and returns the resulting multicast listener.
  564.      * @param l mouse-motion-listener-l
  565.      * @param oldl the mouse-motion-listener being removed
  566.      */
  567.     public static MouseMotionListener remove(MouseMotionListener l, MouseMotionListener oldl) {
  568.     return (MouseMotionListener) removeInternal(l, oldl);
  569.     }
  570.  
  571.     /**
  572.      * Removes the old window-listener from window-listener-l and
  573.      * returns the resulting multicast listener.
  574.      * @param l window-listener-l
  575.      * @param oldl the window-listener being removed
  576.      */
  577.     public static WindowListener remove(WindowListener l, WindowListener oldl) {
  578.     return (WindowListener) removeInternal(l, oldl);
  579.     }
  580.  
  581.     /**
  582.      * Removes the old action-listener from action-listener-l and
  583.      * returns the resulting multicast listener.
  584.      * @param l action-listener-l
  585.      * @param oldl the action-listener being removed
  586.      */
  587.     public static ActionListener remove(ActionListener l, ActionListener oldl) {
  588.     return (ActionListener) removeInternal(l, oldl);
  589.     }
  590.  
  591.     /**
  592.      * Removes the old item-listener from item-listener-l and
  593.      * returns the resulting multicast listener.
  594.      * @param l item-listener-l
  595.      * @param oldl the item-listener being removed
  596.      */
  597.     public static ItemListener remove(ItemListener l, ItemListener oldl) {
  598.     return (ItemListener) removeInternal(l, oldl);
  599.     }
  600.  
  601.     /**
  602.      * Removes the old adjustment-listener from adjustment-listener-l and
  603.      * returns the resulting multicast listener.
  604.      * @param l adjustment-listener-l
  605.      * @param oldl the adjustment-listener being removed
  606.      */
  607.     public static AdjustmentListener remove(AdjustmentListener l, AdjustmentListener oldl) {
  608.     return (AdjustmentListener) removeInternal(l, oldl);
  609.     }
  610.     public static TextListener remove(TextListener l, TextListener oldl) {
  611.     return (TextListener) removeInternal(l, oldl);
  612.     }
  613.  
  614.     /**
  615.      * Removes the old input-method-listener from input-method-listener-l and
  616.      * returns the resulting multicast listener.
  617.      * @param l input-method-listener-l
  618.      * @param oldl the input-method-listener being removed
  619.      */
  620.     public static InputMethodListener remove(InputMethodListener l, InputMethodListener oldl) {
  621.         return (InputMethodListener) removeInternal(l, oldl);
  622.     }
  623.  
  624.     /** 
  625.      * Returns the resulting multicast listener from adding listener-a
  626.      * and listener-b together.  
  627.      * If listener-a is null, it returns listener-b;  
  628.      * If listener-b is null, it returns listener-a
  629.      * If neither are null, then it creates and returns
  630.      * a new AWTEventMulticaster instance which chains a with b.
  631.      * @param a event listener-a
  632.      * @param b event listener-b
  633.      */
  634.     protected static EventListener addInternal(EventListener a, EventListener b) {
  635.     if (a == null)  return b;
  636.     if (b == null)  return a;
  637.     return new AWTEventMulticaster(a, b);
  638.     }
  639.  
  640.     /** 
  641.      * Returns the resulting multicast listener after removing the
  642.      * old listener from listener-l.
  643.      * If listener-l equals the old listener OR listener-l is null, 
  644.      * returns null.
  645.      * Else if listener-l is an instance of AWTEventMulticaster, 
  646.      * then it removes the old listener from it.
  647.      * Else, returns listener l.
  648.      * @param l the listener being removed from
  649.      * @param oldl the listener being removed
  650.      */
  651.     protected static EventListener removeInternal(EventListener l, EventListener oldl) {
  652.     if (l == oldl || l == null) {
  653.         return null;
  654.     } else if (l instanceof AWTEventMulticaster) {
  655.         return ((AWTEventMulticaster)l).remove(oldl);
  656.     } else {
  657.         return l;        // it's not here
  658.     }
  659.     }
  660.       
  661.  
  662.     /* Serialization support.  
  663.      */
  664.  
  665.     protected void saveInternal(ObjectOutputStream s, String k) throws IOException {
  666.         if (a instanceof AWTEventMulticaster) {
  667.         ((AWTEventMulticaster)a).saveInternal(s, k);
  668.         }
  669.         else if (a instanceof Serializable) {
  670.             s.writeObject(k);
  671.             s.writeObject(a);
  672.         }
  673.         
  674.         if (b instanceof AWTEventMulticaster) {
  675.         ((AWTEventMulticaster)b).saveInternal(s, k);
  676.         }
  677.         else if (b instanceof Serializable) {
  678.             s.writeObject(k);
  679.             s.writeObject(b);
  680.         }
  681.     }
  682.  
  683.     protected static void save(ObjectOutputStream s, String k, EventListener l) throws IOException {
  684.       if (l == null) {
  685.           return;
  686.       } 
  687.       else if (l instanceof AWTEventMulticaster) {
  688.           ((AWTEventMulticaster)l).saveInternal(s, k);
  689.       }
  690.       else if (l instanceof Serializable) {
  691.            s.writeObject(k);
  692.            s.writeObject(l);
  693.       }
  694.     }
  695. }
  696.