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