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., 59 Temple Place, Suite 330, Boston, MA 19 02111-1307 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 */ AWTEventMulticaster(EventListener a, EventListener b)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 */ remove(EventListener oldl)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 event the event to handle 185 */ componentResized(ComponentEvent e)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 event the event to handle 197 */ componentMoved(ComponentEvent e)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 event the event to handle 209 */ componentShown(ComponentEvent e)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 event the event to handle 221 */ componentHidden(ComponentEvent e)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 event the event to handle 233 */ componentAdded(ContainerEvent e)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 event the event to handle 245 */ componentRemoved(ContainerEvent e)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 event the event to handle 257 */ focusGained(FocusEvent e)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 event the event to handle 269 */ focusLost(FocusEvent e)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 event the event to handle 281 */ keyTyped(KeyEvent e)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 event the event to handle 293 */ keyPressed(KeyEvent e)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 event the event to handle 305 */ keyReleased(KeyEvent e)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 event the event to handle 317 */ mouseClicked(MouseEvent e)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 event the event to handle 329 */ mousePressed(MouseEvent e)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 event the event to handle 341 */ mouseReleased(MouseEvent e)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 event the event to handle 353 */ mouseEntered(MouseEvent e)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 event the event to handle 365 */ mouseExited(MouseEvent e)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 event the event to handle 377 */ mouseDragged(MouseEvent e)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 event the event to handle 389 */ mouseMoved(MouseEvent e)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 event the event to handle 401 */ windowOpened(WindowEvent e)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 event the event to handle 413 */ windowClosing(WindowEvent e)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 event the event to handle 425 */ windowClosed(WindowEvent e)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 event the event to handle 437 */ windowIconified(WindowEvent e)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 event the event to handle 449 */ windowDeiconified(WindowEvent e)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 event the event to handle 461 */ windowActivated(WindowEvent e)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 event the event to handle 473 */ windowDeactivated(WindowEvent e)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 event the event to handle 485 * @since 1.4 486 */ windowStateChanged(WindowEvent e)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 event the event to handle 498 * @since 1.4 499 */ windowGainedFocus(WindowEvent e)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 event the event to handle 511 * @since 1.4 512 */ windowLostFocus(WindowEvent e)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 event the event to handle 524 */ actionPerformed(ActionEvent e)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 event the event to handle 536 */ itemStateChanged(ItemEvent e)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 event the event to handle 548 */ adjustmentValueChanged(AdjustmentEvent e)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 event the event to handle 560 */ textValueChanged(TextEvent e)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 event the event to handle 572 * @since 1.2 573 */ inputMethodTextChanged(InputMethodEvent e)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 event the event to handle 585 * @since 1.2 586 */ caretPositionChanged(InputMethodEvent e)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 event the event to handle 598 * @since 1.3 599 */ hierarchyChanged(HierarchyEvent e)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 event the event to handle 611 * @since 1.3 612 */ ancestorMoved(HierarchyEvent e)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 event the event to handle 624 * @since 1.3 625 */ ancestorResized(HierarchyEvent e)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 event the event to handle 637 * @since 1.4 638 */ mouseWheelMoved(MouseWheelEvent e)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 */ add(ComponentListener a, ComponentListener b)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 */ add(ContainerListener a, ContainerListener b)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 */ add(FocusListener a, FocusListener b)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 */ add(KeyListener a, KeyListener b)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 */ add(MouseListener a, MouseListener b)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 */ add(MouseMotionListener a, MouseMotionListener b)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 */ add(WindowListener a, WindowListener b)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 */ add(WindowStateListener a, WindowStateListener b)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 */ add(WindowFocusListener a, WindowFocusListener b)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 */ add(ActionListener a, ActionListener b)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 */ add(ItemListener a, ItemListener b)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 */ add(AdjustmentListener a, AdjustmentListener b)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 */ add(TextListener a, TextListener b)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 */ add(InputMethodListener a, InputMethodListener b)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 */ add(HierarchyListener a, HierarchyListener b)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 */ add(HierarchyBoundsListener a, HierarchyBoundsListener b)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 */ add(MouseWheelListener a, MouseWheelListener b)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 */ remove(ComponentListener l, ComponentListener oldl)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 */ remove(ContainerListener l, ContainerListener oldl)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 */ remove(FocusListener l, FocusListener oldl)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 */ remove(KeyListener l, KeyListener oldl)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 */ remove(MouseListener l, MouseListener oldl)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 */ remove(MouseMotionListener l, MouseMotionListener oldl)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 */ remove(WindowListener l, WindowListener oldl)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 */ remove(WindowStateListener l, WindowStateListener oldl)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 */ remove(WindowFocusListener l, WindowFocusListener oldl)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 */ remove(ActionListener l, ActionListener oldl)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 */ remove(ItemListener l, ItemListener oldl)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 */ remove(AdjustmentListener l, AdjustmentListener oldl)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 */ remove(TextListener l, TextListener oldl)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 */ remove(InputMethodListener l, InputMethodListener oldl)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 */ remove(HierarchyListener l, HierarchyListener oldl)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 */ remove(HierarchyBoundsListener l, HierarchyBoundsListener oldl)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 */ remove(MouseWheelListener l, MouseWheelListener oldl)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 */ addInternal(EventListener a, EventListener b)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 */ removeInternal(EventListener l, EventListener oldl)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 */ saveInternal(ObjectOutputStream s, String k)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 */ save(ObjectOutputStream s, String k, EventListener l)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 */ getListeners(EventListener l, Class type)1178 public static EventListener[] getListeners(EventListener l, Class type) 1179 { 1180 ArrayList list = new ArrayList(); 1181 if (l instanceof AWTEventMulticaster) 1182 ((AWTEventMulticaster) l).getListeners(list, type); 1183 else if (type.isInstance(l)) 1184 list.add(l); 1185 EventListener[] r = (EventListener[]) Array.newInstance(type, list.size()); 1186 list.toArray(r); 1187 return r; 1188 } 1189 1190 /** 1191 * Collects all instances of the given type in the chain into the list. 1192 * 1193 * @param l the list to collect into 1194 * @param type the type of listeners to collect 1195 * @throws NullPointerException if type is null 1196 * @see #getListeners(EventListener, Class) 1197 */ getListeners(ArrayList l, Class type)1198 private void getListeners(ArrayList l, Class type) 1199 { 1200 if (a instanceof AWTEventMulticaster) 1201 ((AWTEventMulticaster) a).getListeners(l, type); 1202 else if (type.isInstance(a)) 1203 l.add(a); 1204 if (b instanceof AWTEventMulticaster) 1205 ((AWTEventMulticaster) b).getListeners(l, type); 1206 else if (type.isInstance(b)) 1207 l.add(b); 1208 } 1209 } // class AWTEventMulticaster 1210