KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > widgets > TrayItem


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.swt.widgets;
12
13
14 import org.eclipse.swt.*;
15 import org.eclipse.swt.events.*;
16 import org.eclipse.swt.graphics.*;
17 import org.eclipse.swt.internal.win32.*;
18
19 /**
20  * Instances of this class represent icons that can be placed on the
21  * system tray or task bar status area.
22  * <p>
23  * <dl>
24  * <dt><b>Styles:</b></dt>
25  * <dd>(none)</dd>
26  * <dt><b>Events:</b></dt>
27  * <dd>DefaultSelection, MenuDetect, Selection</dd>
28  * </dl>
29  * </p><p>
30  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
31  * </p>
32  *
33  * @since 3.0
34  */

35 public class TrayItem extends Item {
36     Tray parent;
37     int id;
38     Image image2;
39     ToolTip toolTip;
40     String JavaDoc toolTipText;
41     boolean visible = true;
42     
43 /**
44  * Constructs a new instance of this class given its parent
45  * (which must be a <code>Tray</code>) and a style value
46  * describing its behavior and appearance. The item is added
47  * to the end of the items maintained by its parent.
48  * <p>
49  * The style value is either one of the style constants defined in
50  * class <code>SWT</code> which is applicable to instances of this
51  * class, or must be built by <em>bitwise OR</em>'ing together
52  * (that is, using the <code>int</code> "|" operator) two or more
53  * of those <code>SWT</code> style constants. The class description
54  * lists the style constants that are applicable to the class.
55  * Style bits are also inherited from superclasses.
56  * </p>
57  *
58  * @param parent a composite control which will be the parent of the new instance (cannot be null)
59  * @param style the style of control to construct
60  *
61  * @exception IllegalArgumentException <ul>
62  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
63  * </ul>
64  * @exception SWTException <ul>
65  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
66  * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
67  * </ul>
68  *
69  * @see SWT
70  * @see Widget#checkSubclass
71  * @see Widget#getStyle
72  */

73 public TrayItem (Tray parent, int style) {
74     super (parent, style);
75     this.parent = parent;
76     parent.createItem (this, parent.getItemCount ());
77     createWidget ();
78 }
79
80 /**
81  * Adds the listener to the collection of listeners who will
82  * be notified when the receiver is selected by the user, by sending
83  * it one of the messages defined in the <code>SelectionListener</code>
84  * interface.
85  * <p>
86  * <code>widgetSelected</code> is called when the receiver is selected
87  * <code>widgetDefaultSelected</code> is called when the receiver is double-clicked
88  * </p>
89  *
90  * @param listener the listener which should be notified when the receiver is selected by the user
91  *
92  * @exception IllegalArgumentException <ul>
93  * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
94  * </ul>
95  * @exception SWTException <ul>
96  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
97  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
98  * </ul>
99  *
100  * @see SelectionListener
101  * @see #removeSelectionListener
102  * @see SelectionEvent
103  */

104 public void addSelectionListener(SelectionListener listener) {
105     checkWidget ();
106     if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
107     TypedListener typedListener = new TypedListener (listener);
108     addListener (SWT.Selection,typedListener);
109     addListener (SWT.DefaultSelection,typedListener);
110 }
111
112 /**
113  * Adds the listener to the collection of listeners who will
114  * be notified when the platform-specific context menu trigger
115  * has occurred, by sending it one of the messages defined in
116  * the <code>MenuDetectListener</code> interface.
117  *
118  * @param listener the listener which should be notified
119  *
120  * @exception IllegalArgumentException <ul>
121  * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
122  * </ul>
123  * @exception SWTException <ul>
124  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
125  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
126  * </ul>
127  *
128  * @see MenuDetectListener
129  * @see #removeMenuDetectListener
130  *
131  * @since 3.3
132  */

133 public void addMenuDetectListener (MenuDetectListener listener) {
134     checkWidget ();
135     if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
136     TypedListener typedListener = new TypedListener (listener);
137     addListener (SWT.MenuDetect, typedListener);
138 }
139
140 protected void checkSubclass () {
141     if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
142 }
143
144 void createWidget () {
145     NOTIFYICONDATA iconData = OS.IsUnicode ? (NOTIFYICONDATA) new NOTIFYICONDATAW () : new NOTIFYICONDATAA ();
146     iconData.cbSize = NOTIFYICONDATA.sizeof;
147     iconData.uID = id = display.nextTrayId++;
148     iconData.hWnd = display.hwndMessage;
149     iconData.uFlags = OS.NIF_MESSAGE;
150     iconData.uCallbackMessage = Display.SWT_TRAYICONMSG;
151     OS.Shell_NotifyIcon (OS.NIM_ADD, iconData);
152 }
153
154 void destroyWidget () {
155     parent.destroyItem (this);
156     releaseHandle ();
157 }
158
159 /**
160  * Returns the receiver's parent, which must be a <code>Tray</code>.
161  *
162  * @return the receiver's parent
163  *
164  * @exception SWTException <ul>
165  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
166  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
167  * </ul>
168  *
169  * @since 3.2
170  */

171 public Tray getParent () {
172     checkWidget ();
173     return parent;
174 }
175
176 /**
177  * Returns the receiver's tool tip, or null if it has
178  * not been set.
179  *
180  * @return the receiver's tool tip text
181  *
182  * @exception SWTException <ul>
183  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
184  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
185  * </ul>
186  *
187  * @since 3.2
188  */

189 public ToolTip getToolTip () {
190     checkWidget ();
191     return toolTip;
192 }
193
194 /**
195  * Returns the receiver's tool tip text, or null if it has
196  * not been set.
197  *
198  * @return the receiver's tool tip text
199  *
200  * @exception SWTException <ul>
201  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
202  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
203  * </ul>
204  */

205 public String JavaDoc getToolTipText () {
206     checkWidget ();
207     return toolTipText;
208 }
209
210 /**
211  * Returns <code>true</code> if the receiver is visible and
212  * <code>false</code> otherwise.
213  *
214  * @return the receiver's visibility
215  *
216  * @exception SWTException <ul>
217  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
218  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
219  * </ul>
220  */

221 public boolean getVisible () {
222     checkWidget ();
223     return visible;
224 }
225
226 int messageProc (int hwnd, int msg, int wParam, int lParam) {
227     /*
228     * Feature in Windows. When the user clicks on the tray
229     * icon, another application may be the foreground window.
230     * This means that the event loop is not running and can
231     * cause problems. For example, if a menu is shown, when
232     * the user clicks outside of the menu to cancel it, the
233     * menu is not hidden until an event is processed. If
234     * another application is the foreground window, then the
235     * menu is not hidden. The fix is to force the tray icon
236     * message window to the foreground when sending an event.
237     */

238     switch (lParam) {
239         case OS.WM_LBUTTONDOWN:
240             if (hooks (SWT.Selection)) {
241                 OS.SetForegroundWindow (hwnd);
242                 postEvent (SWT.Selection);
243             }
244             break;
245         case OS.WM_LBUTTONDBLCLK:
246         case OS.WM_RBUTTONDBLCLK:
247             if (hooks (SWT.DefaultSelection)) {
248                 OS.SetForegroundWindow (hwnd);
249                 postEvent (SWT.DefaultSelection);
250             }
251             break;
252         case OS.WM_RBUTTONUP: {
253             if (hooks (SWT.MenuDetect)) {
254                 OS.SetForegroundWindow (hwnd);
255                 sendEvent (SWT.MenuDetect);
256                 // widget could be disposed at this point
257
if (isDisposed()) return 0;
258             }
259             break;
260         }
261         case OS.NIN_BALLOONSHOW:
262             if (toolTip != null && !toolTip.visible) {
263                 toolTip.visible = true;
264                 if (toolTip.hooks (SWT.Show)) {
265                     OS.SetForegroundWindow (hwnd);
266                     toolTip.sendEvent (SWT.Show);
267                     // widget could be disposed at this point
268
if (isDisposed()) return 0;
269                 }
270             }
271             break;
272         case OS.NIN_BALLOONHIDE:
273         case OS.NIN_BALLOONTIMEOUT:
274         case OS.NIN_BALLOONUSERCLICK:
275             if (toolTip != null) {
276                 if (toolTip.visible) {
277                     toolTip.visible = false;
278                     if (toolTip.hooks (SWT.Hide)) {
279                         OS.SetForegroundWindow (hwnd);
280                         toolTip.sendEvent (SWT.Hide);
281                         // widget could be disposed at this point
282
if (isDisposed()) return 0;
283                     }
284                 }
285                 if (lParam == OS.NIN_BALLOONUSERCLICK) {
286                     if (toolTip.hooks (SWT.Selection)) {
287                         OS.SetForegroundWindow (hwnd);
288                         toolTip.postEvent (SWT.Selection);
289                         // widget could be disposed at this point
290
if (isDisposed()) return 0;
291                     }
292                 }
293             }
294             break;
295     }
296     display.wakeThread ();
297     return 0;
298 }
299
300 void recreate () {
301     createWidget ();
302     if (!visible) setVisible (false);
303     if (text.length () != 0) setText (text);
304     if (image != null) setImage (image);
305     if (toolTipText != null) setToolTipText (toolTipText);
306 }
307
308 void releaseHandle () {
309     super.releaseHandle ();
310     parent = null;
311 }
312
313 void releaseWidget () {
314     super.releaseWidget ();
315     if (toolTip != null) toolTip.item = null;
316     toolTip = null;
317     if (image2 != null) image2.dispose ();
318     image2 = null;
319     toolTipText = null;
320     NOTIFYICONDATA iconData = OS.IsUnicode ? (NOTIFYICONDATA) new NOTIFYICONDATAW () : new NOTIFYICONDATAA ();
321     iconData.cbSize = NOTIFYICONDATA.sizeof;
322     iconData.uID = id;
323     iconData.hWnd = display.hwndMessage;
324     OS.Shell_NotifyIcon (OS.NIM_DELETE, iconData);
325 }
326     
327 /**
328  * Removes the listener from the collection of listeners who will
329  * be notified when the receiver is selected by the user.
330  *
331  * @param listener the listener which should no longer be notified
332  *
333  * @exception IllegalArgumentException <ul>
334  * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
335  * </ul>
336  * @exception SWTException <ul>
337  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
338  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
339  * </ul>
340  *
341  * @see SelectionListener
342  * @see #addSelectionListener
343  */

344 public void removeSelectionListener(SelectionListener listener) {
345     checkWidget ();
346     if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
347     if (eventTable == null) return;
348     eventTable.unhook (SWT.Selection, listener);
349     eventTable.unhook (SWT.DefaultSelection,listener);
350 }
351
352 /**
353  * Removes the listener from the collection of listeners who will
354  * be notified when the platform-specific context menu trigger has
355  * occurred.
356  *
357  * @param listener the listener which should no longer be notified
358  *
359  * @exception IllegalArgumentException <ul>
360  * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
361  * </ul>
362  * @exception SWTException <ul>
363  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
364  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
365  * </ul>
366  *
367  * @see MenuDetectListener
368  * @see #addMenuDetectListener
369  *
370  * @since 3.3
371  */

372 public void removeMenuDetectListener (MenuDetectListener listener) {
373     checkWidget ();
374     if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
375     if (eventTable == null) return;
376     eventTable.unhook (SWT.MenuDetect, listener);
377 }
378
379 /**
380  * Sets the receiver's image.
381  *
382  * @param image the new image
383  *
384  * @exception IllegalArgumentException <ul>
385  * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
386  * </ul>
387  * @exception SWTException <ul>
388  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
389  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
390  * </ul>
391  */

392 public void setImage (Image image) {
393     checkWidget ();
394     if (image != null && image.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
395     super.setImage (image);
396     if (image2 != null) image2.dispose ();
397     image2 = null;
398     int hIcon = 0;
399     Image icon = image;
400     if (icon != null) {
401         switch (icon.type) {
402             case SWT.BITMAP:
403                 image2 = Display.createIcon (image);
404                 hIcon = image2.handle;
405                 break;
406             case SWT.ICON:
407                 hIcon = icon.handle;
408                 break;
409         }
410     }
411     NOTIFYICONDATA iconData = OS.IsUnicode ? (NOTIFYICONDATA) new NOTIFYICONDATAW () : new NOTIFYICONDATAA ();
412     iconData.cbSize = NOTIFYICONDATA.sizeof;
413     iconData.uID = id;
414     iconData.hWnd = display.hwndMessage;
415     iconData.hIcon = hIcon;
416     iconData.uFlags = OS.NIF_ICON;
417     OS.Shell_NotifyIcon (OS.NIM_MODIFY, iconData);
418 }
419
420 /**
421  * Sets the receiver's tool tip to the argument, which
422  * may be null indicating that no tool tip should be shown.
423  *
424  * @param toolTip the new tool tip (or null)
425  *
426  * @exception SWTException <ul>
427  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
428  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
429  * </ul>
430  *
431  * @since 3.2
432  */

433 public void setToolTip (ToolTip toolTip) {
434     checkWidget ();
435     ToolTip oldTip = this.toolTip, newTip = toolTip;
436     if (oldTip != null) oldTip.item = null;
437     this.toolTip = newTip;
438     if (newTip != null) newTip.item = this;
439 }
440
441 /**
442  * Sets the receiver's tool tip text to the argument, which
443  * may be null indicating that no tool tip text should be shown.
444  *
445  * @param value the new tool tip text (or null)
446  *
447  * @exception SWTException <ul>
448  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
449  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
450  * </ul>
451  */

452 public void setToolTipText (String JavaDoc value) {
453     checkWidget ();
454     toolTipText = value;
455     NOTIFYICONDATA iconData = OS.IsUnicode ? (NOTIFYICONDATA) new NOTIFYICONDATAW () : new NOTIFYICONDATAA ();
456     TCHAR buffer = new TCHAR (0, toolTipText == null ? "" : toolTipText, true);
457     /*
458     * Note that the size of the szTip field is different in version 5.0 of shell32.dll.
459     */

460     int length = OS.SHELL32_MAJOR < 5 ? 64 : 128;
461     if (OS.IsUnicode) {
462         char [] szTip = ((NOTIFYICONDATAW) iconData).szTip;
463         length = Math.min (length - 1, buffer.length ());
464         System.arraycopy (buffer.chars, 0, szTip, 0, length);
465     } else {
466         byte [] szTip = ((NOTIFYICONDATAA) iconData).szTip;
467         length = Math.min (length - 1, buffer.length ());
468         System.arraycopy (buffer.bytes, 0, szTip, 0, length);
469     }
470     iconData.cbSize = NOTIFYICONDATA.sizeof;
471     iconData.uID = id;
472     iconData.hWnd = display.hwndMessage;
473     iconData.uFlags = OS.NIF_TIP;
474     OS.Shell_NotifyIcon (OS.NIM_MODIFY, iconData);
475 }
476
477 /**
478  * Makes the receiver visible if the argument is <code>true</code>,
479  * and makes it invisible otherwise.
480  *
481  * @param visible the new visibility state
482  *
483  * @exception SWTException <ul>
484  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
485  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
486  * </ul>
487  */

488 public void setVisible (boolean visible) {
489     checkWidget ();
490     if (this.visible == visible) return;
491     if (visible) {
492         /*
493         * It is possible (but unlikely), that application
494         * code could have disposed the widget in the show
495         * event. If this happens, just return.
496         */

497         sendEvent (SWT.Show);
498         if (isDisposed ()) return;
499     }
500     this.visible = visible;
501     NOTIFYICONDATA iconData = OS.IsUnicode ? (NOTIFYICONDATA) new NOTIFYICONDATAW () : new NOTIFYICONDATAA ();
502     iconData.cbSize = NOTIFYICONDATA.sizeof;
503     iconData.uID = id;
504     iconData.hWnd = display.hwndMessage;
505     if (OS.SHELL32_MAJOR < 5) {
506         if (visible) {
507             iconData.uFlags = OS.NIF_MESSAGE;
508             iconData.uCallbackMessage = Display.SWT_TRAYICONMSG;
509             OS.Shell_NotifyIcon (OS.NIM_ADD, iconData);
510             setImage (image);
511             setToolTipText (toolTipText);
512         } else {
513             OS.Shell_NotifyIcon (OS.NIM_DELETE, iconData);
514         }
515     } else {
516         iconData.uFlags = OS.NIF_STATE;
517         iconData.dwState = visible ? 0 : OS.NIS_HIDDEN;
518         iconData.dwStateMask = OS.NIS_HIDDEN;
519         OS.Shell_NotifyIcon (OS.NIM_MODIFY, iconData);
520     }
521     if (!visible) sendEvent (SWT.Hide);
522 }
523
524 }
525
Popular Tags