home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / main.bin / AWTEventMulticaster.java < prev    next >
Text File  |  1997-05-20  |  22KB  |  661 lines

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