KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jdesktop > jdic > tray > internal > impl > GnomeTrayIconService


1 /*
2  * Copyright (C) 2004 Sun Microsystems, Inc. All rights reserved. Use is
3  * subject to license terms.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the Lesser GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18  * USA.
19  */

20
21 package org.jdesktop.jdic.tray.internal.impl;
22
23
24 import org.jdesktop.jdic.tray.internal.TrayIconService;
25
26 /**
27  * The <code>GnomeTrayIconService</code> interface is the contract for a Gnome
28  * TrayIcon implementation.
29  *
30  */

31
32 import java.awt.*;
33 import javax.swing.*;
34 import javax.swing.border.BevelBorder JavaDoc;
35 import javax.swing.event.PopupMenuEvent JavaDoc;
36 import javax.swing.event.PopupMenuListener JavaDoc;
37
38 import java.awt.event.*;
39 import java.util.*;
40
41
42 public class GnomeTrayIconService extends GnomeTrayAppletService
43     implements TrayIconService {
44
45     private JPopupMenu menu;
46     private JDialog popupMenuParent;
47     private IconPanel iconPanel;
48     private Icon icon;
49     private HWToolTip tooltip;
50     private BalloonMessageWindow bmw;
51     private boolean autoSize;
52
53     private LinkedList actionList = new LinkedList();
54     private LinkedList balloonListeners = new LinkedList();
55
56     public GnomeTrayIconService() {
57         super();
58         initFrame();
59     }
60     void initFrame(){
61         iconPanel = new IconPanel();
62         frame.add(iconPanel);
63         frame.setFocusable(true);
64         frame.requestFocus();
65         bmw = new BalloonMessageWindow(frame);
66         
67         initListeners();
68         
69         popupMenuParent = new JDialog(frame, "JDIC Tray Icon");
70         popupMenuParent.setUndecorated(true);
71     }
72
73     void mousePressed(final MouseEvent e) {
74         if(tooltip != null)
75             tooltip.setVisible(false);
76
77         if (e.isPopupTrigger()) {
78             if (menu != null) {
79                 Dimension d = menu.getPreferredSize();
80                 Dimension s = Toolkit.getDefaultToolkit().getScreenSize();
81                 final Point p = e.getPoint();
82                 SwingUtilities.convertPointToScreen(p, (Component) e.getSource());
83                 p.x = p.x + d.width > s.width ? p.x - d.width : p.x;
84                 p.y = p.y + d.height > s.height ? p.y - d.height : p.y;
85                 SwingUtilities.convertPointFromScreen(p, popupMenuParent);
86                 popupMenuParent.setVisible(true);
87                 SwingUtilities.invokeLater(new Runnable JavaDoc(){
88                     public void run(){
89                         menu.show(popupMenuParent.getContentPane(), p.x, p.y);
90                         popupMenuParent.toFront();
91                     }
92                 });
93             }
94         }else {
95             SwingUtilities.invokeLater(new Runnable JavaDoc(){
96                 public void run() {
97                   Thread JavaDoc actionThread = new Thread JavaDoc(){
98                     public void run() {
99                         ListIterator li = actionList.listIterator(0);
100                         while (li.hasNext()) {
101                         ActionListener al;
102                         al = (ActionListener) li.next();
103                         al.actionPerformed(new ActionEvent(GnomeTrayIconService.this,
104                                     ActionEvent.ACTION_PERFORMED, "PressAction", e.getWhen(),
105                                     0));
106                         }
107                     }
108                   };
109                   actionThread.start();
110                 }
111             });
112         }
113     }
114
115     void mouseEntered(MouseEvent e) {
116         if ((tooltip != null) && ((menu == null) || ((menu != null) && !menu.isShowing()))) {
117             Dimension d = tooltip.getSize();
118             Point p = frame.getLocationOnScreen();
119             Dimension size = tooltip.getPreferredSize();
120
121             tooltip.show(p.x, p.y - size.height - 5);
122         }
123     }
124
125     void mouseExited(MouseEvent e) {
126         if (tooltip != null) {
127             tooltip.setVisible(false);
128         }
129     }
130
131     void initListeners() {
132         MouseAdapter ma = new MouseAdapter() {
133             public void mousePressed(MouseEvent e) {
134                 GnomeTrayIconService.this.mousePressed(e);
135             }
136
137             public void mouseEntered(MouseEvent e) {
138                 GnomeTrayIconService.this.mouseEntered(e);
139             }
140
141             public void mouseExited(MouseEvent e) {
142                 GnomeTrayIconService.this.mouseExited(e);
143             }
144         };
145
146         iconPanel.addMouseListener(ma);
147         frame.addMouseListener(ma); // for some reason 1.4.2 needs
148
// to have mouse listener installed on frame instead of iconPanel
149

150     }
151
152     public void addNotify() {
153         if(GnomeTrayAppletService.winMap.get(new Long JavaDoc(this.getWindow())) == null){
154             super.init();
155             initFrame();
156             
157             if(this.icon != null)
158                 this.setIcon(this.icon);
159             if(this.menu != null)
160                 this.setPopupMenu(this.menu);
161             
162             if(this.tooltip != null)
163                 tooltip = new HWToolTip(this.tooltip.label.getTipText(), frame);
164             
165         }
166         GnomeSystemTrayService.dockWindow(this.getWindow());
167         frame.setVisible(true);
168     }
169
170     public void setPopupMenu(JPopupMenu m) {
171         menu = m;
172         if (m != null) {
173             m.setLightWeightPopupEnabled(false);
174             m.addPopupMenuListener(new PopupMenuListener JavaDoc(){
175
176                 public void popupMenuWillBecomeVisible(PopupMenuEvent JavaDoc e) {
177                 }
178
179                 public void popupMenuWillBecomeInvisible(PopupMenuEvent JavaDoc e) {
180                     popupMenuParent.setVisible(false);
181                 }
182
183                 public void popupMenuCanceled(PopupMenuEvent JavaDoc e) {
184                 }
185                 
186             });
187             // in jdk1.4, the popup menu is still visible after the invoker window lost focus.
188
popupMenuParent.addWindowFocusListener(new WindowFocusListener() {
189                 public void windowGainedFocus(WindowEvent e) {
190                 }
191
192                 public void windowLostFocus(WindowEvent e) {
193                     menu.setVisible(false);
194                 }
195             });
196
197         }
198     }
199
200     public void setIcon(final Icon i) {
201         SwingUtilities.invokeLater(new Runnable JavaDoc(){
202            public void run(){
203             icon = i;
204             if (icon != null) {
205                 int w = icon.getIconWidth();
206                 int h = icon.getIconHeight();
207                 reshape(0,0,w,h);
208                 frame.setVisible(false);
209                 frame.remove(iconPanel);
210                 iconPanel = new IconPanel();
211                 frame.add(iconPanel);
212                 frame.setVisible(true);
213             }
214             iconPanel.repaint();
215            }
216         });
217     }
218
219     public void setCaption(String JavaDoc s) {
220         // System.out.println("setCaption s =" + s);
221
if (tooltip == null) {
222             tooltip = new HWToolTip(s, frame);
223         } else {
224             tooltip.setCaption(s);
225         }
226     }
227
228     public void setIconAutoSize(boolean b) {
229         autoSize = b;
230         if (autoSize && (icon != null)) {
231             int w = icon.getIconWidth();
232             int h = icon.getIconHeight();
233             reshape(0,0,w,h);
234             frame.setVisible(false);
235             frame.remove(iconPanel);
236             iconPanel = new IconPanel();
237             frame.add(iconPanel);
238             frame.setVisible(true);
239         }
240     }
241
242     public void addActionListener(ActionListener l) {
243         actionList.add(l);
244     }
245
246     public void removeActionListener(ActionListener l) {
247         actionList.remove(l);
248     }
249
250     public Point getLocationOnScreen() {
251         Point p = null;
252
253         if (iconPanel != null) {
254             p = iconPanel.getLocationOnScreen();
255         }
256         return p;
257     }
258
259     /*
260      * This iconPanel paints the icon
261      *
262      */

263
264     class IconPanel extends JComponent {
265         Image img;
266         IconPanel() {}
267
268         public void paintComponent(Graphics g) {
269             Dimension d = getAppletSize();
270             g.clearRect(0, 0, d.width, d.height);
271
272             if (icon != null) {
273                 int w = icon.getIconWidth();
274                 int h = icon.getIconHeight();
275                 if (!autoSize) {
276                     icon.paintIcon(this, g, 0, 0);
277                 } else {
278                     /* Scale to the right size */
279                     if (img == null) {
280                         img = createImage(w, h);
281                     }
282                     icon.paintIcon(this, img.getGraphics(), 0, 0);
283                     g.drawImage(img, 0, 0, d.width, d.height, 0,0,w,h, this);
284                 }
285             }
286           super.paintComponent(g);
287         }
288         boolean doesIconReferenceImage(Icon icon, Image image) {
289             Image iconImage = (icon != null && (icon instanceof ImageIcon)) ?
290                 ((ImageIcon)icon).getImage() : null;
291             return (iconImage == image);
292         }
293
294         /**
295          * This is overridden to return false if the current Icon's Image is
296          * not equal to the passed in Image <code>img</code>.
297          *
298          * @see java.awt.image.ImageObserver
299          * @see java.awt.Component#imageUpdate(java.awt.Image, int, int, int, int, int)
300          */

301         public boolean imageUpdate(Image img, int infoflags,
302                 int x, int y, int w, int h) {
303             if (!isShowing() ||
304                     !doesIconReferenceImage(icon, img)) {
305                 return false;
306             }
307             return super.imageUpdate(img, infoflags, x, y, w, h);
308         }
309     }
310
311
312     class HWToolTip extends JWindow {
313
314         Font font = new Font("Serif", 10, Font.PLAIN);
315
316         JToolTip label;
317         public HWToolTip(String JavaDoc caption, Window parent) {
318             super(parent);
319             setFocusableWindowState(false);
320             setName("###overrideRedirect###");
321             label = new JToolTip();
322             label.setTipText(caption);
323             getContentPane().add(label);
324         }
325
326         public void setCaption(String JavaDoc caption) {
327             label.setTipText(caption);
328         }
329
330         public void show(int x, int y) {
331             setLocation(x, y);
332             Dimension d = label.getPreferredSize();
333
334             // pack does not seem to work !
335
setSize(d.width, d.height);
336             setVisible(true);
337         }
338     }
339     
340     public void showBalloonMessage(String JavaDoc caption, String JavaDoc text, int type){
341         if( caption == null && text == null)
342             throw new NullPointerException JavaDoc();
343         bmw.showBalloonMessage(caption, text, type);
344     }
345     
346     class BalloonMessageWindow extends JWindow{
347         Dimension sd;
348         Dimension pd;
349         Dimension d;
350         Point pp;
351         Point p;
352         boolean downToup = true;
353         
354         JLabel captionLabel = new JLabel();
355         JLabel textLabel = new JLabel();
356         private Thread JavaDoc showThread;
357         private Thread JavaDoc hideThread;
358         private int timeout = 10000;
359         private int delay = 15;
360         private int pixel = 2;
361
362         private ActionListener hideAction;
363         private javax.swing.Timer JavaDoc hideTimer;
364
365         public BalloonMessageWindow(Window parent){
366             super(parent);
367             JPanel outerPanel = new JPanel();
368             JPanel innerPanel = new JPanel();
369             this.getContentPane().add(outerPanel);
370             outerPanel.setLayout(new BorderLayout());
371             outerPanel.add(innerPanel);
372             outerPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED,
373                     new Color(0x00CBDAF3), new Color(0x002F4A78)));
374             innerPanel.setLayout(new BorderLayout());
375             innerPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED,
376                     new Color(0x00CBDAF3), new Color(0x002F4A78)));
377             
378             captionLabel.setFont(new Font("SansSerif", Font.BOLD, 12));
379             textLabel.setFont(new Font("SansSerif", Font.PLAIN, 12));
380             innerPanel.setBackground(new Color(0x00FFFFE1));
381             innerPanel.setOpaque(true);
382             
383             textLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 3, 3));
384
385             ImageIcon x = new ImageIcon(
386                     GnomeTrayIconService.class.getResource("images/x.png"));
387             ImageIcon xx = new ImageIcon(
388                     GnomeTrayIconService.class.getResource("images/xx.png"));
389             ImageIcon xxx = new ImageIcon(
390                     GnomeTrayIconService.class.getResource("images/xxx.png"));
391             JButton closeButton = new JButton(x);
392             closeButton.setPreferredSize(new Dimension(x.getIconWidth(), x.getIconHeight()));
393             closeButton.setRolloverEnabled(true);
394             closeButton.setRolloverIcon(xx);
395             closeButton.setPressedIcon(xxx);
396             closeButton.setBorder(null);
397             closeButton.addActionListener(new ActionListener(){
398                 public void actionPerformed(ActionEvent e) {
399                     BalloonMessageWindow.this.hideCurrentMessageWindowImmediately();
400                 }
401             });
402             closeButton.setToolTipText("Close");
403             JPanel closePanel = new JPanel();
404             closePanel.setOpaque(false);
405             closePanel.setLayout(new BorderLayout());
406             closePanel.add(closeButton, BorderLayout.NORTH);
407             
408             JPanel topPanel = new JPanel();
409             topPanel.setLayout(new BorderLayout());
410             topPanel.setOpaque(false);
411             topPanel.add(closePanel, BorderLayout.EAST);
412             topPanel.add(captionLabel, BorderLayout.CENTER);
413             topPanel.setBorder(BorderFactory.createEmptyBorder(3, 5, 0, 3));
414             innerPanel.add(topPanel, BorderLayout.NORTH);
415             innerPanel.add(textLabel, BorderLayout.CENTER);
416             
417             outerPanel.addMouseListener(new MouseAdapter(){
418                 public void mouseClicked(final MouseEvent e){
419                     hideCurrentMessageWindowImmediately();
420                     ListIterator li = balloonListeners.listIterator(0);
421                     while (li.hasNext()) {
422                     ActionListener al;
423                     al = (ActionListener) li.next();
424                     al.actionPerformed(new ActionEvent(GnomeTrayIconService.this,
425                                 ActionEvent.ACTION_PERFORMED, "PressAction", e.getWhen(),
426                                 0));
427                     }
428                 }
429             });
430             hideAction = new ActionListener(){
431                 public void actionPerformed(ActionEvent e) {
432                     doHide();
433                 }
434             };
435             hideTimer = new javax.swing.Timer JavaDoc(timeout, hideAction);
436             hideTimer.setRepeats(false);
437         }
438         private void hideCurrentMessageWindowImmediately(){
439             if(hideThread != null){
440                 hideThread.interrupt(); // already in hiding.
441
} else if(showThread != null){
442                 hideTimer.stop();
443                 showThread.interrupt();
444                 this.setVisible(false);
445
446                 synchronized(GnomeTrayIconService.class){
447                     GnomeTrayIconService.class.notify();
448                     showThread = null;
449                 }
450             }
451         }
452         
453         public void showBalloonMessage(final String JavaDoc caption, final String JavaDoc text, final int type){
454             if(showThread != null){
455                 Thread JavaDoc waitThread = new Thread JavaDoc(){
456                     public void run(){
457                         synchronized(GnomeTrayIconService.class){
458                             try{
459                                 if(showThread != null)
460                                     GnomeTrayIconService.class.wait();
461                             }catch(InterruptedException JavaDoc ie){
462                                 ie.printStackTrace();
463                             }
464                         }
465                         doShowMessageWindow(caption, text, type);
466                     }
467                 };
468                 waitThread.start();
469             }else {
470                 this.doShowMessageWindow(caption, text, type);
471             }
472         }
473         
474         private void doShowMessageWindow(final String JavaDoc caption, final String JavaDoc text, final int type){
475             showThread = new Thread JavaDoc(){
476                 public void run(){
477                     doShow(caption, text, type);
478                 }
479             };
480             showThread.start();
481         }
482      
483         private synchronized void doShow(String JavaDoc caption, String JavaDoc text, int type){
484             switch(type) {
485                 case 0:
486                     captionLabel.setIcon(new ImageIcon(
487                             GnomeTrayIconService.class.getResource("images/info.png")));
488                     break;
489                 case 1:
490                     captionLabel.setIcon(new ImageIcon(
491                             GnomeTrayIconService.class.getResource("images/error.png")));
492                     break;
493                 case 2:
494                     captionLabel.setIcon(new ImageIcon(
495                             GnomeTrayIconService.class.getResource("images/warning.png")));
496                     break;
497                 default :
498                     captionLabel.setIcon(null);
499                     break;
500             }
501             captionLabel.setText(caption != null ? caption : "");
502             if(text != null){
503                 text = "<html>"+text.replaceAll("\\n", "<br>")+"</html>";
504                 textLabel.setText(text);
505             }else{
506                 textLabel.setText("");
507             }
508             
509             this.pack();
510
511             pp = frame.getLocation();
512             SwingUtilities.convertPointToScreen(pp, frame);
513             p = new Point();
514
515             sd = Toolkit.getDefaultToolkit().getScreenSize();
516             pd = frame.getSize();
517             d = this.getSize();
518
519             // Adjust for the frame's size
520
pp.x -= 2;
521             pp.y -= 4;
522             pd.width += 2;
523             pd.height += 6;
524
525             p.x = (pp.x + d.width) < sd.width ? pp.x : sd.width-d.width;
526             downToup = (pp.y - d.height) > 0;
527             p.y = (pp.y - d.height) > 0 ? pp.y - d.height : pp.y + pd.height;
528             try{
529                 if(downToup)
530                     this.setBounds(p.x, p.y+d.height, d.width, 1);
531                 else
532                     this.setBounds(p.x, p.y, d.width, 1);
533
534                 this.setVisible(true);
535                 for(int i=1; i < d.height; i+=pixel){
536                     Thread.sleep(delay);
537                     if(downToup)
538                         this.setBounds(p.x, p.y+d.height-i, d.width, i);
539                     else
540                         this.setBounds(p.x, p.y, d.width, i);
541                     
542                     this.validate();
543                 }
544                 if(p.y != this.getLocation().y || d.height != this.getSize().getHeight()){
545                     this.setBounds(p.x, p.y, d.width, d.height);
546                     this.validate();
547                 }
548                 hideTimer.start();
549             }catch(InterruptedException JavaDoc ie){}
550         }
551
552         private void doHide(){
553             hideThread = new Thread JavaDoc(){
554              public void run(){
555                 p = getLocation();
556                 d = getSize();
557                 try{
558                     for(int i=d.height; i>=1; i-=pixel){
559                         Thread.sleep(delay);
560                         if(downToup){
561                             setBounds(p.x, p.y+d.height-i, d.width, i);
562                         }else{
563                             setSize(d.width, i);
564                         }
565                         validate();
566                     }
567                 }catch(Exception JavaDoc e){}
568                 setVisible(false);
569                 synchronized(GnomeTrayIconService.class){
570                     showThread = null;
571                     GnomeTrayIconService.class.notify();
572                 }
573                 hideThread = null;
574              }
575             };
576             hideThread.start();
577         }
578     }
579
580     public void addBalloonActionListener(ActionListener al) {
581         balloonListeners.add(al);
582     }
583     public void removeBalloonActionListener(ActionListener al) {
584         balloonListeners.remove(al);
585     }
586 }
587
Popular Tags