Frames | No Frames |
1: /* AWTEventMulticaster.java -- allows multicast chaining of listeners 2: Copyright (C) 1999, 2000, 2002 Free Software Foundation 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.awt; 40: 41: import java.awt.event.ActionEvent; 42: import java.awt.event.ActionListener; 43: import java.awt.event.AdjustmentEvent; 44: import java.awt.event.AdjustmentListener; 45: import java.awt.event.ComponentEvent; 46: import java.awt.event.ComponentListener; 47: import java.awt.event.ContainerEvent; 48: import java.awt.event.ContainerListener; 49: import java.awt.event.FocusEvent; 50: import java.awt.event.FocusListener; 51: import java.awt.event.HierarchyBoundsListener; 52: import java.awt.event.HierarchyEvent; 53: import java.awt.event.HierarchyListener; 54: import java.awt.event.InputMethodEvent; 55: import java.awt.event.InputMethodListener; 56: import java.awt.event.ItemEvent; 57: import java.awt.event.ItemListener; 58: import java.awt.event.KeyEvent; 59: import java.awt.event.KeyListener; 60: import java.awt.event.MouseEvent; 61: import java.awt.event.MouseListener; 62: import java.awt.event.MouseMotionListener; 63: import java.awt.event.MouseWheelEvent; 64: import java.awt.event.MouseWheelListener; 65: import java.awt.event.TextEvent; 66: import java.awt.event.TextListener; 67: import java.awt.event.WindowEvent; 68: import java.awt.event.WindowFocusListener; 69: import java.awt.event.WindowListener; 70: import java.awt.event.WindowStateListener; 71: import java.io.IOException; 72: import java.io.ObjectOutputStream; 73: import java.io.Serializable; 74: import java.lang.reflect.Array; 75: import java.util.ArrayList; 76: import java.util.EventListener; 77: 78: /** 79: * This class is used to implement a chain of event handlers. Dispatching 80: * using this class is thread safe. Here is a quick example of how to 81: * add and delete listeners using this class. For this example, we will 82: * assume are firing <code>AdjustmentEvent</code>'s. However, this 83: * same approach is useful for all events in the <code>java.awt.event</code> 84: * package, and more if this class is subclassed. 85: * 86: * <p><code> 87: * AdjustmentListener al; 88: * public void addAdjustmentListener(AdjustmentListener listener) 89: * { 90: * al = AWTEventMulticaster.add(al, listener); 91: * } 92: * public void removeAdjustmentListener(AdjustmentListener listener) 93: * { 94: * al = AWTEventMulticaster.remove(al, listener); 95: * } 96: * </code> 97: * 98: * <p>When it come time to process an event, simply call <code>al</code>, 99: * assuming it is not <code>null</code>, and all listeners in the chain will 100: * be fired. 101: * 102: * <p>The first time <code>add</code> is called it is passed 103: * <code>null</code> and <code>listener</code> as its arguments. This 104: * starts building the chain. This class returns <code>listener</code> 105: * which becomes the new <code>al</code>. The next time, <code>add</code> 106: * is called with <code>al</code> and <code>listener</code> and the 107: * new listener is then chained to the old. 108: * 109: * @author Bryce McKinlay 110: * @author Aaron M. Renn (arenn@urbanophile.com) 111: * @author Eric Blake (ebb9@email.byu.edu) 112: * @since 1.1 113: * @status updated to 1.4 114: */ 115: public class AWTEventMulticaster 116: implements ComponentListener, ContainerListener, FocusListener, KeyListener, 117: MouseListener, MouseMotionListener, WindowListener, 118: WindowFocusListener, WindowStateListener, ActionListener, 119: ItemListener, AdjustmentListener, TextListener, 120: InputMethodListener, HierarchyListener, HierarchyBoundsListener, 121: MouseWheelListener 122: { 123: /** 124: * A variable in the event chain. 125: */ 126: protected final EventListener a; 127: 128: /** 129: * A variable in the event chain. 130: */ 131: protected final EventListener b; 132: 133: /** 134: * Initializes a new instance of <code>AWTEventMulticaster</code> with 135: * the specified event listener parameters. The parameters should not be 136: * null, although it is not required to enforce this with a 137: * NullPointerException. 138: * 139: * @param a the "a" listener object 140: * @param b the "b" listener object 141: */ 142: protected AWTEventMulticaster(EventListener a, EventListener b) 143: { 144: this.a = a; 145: this.b = b; 146: } 147: 148: /** 149: * Removes one instance of the specified listener from this multicaster 150: * chain. This descends recursively if either child is a multicaster, and 151: * returns a multicaster chain with the old listener removed. 152: * 153: * @param oldl the object to remove from this multicaster 154: * @return the resulting multicaster with the specified listener removed 155: */ 156: protected EventListener remove(EventListener oldl) 157: { 158: // If oldl is an immediate child, return the other child. 159: if (a == oldl) 160: return b; 161: if (b == oldl) 162: return a; 163: // If a and/or b are Multicaster's, search them recursively. 164: if (a instanceof AWTEventMulticaster) 165: { 166: EventListener newa = ((AWTEventMulticaster) a).remove(oldl); 167: if (newa != a) 168: return new AWTEventMulticaster(newa, b); 169: } 170: if (b instanceof AWTEventMulticaster) 171: { 172: EventListener newb = ((AWTEventMulticaster) b).remove(oldl); 173: if (newb != b) 174: return new AWTEventMulticaster(a, newb); 175: } 176: // oldl was not found. 177: return this; 178: } 179: 180: /** 181: * Handles this event by dispatching it to the "a" and "b" listener 182: * instances. 183: * 184: * @param e the event to handle 185: */ 186: public void componentResized(ComponentEvent e) 187: { 188: ((ComponentListener) a).componentResized(e); 189: ((ComponentListener) b).componentResized(e); 190: } 191: 192: /** 193: * Handles this event by dispatching it to the "a" and "b" listener 194: * instances. 195: * 196: * @param e the event to handle 197: */ 198: public void componentMoved(ComponentEvent e) 199: { 200: ((ComponentListener) a).componentMoved(e); 201: ((ComponentListener) b).componentMoved(e); 202: } 203: 204: /** 205: * Handles this event by dispatching it to the "a" and "b" listener 206: * instances. 207: * 208: * @param e the event to handle 209: */ 210: public void componentShown(ComponentEvent e) 211: { 212: ((ComponentListener) a).componentShown(e); 213: ((ComponentListener) b).componentShown(e); 214: } 215: 216: /** 217: * Handles this event by dispatching it to the "a" and "b" listener 218: * instances. 219: * 220: * @param e the event to handle 221: */ 222: public void componentHidden(ComponentEvent e) 223: { 224: ((ComponentListener) a).componentHidden(e); 225: ((ComponentListener) b).componentHidden(e); 226: } 227: 228: /** 229: * Handles this event by dispatching it to the "a" and "b" listener 230: * instances. 231: * 232: * @param e the event to handle 233: */ 234: public void componentAdded(ContainerEvent e) 235: { 236: ((ContainerListener) a).componentAdded(e); 237: ((ContainerListener) b).componentAdded(e); 238: } 239: 240: /** 241: * Handles this event by dispatching it to the "a" and "b" listener 242: * instances. 243: * 244: * @param e the event to handle 245: */ 246: public void componentRemoved(ContainerEvent e) 247: { 248: ((ContainerListener) a).componentRemoved(e); 249: ((ContainerListener) b).componentRemoved(e); 250: } 251: 252: /** 253: * Handles this event by dispatching it to the "a" and "b" listener 254: * instances. 255: * 256: * @param e the event to handle 257: */ 258: public void focusGained(FocusEvent e) 259: { 260: ((FocusListener) a).focusGained(e); 261: ((FocusListener) b).focusGained(e); 262: } 263: 264: /** 265: * Handles this event by dispatching it to the "a" and "b" listener 266: * instances. 267: * 268: * @param e the event to handle 269: */ 270: public void focusLost(FocusEvent e) 271: { 272: ((FocusListener) a).focusLost(e); 273: ((FocusListener) b).focusLost(e); 274: } 275: 276: /** 277: * Handles this event by dispatching it to the "a" and "b" listener 278: * instances. 279: * 280: * @param e the event to handle 281: */ 282: public void keyTyped(KeyEvent e) 283: { 284: ((KeyListener) a).keyTyped(e); 285: ((KeyListener) b).keyTyped(e); 286: } 287: 288: /** 289: * Handles this event by dispatching it to the "a" and "b" listener 290: * instances. 291: * 292: * @param e the event to handle 293: */ 294: public void keyPressed(KeyEvent e) 295: { 296: ((KeyListener) a).keyPressed(e); 297: ((KeyListener) b).keyPressed(e); 298: } 299: 300: /** 301: * Handles this event by dispatching it to the "a" and "b" listener 302: * instances. 303: * 304: * @param e the event to handle 305: */ 306: public void keyReleased(KeyEvent e) 307: { 308: ((KeyListener) a).keyReleased(e); 309: ((KeyListener) b).keyReleased(e); 310: } 311: 312: /** 313: * Handles this event by dispatching it to the "a" and "b" listener 314: * instances. 315: * 316: * @param e the event to handle 317: */ 318: public void mouseClicked(MouseEvent e) 319: { 320: ((MouseListener) a).mouseClicked(e); 321: ((MouseListener) b).mouseClicked(e); 322: } 323: 324: /** 325: * Handles this event by dispatching it to the "a" and "b" listener 326: * instances. 327: * 328: * @param e the event to handle 329: */ 330: public void mousePressed(MouseEvent e) 331: { 332: ((MouseListener) a).mousePressed(e); 333: ((MouseListener) b).mousePressed(e); 334: } 335: 336: /** 337: * Handles this event by dispatching it to the "a" and "b" listener 338: * instances. 339: * 340: * @param e the event to handle 341: */ 342: public void mouseReleased(MouseEvent e) 343: { 344: ((MouseListener) a).mouseReleased(e); 345: ((MouseListener) b).mouseReleased(e); 346: } 347: 348: /** 349: * Handles this event by dispatching it to the "a" and "b" listener 350: * instances. 351: * 352: * @param e the event to handle 353: */ 354: public void mouseEntered(MouseEvent e) 355: { 356: ((MouseListener) a).mouseEntered(e); 357: ((MouseListener) b).mouseEntered(e); 358: } 359: 360: /** 361: * Handles this event by dispatching it to the "a" and "b" listener 362: * instances. 363: * 364: * @param e the event to handle 365: */ 366: public void mouseExited(MouseEvent e) 367: { 368: ((MouseListener) a).mouseExited(e); 369: ((MouseListener) b).mouseExited(e); 370: } 371: 372: /** 373: * Handles this event by dispatching it to the "a" and "b" listener 374: * instances. 375: * 376: * @param e the event to handle 377: */ 378: public void mouseDragged(MouseEvent e) 379: { 380: ((MouseMotionListener) a).mouseDragged(e); 381: ((MouseMotionListener) b).mouseDragged(e); 382: } 383: 384: /** 385: * Handles this event by dispatching it to the "a" and "b" listener 386: * instances. 387: * 388: * @param e the event to handle 389: */ 390: public void mouseMoved(MouseEvent e) 391: { 392: ((MouseMotionListener) a).mouseMoved(e); 393: ((MouseMotionListener) b).mouseMoved(e); 394: } 395: 396: /** 397: * Handles this event by dispatching it to the "a" and "b" listener 398: * instances. 399: * 400: * @param e the event to handle 401: */ 402: public void windowOpened(WindowEvent e) 403: { 404: ((WindowListener) a).windowOpened(e); 405: ((WindowListener) b).windowOpened(e); 406: } 407: 408: /** 409: * Handles this event by dispatching it to the "a" and "b" listener 410: * instances. 411: * 412: * @param e the event to handle 413: */ 414: public void windowClosing(WindowEvent e) 415: { 416: ((WindowListener) a).windowClosing(e); 417: ((WindowListener) b).windowClosing(e); 418: } 419: 420: /** 421: * Handles this event by dispatching it to the "a" and "b" listener 422: * instances. 423: * 424: * @param e the event to handle 425: */ 426: public void windowClosed(WindowEvent e) 427: { 428: ((WindowListener) a).windowClosed(e); 429: ((WindowListener) b).windowClosed(e); 430: } 431: 432: /** 433: * Handles this event by dispatching it to the "a" and "b" listener 434: * instances. 435: * 436: * @param e the event to handle 437: */ 438: public void windowIconified(WindowEvent e) 439: { 440: ((WindowListener) a).windowIconified(e); 441: ((WindowListener) b).windowIconified(e); 442: } 443: 444: /** 445: * Handles this event by dispatching it to the "a" and "b" listener 446: * instances. 447: * 448: * @param e the event to handle 449: */ 450: public void windowDeiconified(WindowEvent e) 451: { 452: ((WindowListener) a).windowDeiconified(e); 453: ((WindowListener) b).windowDeiconified(e); 454: } 455: 456: /** 457: * Handles this event by dispatching it to the "a" and "b" listener 458: * instances. 459: * 460: * @param e the event to handle 461: */ 462: public void windowActivated(WindowEvent e) 463: { 464: ((WindowListener) a).windowActivated(e); 465: ((WindowListener) b).windowActivated(e); 466: } 467: 468: /** 469: * Handles this event by dispatching it to the "a" and "b" listener 470: * instances. 471: * 472: * @param e the event to handle 473: */ 474: public void windowDeactivated(WindowEvent e) 475: { 476: ((WindowListener) a).windowDeactivated(e); 477: ((WindowListener) b).windowDeactivated(e); 478: } 479: 480: /** 481: * Handles this event by dispatching it to the "a" and "b" listener 482: * instances. 483: * 484: * @param e the event to handle 485: * @since 1.4 486: */ 487: public void windowStateChanged(WindowEvent e) 488: { 489: ((WindowStateListener) a).windowStateChanged(e); 490: ((WindowStateListener) b).windowStateChanged(e); 491: } 492: 493: /** 494: * Handles this event by dispatching it to the "a" and "b" listener 495: * instances. 496: * 497: * @param e the event to handle 498: * @since 1.4 499: */ 500: public void windowGainedFocus(WindowEvent e) 501: { 502: ((WindowFocusListener) a).windowGainedFocus(e); 503: ((WindowFocusListener) b).windowGainedFocus(e); 504: } 505: 506: /** 507: * Handles this event by dispatching it to the "a" and "b" listener 508: * instances. 509: * 510: * @param e the event to handle 511: * @since 1.4 512: */ 513: public void windowLostFocus(WindowEvent e) 514: { 515: ((WindowFocusListener) a).windowLostFocus(e); 516: ((WindowFocusListener) b).windowLostFocus(e); 517: } 518: 519: /** 520: * Handles this event by dispatching it to the "a" and "b" listener 521: * instances. 522: * 523: * @param e the event to handle 524: */ 525: public void actionPerformed(ActionEvent e) 526: { 527: ((ActionListener) a).actionPerformed(e); 528: ((ActionListener) b).actionPerformed(e); 529: } 530: 531: /** 532: * Handles this event by dispatching it to the "a" and "b" listener 533: * instances. 534: * 535: * @param e the event to handle 536: */ 537: public void itemStateChanged(ItemEvent e) 538: { 539: ((ItemListener) a).itemStateChanged(e); 540: ((ItemListener) b).itemStateChanged(e); 541: } 542: 543: /** 544: * Handles this event by dispatching it to the "a" and "b" listener 545: * instances. 546: * 547: * @param e the event to handle 548: */ 549: public void adjustmentValueChanged(AdjustmentEvent e) 550: { 551: ((AdjustmentListener) a).adjustmentValueChanged(e); 552: ((AdjustmentListener) b).adjustmentValueChanged(e); 553: } 554: 555: /** 556: * Handles this event by dispatching it to the "a" and "b" listener 557: * instances. 558: * 559: * @param e the event to handle 560: */ 561: public void textValueChanged(TextEvent e) 562: { 563: ((TextListener) a).textValueChanged(e); 564: ((TextListener) b).textValueChanged(e); 565: } 566: 567: /** 568: * Handles this event by dispatching it to the "a" and "b" listener 569: * instances. 570: * 571: * @param e the event to handle 572: * @since 1.2 573: */ 574: public void inputMethodTextChanged(InputMethodEvent e) 575: { 576: ((InputMethodListener) a).inputMethodTextChanged(e); 577: ((InputMethodListener) b).inputMethodTextChanged(e); 578: } 579: 580: /** 581: * Handles this event by dispatching it to the "a" and "b" listener 582: * instances. 583: * 584: * @param e the event to handle 585: * @since 1.2 586: */ 587: public void caretPositionChanged(InputMethodEvent e) 588: { 589: ((InputMethodListener) a).caretPositionChanged(e); 590: ((InputMethodListener) b).caretPositionChanged(e); 591: } 592: 593: /** 594: * Handles this event by dispatching it to the "a" and "b" listener 595: * instances. 596: * 597: * @param e the event to handle 598: * @since 1.3 599: */ 600: public void hierarchyChanged(HierarchyEvent e) 601: { 602: ((HierarchyListener) a).hierarchyChanged(e); 603: ((HierarchyListener) b).hierarchyChanged(e); 604: } 605: 606: /** 607: * Handles this event by dispatching it to the "a" and "b" listener 608: * instances. 609: * 610: * @param e the event to handle 611: * @since 1.3 612: */ 613: public void ancestorMoved(HierarchyEvent e) 614: { 615: ((HierarchyBoundsListener) a).ancestorMoved(e); 616: ((HierarchyBoundsListener) b).ancestorMoved(e); 617: } 618: 619: /** 620: * Handles this event by dispatching it to the "a" and "b" listener 621: * instances. 622: * 623: * @param e the event to handle 624: * @since 1.3 625: */ 626: public void ancestorResized(HierarchyEvent e) 627: { 628: ((HierarchyBoundsListener) a).ancestorResized(e); 629: ((HierarchyBoundsListener) b).ancestorResized(e); 630: } 631: 632: /** 633: * Handles this event by dispatching it to the "a" and "b" listener 634: * instances. 635: * 636: * @param e the event to handle 637: * @since 1.4 638: */ 639: public void mouseWheelMoved(MouseWheelEvent e) 640: { 641: ((MouseWheelListener) a).mouseWheelMoved(e); 642: ((MouseWheelListener) b).mouseWheelMoved(e); 643: } 644: 645: /** 646: * Chain <code>ComponentListener</code> a and b. 647: * 648: * @param a the "a" listener, may be null 649: * @param b the "b" listener, may be null 650: * @return latest entry in the chain 651: */ 652: public static ComponentListener add(ComponentListener a, ComponentListener b) 653: { 654: return (ComponentListener) addInternal(a, b); 655: } 656: 657: /** 658: * Chain <code>ContainerListener</code> a and b. 659: * 660: * @param a the "a" listener, may be null 661: * @param b the "b" listener, may be null 662: * @return latest entry in the chain 663: */ 664: public static ContainerListener add(ContainerListener a, ContainerListener b) 665: { 666: return (ContainerListener) addInternal(a, b); 667: } 668: 669: /** 670: * Chain <code>FocusListener</code> a and b. 671: * 672: * @param a the "a" listener, may be null 673: * @param b the "b" listener, may be null 674: * @return latest entry in the chain 675: */ 676: public static FocusListener add(FocusListener a, FocusListener b) 677: { 678: return (FocusListener) addInternal(a, b); 679: } 680: 681: /** 682: * Chain <code>KeyListener</code> a and b. 683: * 684: * @param a the "a" listener, may be null 685: * @param b the "b" listener, may be null 686: * @return latest entry in the chain 687: */ 688: public static KeyListener add(KeyListener a, KeyListener b) 689: { 690: return (KeyListener) addInternal(a, b); 691: } 692: 693: /** 694: * Chain <code>MouseListener</code> a and b. 695: * 696: * @param a the "a" listener, may be null 697: * @param b the "b" listener, may be null 698: * @return latest entry in the chain 699: */ 700: public static MouseListener add(MouseListener a, MouseListener b) 701: { 702: return (MouseListener) addInternal(a, b); 703: } 704: 705: /** 706: * Chain <code>MouseMotionListener</code> a and b. 707: * 708: * @param a the "a" listener, may be null 709: * @param b the "b" listener, may be null 710: * @return latest entry in the chain 711: */ 712: public static MouseMotionListener add(MouseMotionListener a, 713: MouseMotionListener b) 714: { 715: return (MouseMotionListener) addInternal(a, b); 716: } 717: 718: /** 719: * Chain <code>WindowListener</code> a and b. 720: * 721: * @param a the "a" listener, may be null 722: * @param b the "b" listener, may be null 723: * @return latest entry in the chain 724: */ 725: public static WindowListener add(WindowListener a, WindowListener b) 726: { 727: return (WindowListener) addInternal(a, b); 728: } 729: 730: /** 731: * Chain <code>WindowStateListener</code> a and b. 732: * 733: * @param a the "a" listener, may be null 734: * @param b the "b" listener, may be null 735: * @return latest entry in the chain 736: * @since 1.4 737: */ 738: public static WindowStateListener add(WindowStateListener a, 739: WindowStateListener b) 740: { 741: return (WindowStateListener) addInternal(a, b); 742: } 743: 744: /** 745: * Chain <code>WindowFocusListener</code> a and b. 746: * 747: * @param a the "a" listener, may be null 748: * @param b the "b" listener, may be null 749: * @return latest entry in the chain 750: * @since 1.4 751: */ 752: public static WindowFocusListener add(WindowFocusListener a, 753: WindowFocusListener b) 754: { 755: return (WindowFocusListener) addInternal(a, b); 756: } 757: 758: /** 759: * Chain <code>ActionListener</code> a and b. 760: * 761: * @param a the "a" listener, may be null 762: * @param b the "b" listener, may be null 763: * @return latest entry in the chain 764: */ 765: public static ActionListener add(ActionListener a, ActionListener b) 766: { 767: return (ActionListener) addInternal(a, b); 768: } 769: 770: /** 771: * Chain <code>ItemListener</code> a and b. 772: * 773: * @param a the "a" listener, may be null 774: * @param b the "b" listener, may be null 775: * @return latest entry in the chain 776: */ 777: public static ItemListener add(ItemListener a, ItemListener b) 778: { 779: return (ItemListener) addInternal(a, b); 780: } 781: 782: /** 783: * Chain <code>AdjustmentListener</code> a and b. 784: * 785: * @param a the "a" listener, may be null 786: * @param b the "b" listener, may be null 787: * @return latest entry in the chain 788: */ 789: public static AdjustmentListener add(AdjustmentListener a, 790: AdjustmentListener b) 791: { 792: return (AdjustmentListener) addInternal(a, b); 793: } 794: 795: /** 796: * Chain <code>AdjustmentListener</code> a and b. 797: * 798: * @param a the "a" listener, may be null 799: * @param b the "b" listener, may be null 800: * @return latest entry in the chain 801: */ 802: public static TextListener add(TextListener a, TextListener b) 803: { 804: return (TextListener) addInternal(a, b); 805: } 806: 807: /** 808: * Chain <code>InputMethodListener</code> a and b. 809: * 810: * @param a the "a" listener, may be null 811: * @param b the "b" listener, may be null 812: * @return latest entry in the chain 813: * @since 1.2 814: */ 815: public static InputMethodListener add(InputMethodListener a, 816: InputMethodListener b) 817: { 818: return (InputMethodListener) addInternal(a, b); 819: } 820: 821: /** 822: * Chain <code>HierarchyListener</code> a and b. 823: * 824: * @param a the "a" listener, may be null 825: * @param b the "b" listener, may be null 826: * @return latest entry in the chain 827: * @since 1.3 828: */ 829: public static HierarchyListener add(HierarchyListener a, HierarchyListener b) 830: { 831: return (HierarchyListener) addInternal(a, b); 832: } 833: 834: /** 835: * Chain <code>HierarchyBoundsListener</code> a and b. 836: * 837: * @param a the "a" listener, may be null 838: * @param b the "b" listener, may be null 839: * @return latest entry in the chain 840: * @since 1.3 841: */ 842: public static HierarchyBoundsListener add(HierarchyBoundsListener a, 843: HierarchyBoundsListener b) 844: { 845: return (HierarchyBoundsListener) addInternal(a, b); 846: } 847: 848: /** 849: * Chain <code>MouseWheelListener</code> a and b. 850: * 851: * @param a the "a" listener, may be null 852: * @param b the "b" listener, may be null 853: * @return latest entry in the chain 854: * @since 1.4 855: */ 856: public static MouseWheelListener add(MouseWheelListener a, 857: MouseWheelListener b) 858: { 859: return (MouseWheelListener) addInternal(a, b); 860: } 861: 862: /** 863: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 864: * 865: * @param l the listener chain to reduce 866: * @param oldl the listener to remove 867: * @return the resulting listener chain 868: */ 869: public static ComponentListener remove(ComponentListener l, 870: ComponentListener oldl) 871: { 872: return (ComponentListener) removeInternal(l, oldl); 873: } 874: 875: /** 876: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 877: * 878: * @param l the listener chain to reduce 879: * @param oldl the listener to remove 880: * @return the resulting listener chain 881: */ 882: public static ContainerListener remove(ContainerListener l, 883: ContainerListener oldl) 884: { 885: return (ContainerListener) removeInternal(l, oldl); 886: } 887: 888: /** 889: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 890: * 891: * @param l the listener chain to reduce 892: * @param oldl the listener to remove 893: * @return the resulting listener chain 894: */ 895: public static FocusListener remove(FocusListener l, FocusListener oldl) 896: { 897: return (FocusListener) removeInternal(l, oldl); 898: } 899: 900: /** 901: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 902: * 903: * @param l the listener chain to reduce 904: * @param oldl the listener to remove 905: * @return the resulting listener chain 906: */ 907: public static KeyListener remove(KeyListener l, KeyListener oldl) 908: { 909: return (KeyListener) removeInternal(l, oldl); 910: } 911: 912: /** 913: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 914: * 915: * @param l the listener chain to reduce 916: * @param oldl the listener to remove 917: * @return the resulting listener chain 918: */ 919: public static MouseListener remove(MouseListener l, MouseListener oldl) 920: { 921: return (MouseListener) removeInternal(l, oldl); 922: } 923: 924: /** 925: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 926: * 927: * @param l the listener chain to reduce 928: * @param oldl the listener to remove 929: * @return the resulting listener chain 930: */ 931: public static MouseMotionListener remove(MouseMotionListener l, 932: MouseMotionListener oldl) 933: { 934: return (MouseMotionListener) removeInternal(l, oldl); 935: } 936: 937: /** 938: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 939: * 940: * @param l the listener chain to reduce 941: * @param oldl the listener to remove 942: * @return the resulting listener chain 943: */ 944: public static WindowListener remove(WindowListener l, WindowListener oldl) 945: { 946: return (WindowListener) removeInternal(l, oldl); 947: } 948: 949: /** 950: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 951: * 952: * @param l the listener chain to reduce 953: * @param oldl the listener to remove 954: * @return the resulting listener chain 955: * @since 1.4 956: */ 957: public static WindowStateListener remove(WindowStateListener l, 958: WindowStateListener oldl) 959: { 960: return (WindowStateListener) removeInternal(l, oldl); 961: } 962: 963: /** 964: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 965: * 966: * @param l the listener chain to reduce 967: * @param oldl the listener to remove 968: * @return the resulting listener chain 969: * @since 1.4 970: */ 971: public static WindowFocusListener remove(WindowFocusListener l, 972: WindowFocusListener oldl) 973: { 974: return (WindowFocusListener) removeInternal(l, oldl); 975: } 976: 977: /** 978: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 979: * 980: * @param l the listener chain to reduce 981: * @param oldl the listener to remove 982: * @return the resulting listener chain 983: */ 984: public static ActionListener remove(ActionListener l, ActionListener oldl) 985: { 986: return (ActionListener) removeInternal(l, oldl); 987: } 988: 989: /** 990: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 991: * 992: * @param l the listener chain to reduce 993: * @param oldl the listener to remove 994: * @return the resulting listener chain 995: */ 996: public static ItemListener remove(ItemListener l, ItemListener oldl) 997: { 998: return (ItemListener) removeInternal(l, oldl); 999: } 1000: 1001: /** 1002: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 1003: * 1004: * @param l the listener chain to reduce 1005: * @param oldl the listener to remove 1006: * @return the resulting listener chain 1007: */ 1008: public static AdjustmentListener remove(AdjustmentListener l, 1009: AdjustmentListener oldl) 1010: { 1011: return (AdjustmentListener) removeInternal(l, oldl); 1012: } 1013: 1014: /** 1015: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 1016: * 1017: * @param l the listener chain to reduce 1018: * @param oldl the listener to remove 1019: * @return the resulting listener chain 1020: */ 1021: public static TextListener remove(TextListener l, TextListener oldl) 1022: { 1023: return (TextListener) removeInternal(l, oldl); 1024: } 1025: 1026: /** 1027: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 1028: * 1029: * @param l the listener chain to reduce 1030: * @param oldl the listener to remove 1031: * @return the resulting listener chain 1032: * @since 1.2 1033: */ 1034: public static InputMethodListener remove(InputMethodListener l, 1035: InputMethodListener oldl) 1036: { 1037: return (InputMethodListener) removeInternal(l, oldl); 1038: } 1039: 1040: /** 1041: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 1042: * 1043: * @param l the listener chain to reduce 1044: * @param oldl the listener to remove 1045: * @return the resulting listener chain 1046: * @since 1.3 1047: */ 1048: public static HierarchyListener remove(HierarchyListener l, 1049: HierarchyListener oldl) 1050: { 1051: return (HierarchyListener) removeInternal(l, oldl); 1052: } 1053: 1054: /** 1055: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 1056: * 1057: * @param l the listener chain to reduce 1058: * @param oldl the listener to remove 1059: * @return the resulting listener chain 1060: * @since 1.3 1061: */ 1062: public static HierarchyBoundsListener remove(HierarchyBoundsListener l, 1063: HierarchyBoundsListener oldl) 1064: { 1065: return (HierarchyBoundsListener) removeInternal(l, oldl); 1066: } 1067: 1068: /** 1069: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 1070: * 1071: * @param l the listener chain to reduce 1072: * @param oldl the listener to remove 1073: * @return the resulting listener chain 1074: * @since 1.4 1075: */ 1076: public static MouseWheelListener remove(MouseWheelListener l, 1077: MouseWheelListener oldl) 1078: { 1079: return (MouseWheelListener) removeInternal(l, oldl); 1080: } 1081: 1082: /** 1083: * Chain <code>EventListener</code> a and b. 1084: * 1085: * @param a the "a" listener, may be null 1086: * @param b the "b" listener, may be null 1087: * @return latest entry in the chain 1088: */ 1089: protected static EventListener addInternal(EventListener a, EventListener b) 1090: { 1091: if (a == null) 1092: return b; 1093: if (b == null) 1094: return a; 1095: return new AWTEventMulticaster(a, b); 1096: } 1097: 1098: /** 1099: * Removes the listener <code>oldl</code> from the listener <code>l</code>. 1100: * 1101: * @param l the listener chain to reduce 1102: * @param oldl the listener to remove 1103: * @return the resulting listener chain 1104: */ 1105: protected static EventListener removeInternal(EventListener l, 1106: EventListener oldl) 1107: { 1108: if (l == oldl) 1109: return null; 1110: if (l instanceof AWTEventMulticaster) 1111: return ((AWTEventMulticaster) l).remove(oldl); 1112: return l; 1113: } 1114: 1115: /** 1116: * Saves all Serializable listeners to a serialization stream. 1117: * 1118: * @param s the stream to save to 1119: * @param k a prefix stream put before each serializable listener 1120: * @throws IOException if serialization fails 1121: */ 1122: protected void saveInternal(ObjectOutputStream s, String k) 1123: throws IOException 1124: { 1125: // This is not documented by Sun, but I think it is correct. 1126: if (a instanceof AWTEventMulticaster) 1127: ((AWTEventMulticaster) a).saveInternal(s, k); 1128: else if (a instanceof Serializable) 1129: { 1130: s.writeObject(k); 1131: s.writeObject(a); 1132: } 1133: if (b instanceof AWTEventMulticaster) 1134: ((AWTEventMulticaster) b).saveInternal(s, k); 1135: else if (b instanceof Serializable) 1136: { 1137: s.writeObject(k); 1138: s.writeObject(b); 1139: } 1140: } 1141: 1142: /** 1143: * Saves a Serializable listener chain to a serialization stream. 1144: * 1145: * @param s the stream to save to 1146: * @param k a prefix stream put before each serializable listener 1147: * @param l the listener chain to save 1148: * @throws IOException if serialization fails 1149: */ 1150: protected static void save(ObjectOutputStream s, String k, EventListener l) 1151: throws IOException 1152: { 1153: // This is not documented by Sun, but I think it is correct. 1154: if (l instanceof AWTEventMulticaster) 1155: ((AWTEventMulticaster) l).saveInternal(s, k); 1156: else if (l instanceof Serializable) 1157: { 1158: s.writeObject(k); 1159: s.writeObject(l); 1160: } 1161: } 1162: 1163: /** 1164: * Returns an array of all chained listeners of the specified type in the 1165: * given chain. A null listener returns an empty array, and a listener 1166: * which is not an AWTEventMulticaster returns an array of one element. If 1167: * no listeners in the chain are of the specified type, an empty array is 1168: * returned. 1169: * 1170: * @param l the listener chain to convert to an array 1171: * @param type the type of listeners to collect 1172: * @return an array of the listeners of that type in the chain 1173: * @throws ClassCastException if type is not assignable from EventListener 1174: * @throws NullPointerException if type is null 1175: * @throws IllegalArgumentException if type is Void.TYPE 1176: * @since 1.4 1177: */ 1178: public static <T extends EventListener> T[] getListeners(EventListener l, 1179: Class<T> type) 1180: { 1181: ArrayList<EventListener> list = new ArrayList<EventListener>(); 1182: if (l instanceof AWTEventMulticaster) 1183: ((AWTEventMulticaster) l).getListeners(list, type); 1184: else if (type.isInstance(l)) 1185: list.add(l); 1186: EventListener[] r = (EventListener[]) Array.newInstance(type, list.size()); 1187: list.toArray(r); 1188: return (T[]) r; 1189: } 1190: 1191: /** 1192: * Collects all instances of the given type in the chain into the list. 1193: * 1194: * @param l the list to collect into 1195: * @param type the type of listeners to collect 1196: * @throws NullPointerException if type is null 1197: * @see #getListeners(EventListener, Class) 1198: */ 1199: private void getListeners(ArrayList l, Class type) 1200: { 1201: if (a instanceof AWTEventMulticaster) 1202: ((AWTEventMulticaster) a).getListeners(l, type); 1203: else if (type.isInstance(a)) 1204: l.add(a); 1205: if (b instanceof AWTEventMulticaster) 1206: ((AWTEventMulticaster) b).getListeners(l, type); 1207: else if (type.isInstance(b)) 1208: l.add(b); 1209: } 1210: } // class AWTEventMulticaster