1 /* 2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.awt; 27 28 import java.awt.event.*; 29 import java.awt.peer.TrayIconPeer; 30 import sun.awt.AppContext; 31 import sun.awt.SunToolkit; 32 import sun.awt.AWTAccessor; 33 import sun.awt.HeadlessToolkit; 34 import java.util.EventObject; 35 import java.security.AccessControlContext; 36 import java.security.AccessController; 37 38 /** 39 * A {@code TrayIcon} object represents a tray icon that can be 40 * added to the {@link SystemTray system tray}. A 41 * {@code TrayIcon} can have a tooltip (text), an image, a popup 42 * menu, and a set of listeners associated with it. 43 * 44 * <p>A {@code TrayIcon} can generate various {@link MouseEvent 45 * MouseEvents} and supports adding corresponding listeners to receive 46 * notification of these events. {@code TrayIcon} processes some 47 * of the events by itself. For example, by default, when the 48 * right-mouse click is performed on the {@code TrayIcon} it 49 * displays the specified popup menu. When the mouse hovers 50 * over the {@code TrayIcon} the tooltip is displayed. 51 * 52 * <p><strong>Note:</strong> When the {@code MouseEvent} is 53 * dispatched to its registered listeners its {@code component} 54 * property will be set to {@code null}. (See {@link 55 * java.awt.event.ComponentEvent#getComponent}) The 56 * {@code source} property will be set to this 57 * {@code TrayIcon}. (See {@link 58 * java.util.EventObject#getSource}) 59 * 60 * <p><b>Note:</b> A well-behaved {@link TrayIcon} implementation 61 * will assign different gestures to showing a popup menu and 62 * selecting a tray icon. 63 * 64 * <p>A {@code TrayIcon} can generate an {@link ActionEvent 65 * ActionEvent}. On some platforms, this occurs when the user selects 66 * the tray icon using either the mouse or keyboard. 67 * 68 * <p>If a SecurityManager is installed, the AWTPermission 69 * {@code accessSystemTray} must be granted in order to create 70 * a {@code TrayIcon}. Otherwise the constructor will throw a 71 * SecurityException. 72 * 73 * <p> See the {@link SystemTray} class overview for an example on how 74 * to use the {@code TrayIcon} API. 75 * 76 * @since 1.6 77 * @see SystemTray#add 78 * @see java.awt.event.ComponentEvent#getComponent 79 * @see java.util.EventObject#getSource 80 * 81 * @author Bino George 82 * @author Denis Mikhalkin 83 * @author Sharon Zakhour 84 * @author Anton Tarasov 85 */ 86 public class TrayIcon { 87 88 private Image image; 89 private String tooltip; 90 private PopupMenu popup; 91 private boolean autosize; 92 private int id; 93 private String actionCommand; 94 95 private transient TrayIconPeer peer; 96 97 transient MouseListener mouseListener; 98 transient MouseMotionListener mouseMotionListener; 99 transient ActionListener actionListener; 100 101 /* 102 * The tray icon's AccessControlContext. 103 * 104 * Unlike the acc in Component, this field is made final 105 * because TrayIcon is not serializable. 106 */ 107 private final AccessControlContext acc = AccessController.getContext(); 108 109 /* 110 * Returns the acc this tray icon was constructed with. 111 */ 112 final AccessControlContext getAccessControlContext() { 113 if (acc == null) { 114 throw new SecurityException("TrayIcon is missing AccessControlContext"); 115 } 116 return acc; 117 } 118 119 static { 120 Toolkit.loadLibraries(); 121 if (!GraphicsEnvironment.isHeadless()) { 122 initIDs(); 123 } 124 125 AWTAccessor.setTrayIconAccessor( 126 new AWTAccessor.TrayIconAccessor() { 127 public void addNotify(TrayIcon trayIcon) throws AWTException { 128 trayIcon.addNotify(); 129 } 130 public void removeNotify(TrayIcon trayIcon) { 131 trayIcon.removeNotify(); 132 } 133 }); 134 } 135 136 private TrayIcon() 137 throws UnsupportedOperationException, HeadlessException, SecurityException 138 { 139 SystemTray.checkSystemTrayAllowed(); 140 if (GraphicsEnvironment.isHeadless()) { 141 throw new HeadlessException(); 142 } 143 if (!SystemTray.isSupported()) { 144 throw new UnsupportedOperationException(); 145 } 146 SunToolkit.insertTargetMapping(this, AppContext.getAppContext()); 147 } 148 149 /** 150 * Creates a {@code TrayIcon} with the specified image. 151 * 152 * @param image the {@code Image} to be used 153 * @throws IllegalArgumentException if {@code image} is 154 * {@code null} 155 * @throws UnsupportedOperationException if the system tray isn't 156 * supported by the current platform 157 * @throws HeadlessException if 158 * {@code GraphicsEnvironment.isHeadless()} returns {@code true} 159 * @throws SecurityException if {@code accessSystemTray} permission 160 * is not granted 161 * @see SystemTray#add(TrayIcon) 162 * @see TrayIcon#TrayIcon(Image, String, PopupMenu) 163 * @see TrayIcon#TrayIcon(Image, String) 164 * @see SecurityManager#checkPermission 165 * @see AWTPermission 166 */ 167 public TrayIcon(Image image) { 168 this(); 169 if (image == null) { 170 throw new IllegalArgumentException("creating TrayIcon with null Image"); 171 } 172 setImage(image); 173 } 174 175 /** 176 * Creates a {@code TrayIcon} with the specified image and 177 * tooltip text. 178 * 179 * @param image the {@code Image} to be used 180 * @param tooltip the string to be used as tooltip text; if the 181 * value is {@code null} no tooltip is shown 182 * @throws IllegalArgumentException if {@code image} is 183 * {@code null} 184 * @throws UnsupportedOperationException if the system tray isn't 185 * supported by the current platform 186 * @throws HeadlessException if 187 * {@code GraphicsEnvironment.isHeadless()} returns {@code true} 188 * @throws SecurityException if {@code accessSystemTray} permission 189 * is not granted 190 * @see SystemTray#add(TrayIcon) 191 * @see TrayIcon#TrayIcon(Image) 192 * @see TrayIcon#TrayIcon(Image, String, PopupMenu) 193 * @see SecurityManager#checkPermission 194 * @see AWTPermission 195 */ 196 public TrayIcon(Image image, String tooltip) { 197 this(image); 198 setToolTip(tooltip); 199 } 200 201 /** 202 * Creates a {@code TrayIcon} with the specified image, 203 * tooltip and popup menu. 204 * 205 * @param image the {@code Image} to be used 206 * @param tooltip the string to be used as tooltip text; if the 207 * value is {@code null} no tooltip is shown 208 * @param popup the menu to be used for the tray icon's popup 209 * menu; if the value is {@code null} no popup menu is shown 210 * @throws IllegalArgumentException if {@code image} is {@code null} 211 * @throws UnsupportedOperationException if the system tray isn't 212 * supported by the current platform 213 * @throws HeadlessException if 214 * {@code GraphicsEnvironment.isHeadless()} returns {@code true} 215 * @throws SecurityException if {@code accessSystemTray} permission 216 * is not granted 217 * @see SystemTray#add(TrayIcon) 218 * @see TrayIcon#TrayIcon(Image, String) 219 * @see TrayIcon#TrayIcon(Image) 220 * @see PopupMenu 221 * @see MouseListener 222 * @see #addMouseListener(MouseListener) 223 * @see SecurityManager#checkPermission 224 * @see AWTPermission 225 */ 226 public TrayIcon(Image image, String tooltip, PopupMenu popup) { 227 this(image, tooltip); 228 setPopupMenu(popup); 229 } 230 231 /** 232 * Sets the image for this {@code TrayIcon}. The previous 233 * tray icon image is discarded without calling the {@link 234 * java.awt.Image#flush} method — you will need to call it 235 * manually. 236 * 237 * <p> If the image represents an animated image, it will be 238 * animated automatically. 239 * 240 * <p> See the {@link #setImageAutoSize(boolean)} property for 241 * details on the size of the displayed image. 242 * 243 * <p> Calling this method with the same image that is currently 244 * being used has no effect. 245 * 246 * @throws NullPointerException if {@code image} is {@code null} 247 * @param image the non-null {@code Image} to be used 248 * @see #getImage 249 * @see Image 250 * @see SystemTray#add(TrayIcon) 251 * @see TrayIcon#TrayIcon(Image, String) 252 */ 253 public void setImage(Image image) { 254 if (image == null) { 255 throw new NullPointerException("setting null Image"); 256 } 257 this.image = image; 258 259 TrayIconPeer peer = this.peer; 260 if (peer != null) { 261 peer.updateImage(); 262 } 263 } 264 265 /** 266 * Returns the current image used for this {@code TrayIcon}. 267 * 268 * @return the image 269 * @see #setImage(Image) 270 * @see Image 271 */ 272 public Image getImage() { 273 return image; 274 } 275 276 /** 277 * Sets the popup menu for this {@code TrayIcon}. If 278 * {@code popup} is {@code null}, no popup menu will be 279 * associated with this {@code TrayIcon}. 280 * 281 * <p>Note that this {@code popup} must not be added to any 282 * parent before or after it is set on the tray icon. If you add 283 * it to some parent, the {@code popup} may be removed from 284 * that parent. 285 * 286 * <p>The {@code popup} can be set on one {@code TrayIcon} only. 287 * Setting the same popup on multiple {@code TrayIcon}s will cause 288 * an {@code IllegalArgumentException}. 289 * 290 * <p><strong>Note:</strong> Some platforms may not support 291 * showing the user-specified popup menu component when the user 292 * right-clicks the tray icon. In this situation, either no menu 293 * will be displayed or, on some systems, a native version of the 294 * menu may be displayed. 295 * 296 * @throws IllegalArgumentException if the {@code popup} is already 297 * set for another {@code TrayIcon} 298 * @param popup a {@code PopupMenu} or {@code null} to 299 * remove any popup menu 300 * @see #getPopupMenu 301 */ 302 public void setPopupMenu(PopupMenu popup) { 303 if (popup == this.popup) { 304 return; 305 } 306 synchronized (TrayIcon.class) { 307 if (popup != null) { 308 if (popup.isTrayIconPopup) { 309 throw new IllegalArgumentException("the PopupMenu is already set for another TrayIcon"); 310 } 311 popup.isTrayIconPopup = true; 312 } 313 if (this.popup != null) { 314 this.popup.isTrayIconPopup = false; 315 } 316 this.popup = popup; 317 } 318 } 319 320 /** 321 * Returns the popup menu associated with this {@code TrayIcon}. 322 * 323 * @return the popup menu or {@code null} if none exists 324 * @see #setPopupMenu(PopupMenu) 325 */ 326 public PopupMenu getPopupMenu() { 327 return popup; 328 } 329 330 /** 331 * Sets the tooltip string for this {@code TrayIcon}. The 332 * tooltip is displayed automatically when the mouse hovers over 333 * the icon. Setting the tooltip to {@code null} removes any 334 * tooltip text. 335 * 336 * When displayed, the tooltip string may be truncated on some platforms; 337 * the number of characters that may be displayed is platform-dependent. 338 * 339 * @param tooltip the string for the tooltip; if the value is 340 * {@code null} no tooltip is shown 341 * @see #getToolTip 342 */ 343 public void setToolTip(String tooltip) { 344 this.tooltip = tooltip; 345 346 TrayIconPeer peer = this.peer; 347 if (peer != null) { 348 peer.setToolTip(tooltip); 349 } 350 } 351 352 /** 353 * Returns the tooltip string associated with this 354 * {@code TrayIcon}. 355 * 356 * @return the tooltip string or {@code null} if none exists 357 * @see #setToolTip(String) 358 */ 359 public String getToolTip() { 360 return tooltip; 361 } 362 363 /** 364 * Sets the auto-size property. Auto-size determines whether the 365 * tray image is automatically sized to fit the space allocated 366 * for the image on the tray. By default, the auto-size property 367 * is set to {@code false}. 368 * 369 * <p> If auto-size is {@code false}, and the image size 370 * doesn't match the tray icon space, the image is painted as-is 371 * inside that space — if larger than the allocated space, it will 372 * be cropped. 373 * 374 * <p> If auto-size is {@code true}, the image is stretched or shrunk to 375 * fit the tray icon space. 376 * 377 * @param autosize {@code true} to auto-size the image, 378 * {@code false} otherwise 379 * @see #isImageAutoSize 380 */ 381 public void setImageAutoSize(boolean autosize) { 382 this.autosize = autosize; 383 384 TrayIconPeer peer = this.peer; 385 if (peer != null) { 386 peer.updateImage(); 387 } 388 } 389 390 /** 391 * Returns the value of the auto-size property. 392 * 393 * @return {@code true} if the image will be auto-sized, 394 * {@code false} otherwise 395 * @see #setImageAutoSize(boolean) 396 */ 397 public boolean isImageAutoSize() { 398 return autosize; 399 } 400 401 /** 402 * Adds the specified mouse listener to receive mouse events from 403 * this {@code TrayIcon}. Calling this method with a 404 * {@code null} value has no effect. 405 * 406 * <p><b>Note</b>: The {@code MouseEvent}'s coordinates (received 407 * from the {@code TrayIcon}) are relative to the screen, not the 408 * {@code TrayIcon}. 409 * 410 * <p> <b>Note: </b>The {@code MOUSE_ENTERED} and 411 * {@code MOUSE_EXITED} mouse events are not supported. 412 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 413 * >AWT Threading Issues</a> for details on AWT's threading model. 414 * 415 * @param listener the mouse listener 416 * @see java.awt.event.MouseEvent 417 * @see java.awt.event.MouseListener 418 * @see #removeMouseListener(MouseListener) 419 * @see #getMouseListeners 420 */ 421 public synchronized void addMouseListener(MouseListener listener) { 422 if (listener == null) { 423 return; 424 } 425 mouseListener = AWTEventMulticaster.add(mouseListener, listener); 426 } 427 428 /** 429 * Removes the specified mouse listener. Calling this method with 430 * {@code null} or an invalid value has no effect. 431 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 432 * >AWT Threading Issues</a> for details on AWT's threading model. 433 * 434 * @param listener the mouse listener 435 * @see java.awt.event.MouseEvent 436 * @see java.awt.event.MouseListener 437 * @see #addMouseListener(MouseListener) 438 * @see #getMouseListeners 439 */ 440 public synchronized void removeMouseListener(MouseListener listener) { 441 if (listener == null) { 442 return; 443 } 444 mouseListener = AWTEventMulticaster.remove(mouseListener, listener); 445 } 446 447 /** 448 * Returns an array of all the mouse listeners 449 * registered on this {@code TrayIcon}. 450 * 451 * @return all of the {@code MouseListeners} registered on 452 * this {@code TrayIcon} or an empty array if no mouse 453 * listeners are currently registered 454 * 455 * @see #addMouseListener(MouseListener) 456 * @see #removeMouseListener(MouseListener) 457 * @see java.awt.event.MouseListener 458 */ 459 public synchronized MouseListener[] getMouseListeners() { 460 return AWTEventMulticaster.getListeners(mouseListener, MouseListener.class); 461 } 462 463 /** 464 * Adds the specified mouse listener to receive mouse-motion 465 * events from this {@code TrayIcon}. Calling this method 466 * with a {@code null} value has no effect. 467 * 468 * <p><b>Note</b>: The {@code MouseEvent}'s coordinates (received 469 * from the {@code TrayIcon}) are relative to the screen, not the 470 * {@code TrayIcon}. 471 * 472 * <p> <b>Note: </b>The {@code MOUSE_DRAGGED} mouse event is not supported. 473 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 474 * >AWT Threading Issues</a> for details on AWT's threading model. 475 * 476 * @param listener the mouse listener 477 * @see java.awt.event.MouseEvent 478 * @see java.awt.event.MouseMotionListener 479 * @see #removeMouseMotionListener(MouseMotionListener) 480 * @see #getMouseMotionListeners 481 */ 482 public synchronized void addMouseMotionListener(MouseMotionListener listener) { 483 if (listener == null) { 484 return; 485 } 486 mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, listener); 487 } 488 489 /** 490 * Removes the specified mouse-motion listener. Calling this method with 491 * {@code null} or an invalid value has no effect. 492 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 493 * >AWT Threading Issues</a> for details on AWT's threading model. 494 * 495 * @param listener the mouse listener 496 * @see java.awt.event.MouseEvent 497 * @see java.awt.event.MouseMotionListener 498 * @see #addMouseMotionListener(MouseMotionListener) 499 * @see #getMouseMotionListeners 500 */ 501 public synchronized void removeMouseMotionListener(MouseMotionListener listener) { 502 if (listener == null) { 503 return; 504 } 505 mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, listener); 506 } 507 508 /** 509 * Returns an array of all the mouse-motion listeners 510 * registered on this {@code TrayIcon}. 511 * 512 * @return all of the {@code MouseInputListeners} registered on 513 * this {@code TrayIcon} or an empty array if no mouse 514 * listeners are currently registered 515 * 516 * @see #addMouseMotionListener(MouseMotionListener) 517 * @see #removeMouseMotionListener(MouseMotionListener) 518 * @see java.awt.event.MouseMotionListener 519 */ 520 public synchronized MouseMotionListener[] getMouseMotionListeners() { 521 return AWTEventMulticaster.getListeners(mouseMotionListener, MouseMotionListener.class); 522 } 523 524 /** 525 * Returns the command name of the action event fired by this tray icon. 526 * 527 * @return the action command name, or {@code null} if none exists 528 * @see #addActionListener(ActionListener) 529 * @see #setActionCommand(String) 530 */ 531 public String getActionCommand() { 532 return actionCommand; 533 } 534 535 /** 536 * Sets the command name for the action event fired by this tray 537 * icon. By default, this action command is set to 538 * {@code null}. 539 * 540 * @param command a string used to set the tray icon's 541 * action command. 542 * @see java.awt.event.ActionEvent 543 * @see #addActionListener(ActionListener) 544 * @see #getActionCommand 545 */ 546 public void setActionCommand(String command) { 547 actionCommand = command; 548 } 549 550 /** 551 * Adds the specified action listener to receive 552 * {@code ActionEvent}s from this {@code TrayIcon}. 553 * Action events usually occur when a user selects the tray icon, 554 * using either the mouse or keyboard. The conditions in which 555 * action events are generated are platform-dependent. 556 * 557 * <p>Calling this method with a {@code null} value has no 558 * effect. 559 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 560 * >AWT Threading Issues</a> for details on AWT's threading model. 561 * 562 * @param listener the action listener 563 * @see #removeActionListener 564 * @see #getActionListeners 565 * @see java.awt.event.ActionListener 566 * @see #setActionCommand(String) 567 */ 568 public synchronized void addActionListener(ActionListener listener) { 569 if (listener == null) { 570 return; 571 } 572 actionListener = AWTEventMulticaster.add(actionListener, listener); 573 } 574 575 /** 576 * Removes the specified action listener. Calling this method with 577 * {@code null} or an invalid value has no effect. 578 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 579 * >AWT Threading Issues</a> for details on AWT's threading model. 580 * 581 * @param listener the action listener 582 * @see java.awt.event.ActionEvent 583 * @see java.awt.event.ActionListener 584 * @see #addActionListener(ActionListener) 585 * @see #getActionListeners 586 * @see #setActionCommand(String) 587 */ 588 public synchronized void removeActionListener(ActionListener listener) { 589 if (listener == null) { 590 return; 591 } 592 actionListener = AWTEventMulticaster.remove(actionListener, listener); 593 } 594 595 /** 596 * Returns an array of all the action listeners 597 * registered on this {@code TrayIcon}. 598 * 599 * @return all of the {@code ActionListeners} registered on 600 * this {@code TrayIcon} or an empty array if no action 601 * listeners are currently registered 602 * 603 * @see #addActionListener(ActionListener) 604 * @see #removeActionListener(ActionListener) 605 * @see java.awt.event.ActionListener 606 */ 607 public synchronized ActionListener[] getActionListeners() { 608 return AWTEventMulticaster.getListeners(actionListener, ActionListener.class); 609 } 610 611 /** 612 * The message type determines which icon will be displayed in the 613 * caption of the message, and a possible system sound a message 614 * may generate upon showing. 615 * 616 * @see TrayIcon 617 * @see TrayIcon#displayMessage(String, String, MessageType) 618 * @since 1.6 619 */ 620 public enum MessageType { 621 /** An error message */ 622 ERROR, 623 /** A warning message */ 624 WARNING, 625 /** An information message */ 626 INFO, 627 /** Simple message */ 628 NONE 629 }; 630 631 /** 632 * Displays a popup message near the tray icon. The message will 633 * disappear after a time or if the user clicks on it. Clicking 634 * on the message may trigger an {@code ActionEvent}. 635 * 636 * <p>Either the caption or the text may be {@code null}, but an 637 * {@code NullPointerException} is thrown if both are 638 * {@code null}. 639 * 640 * When displayed, the caption or text strings may be truncated on 641 * some platforms; the number of characters that may be displayed is 642 * platform-dependent. 643 * 644 * <p><strong>Note:</strong> Some platforms may not support 645 * showing a message. 646 * 647 * @param caption the caption displayed above the text, usually in 648 * bold; may be {@code null} 649 * @param text the text displayed for the particular message; may be 650 * {@code null} 651 * @param messageType an enum indicating the message type 652 * @throws NullPointerException if both {@code caption} 653 * and {@code text} are {@code null} 654 */ 655 public void displayMessage(String caption, String text, MessageType messageType) { 656 if (caption == null && text == null) { 657 throw new NullPointerException("displaying the message with both caption and text being null"); 658 } 659 660 TrayIconPeer peer = this.peer; 661 if (peer != null) { 662 peer.displayMessage(caption, text, messageType.name()); 663 } 664 } 665 666 /** 667 * Returns the size, in pixels, of the space that the tray icon 668 * occupies in the system tray. For the tray icon that is not yet 669 * added to the system tray, the returned size is equal to the 670 * result of the {@link SystemTray#getTrayIconSize}. 671 * 672 * @return the size of the tray icon, in pixels 673 * @see TrayIcon#setImageAutoSize(boolean) 674 * @see java.awt.Image 675 * @see TrayIcon#getSize() 676 */ 677 public Dimension getSize() { 678 return SystemTray.getSystemTray().getTrayIconSize(); 679 } 680 681 // **************************************************************** 682 // **************************************************************** 683 684 void addNotify() 685 throws AWTException 686 { 687 synchronized (this) { 688 if (peer == null) { 689 Toolkit toolkit = Toolkit.getDefaultToolkit(); 690 if (toolkit instanceof SunToolkit) { 691 peer = ((SunToolkit)Toolkit.getDefaultToolkit()).createTrayIcon(this); 692 } else if (toolkit instanceof HeadlessToolkit) { 693 peer = ((HeadlessToolkit)Toolkit.getDefaultToolkit()).createTrayIcon(this); 694 } 695 } 696 } 697 peer.setToolTip(tooltip); 698 } 699 700 void removeNotify() { 701 TrayIconPeer p = null; 702 synchronized (this) { 703 p = peer; 704 peer = null; 705 } 706 if (p != null) { 707 p.dispose(); 708 } 709 } 710 711 void setID(int id) { 712 this.id = id; 713 } 714 715 int getID(){ 716 return id; 717 } 718 719 void dispatchEvent(AWTEvent e) { 720 EventQueue.setCurrentEventAndMostRecentTime(e); 721 Toolkit.getDefaultToolkit().notifyAWTEventListeners(e); 722 processEvent(e); 723 } 724 725 void processEvent(AWTEvent e) { 726 if (e instanceof MouseEvent) { 727 switch(e.getID()) { 728 case MouseEvent.MOUSE_PRESSED: 729 case MouseEvent.MOUSE_RELEASED: 730 case MouseEvent.MOUSE_CLICKED: 731 processMouseEvent((MouseEvent)e); 732 break; 733 case MouseEvent.MOUSE_MOVED: 734 processMouseMotionEvent((MouseEvent)e); 735 break; 736 default: 737 return; 738 } 739 } else if (e instanceof ActionEvent) { 740 processActionEvent((ActionEvent)e); 741 } 742 } 743 744 void processMouseEvent(MouseEvent e) { 745 MouseListener listener = mouseListener; 746 747 if (listener != null) { 748 int id = e.getID(); 749 switch(id) { 750 case MouseEvent.MOUSE_PRESSED: 751 listener.mousePressed(e); 752 break; 753 case MouseEvent.MOUSE_RELEASED: 754 listener.mouseReleased(e); 755 break; 756 case MouseEvent.MOUSE_CLICKED: 757 listener.mouseClicked(e); 758 break; 759 default: 760 return; 761 } 762 } 763 } 764 765 void processMouseMotionEvent(MouseEvent e) { 766 MouseMotionListener listener = mouseMotionListener; 767 if (listener != null && 768 e.getID() == MouseEvent.MOUSE_MOVED) 769 { 770 listener.mouseMoved(e); 771 } 772 } 773 774 void processActionEvent(ActionEvent e) { 775 ActionListener listener = actionListener; 776 if (listener != null) { 777 listener.actionPerformed(e); 778 } 779 } 780 781 private static native void initIDs(); 782 }