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