1 20 21 package org.jdesktop.jdic.tray.internal.impl; 22 23 24 import org.jdesktop.jdic.tray.internal.TrayIconService; 25 26 31 32 import java.awt.*; 33 import javax.swing.*; 34 import javax.swing.border.BevelBorder ; 35 import javax.swing.event.PopupMenuEvent ; 36 import javax.swing.event.PopupMenuListener ; 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 (){ 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 (){ 96 public void run() { 97 Thread actionThread = new Thread (){ 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); 150 } 151 152 public void addNotify() { 153 if(GnomeTrayAppletService.winMap.get(new Long (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 (){ 175 176 public void popupMenuWillBecomeVisible(PopupMenuEvent e) { 177 } 178 179 public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { 180 popupMenuParent.setVisible(false); 181 } 182 183 public void popupMenuCanceled(PopupMenuEvent e) { 184 } 185 186 }); 187 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 (){ 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 s) { 220 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 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 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 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 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 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 setSize(d.width, d.height); 336 setVisible(true); 337 } 338 } 339 340 public void showBalloonMessage(String caption, String text, int type){ 341 if( caption == null && text == null) 342 throw new NullPointerException (); 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 showThread; 357 private Thread 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 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 (timeout, hideAction); 436 hideTimer.setRepeats(false); 437 } 438 private void hideCurrentMessageWindowImmediately(){ 439 if(hideThread != null){ 440 hideThread.interrupt(); } 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 caption, final String text, final int type){ 454 if(showThread != null){ 455 Thread waitThread = new Thread (){ 456 public void run(){ 457 synchronized(GnomeTrayIconService.class){ 458 try{ 459 if(showThread != null) 460 GnomeTrayIconService.class.wait(); 461 }catch(InterruptedException 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 caption, final String text, final int type){ 475 showThread = new Thread (){ 476 public void run(){ 477 doShow(caption, text, type); 478 } 479 }; 480 showThread.start(); 481 } 482 483 private synchronized void doShow(String caption, String 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 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 ie){} 550 } 551 552 private void doHide(){ 553 hideThread = new Thread (){ 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 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 |