1 20 21 package org.jdesktop.jdic.tray.internal.impl; 22 23 24 29 30 import org.jdesktop.jdic.tray.internal.TrayIconService; 31 import java.awt.*; 32 import java.awt.image.*; 33 import javax.swing.*; 34 import javax.swing.event.PopupMenuListener ; 35 import javax.swing.event.PopupMenuEvent ; 36 import java.awt.event.*; 37 import java.lang.reflect.InvocationTargetException ; 38 import java.lang.reflect.Method ; 39 import java.util.*; 40 41 import sun.awt.image.IntegerComponentRaster; 42 43 44 public class WinTrayIconService implements TrayIconService{ 45 46 private JPopupMenu menu; 47 private Icon icon; 48 private boolean autoSize; 49 private byte[] caption = "JDIC TrayIcon".getBytes(); 50 51 private long hicon; 52 private Image oldIconImage; 53 static private HashMap map = new HashMap(); 54 55 private LinkedList actionList = new LinkedList(); 56 private LinkedList balloonListeners = new LinkedList(); 57 58 static int noIcons; 59 60 int iconID; 61 62 AnimationObserver observer; 63 64 private final int WINDOWS_TASKBAR_ICON_WIDTH = 16; 65 private final int WINDOWS_TASKBAR_ICON_HEIGHT = 16; 66 67 static class PopupParent extends JDialog{ 68 public PopupParent(){ 69 super((Frame)null, "JDIC Tray Icon"); 70 try{ 71 Method setAlwaysOnTop = this.getClass().getMethod("setAlwaysOnTop", new Class []{boolean.class}); 72 setAlwaysOnTop.invoke(this, new Object []{Boolean.TRUE}); 73 }catch(NoSuchMethodException e){ 74 }catch(Exception e){ 75 e.printStackTrace(); 76 } 77 this.setUndecorated(true); 78 this.setBounds(0, 0, 0, 0); 79 } 80 } 81 static PopupParent popupParentFrame; 82 83 boolean created; 84 85 static { 86 Runtime.getRuntime().addShutdownHook(new Thread () { 87 public void run() { 88 removeAllIcons(); 89 } 90 }); 91 } 92 93 public static void removeAllIcons() { 94 for (int i = 0; i < noIcons; i++) { 95 removeIcon(i); 96 } 97 } 98 99 public WinTrayIconService() { 100 iconID = noIcons++; 101 if(popupParentFrame == null){ 102 popupParentFrame = new PopupParent(); 103 } 104 } 105 106 private native long createIconIndirect(int[] rData, byte[] andMask, 107 int nScanStride, int width, 108 int height, int xHotSpot, 109 int yHotSpot); 110 111 private native void createIcon(long hIcon, int id, byte[] tooltip); 112 113 private native void updateNativeIcon(long hIcon, int id, byte[] tooltip); 114 115 private native void showBalloonMessage(long hIcon, int id, byte[] caption, byte[] text, int type); 116 117 private native void deleteHIcon(long hIcon); 118 119 private native int[] getRectangleOnScreen(int id); 120 121 private static native void removeIcon(int id); 122 123 public void showBalloonMessage(String caption, String text, int type){ 124 byte[] batitle = caption == null ? new byte[0]: caption.getBytes(); 125 byte[] bacontent = text == null ? new byte[0] : text.getBytes(); 126 showBalloonMessage(hicon, iconID, batitle, bacontent, type); 127 } 128 129 public void addNotify() { 130 if(popupParentFrame == null){ 131 popupParentFrame = new PopupParent(); 132 } 133 popupParentFrame.pack(); 134 map.put(new Integer (iconID), this); 135 136 observer = new AnimationObserver(); 137 updateIcon(null); 138 created = true; 139 } 140 141 private void updateBufferedImage() { 142 } 143 144 public void setPopupMenu(JPopupMenu m) { 145 menu = m; 146 if (menu != null) { 147 menu.setLightWeightPopupEnabled(false); 148 149 menu.addPopupMenuListener(new PopupMenuListener () { 150 public void popupMenuWillBecomeVisible(PopupMenuEvent e) { 151 } 152 153 public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { 154 popupParentFrame.setVisible(false); 155 popupParentFrame.toBack(); 156 } 157 158 public void popupMenuCanceled(PopupMenuEvent e) { 159 } 160 }); 161 162 popupParentFrame.addWindowFocusListener(new WindowFocusListener() { 164 public void windowGainedFocus(WindowEvent e) { 165 } 166 167 public void windowLostFocus(WindowEvent e) { 168 menu.setVisible(false); 169 } 170 }); 171 172 } 173 } 174 175 protected long createNativeIcon(BufferedImage bimage, int w, int h, 176 int xHotSpot, int yHotSpot) { 177 178 int pixels[] = ((DataBufferInt) bimage.getRaster().getDataBuffer()).getData(); 179 Raster raster = bimage.getRaster(); 180 byte[] andMask = new byte[(w * h) / 8]; 181 int npixels = pixels.length; 182 183 for (int i = 0; i < npixels; i++) { 184 int ibyte = i / 8; 185 int omask = 1 << (7 - (i % 8)); 186 187 if ((pixels[i] & 0xff000000) == 0) { 188 if (ibyte < andMask.length) { 190 andMask[ibyte] |= omask; 191 } 192 } 193 } { 194 int ficW = raster.getWidth(); 195 196 if (raster instanceof IntegerComponentRaster) { 197 ficW = ((IntegerComponentRaster) raster).getScanlineStride(); 198 } 199 return createIconIndirect(((DataBufferInt) bimage.getRaster().getDataBuffer()).getData(), 200 andMask, ficW, raster.getWidth(), raster.getHeight(), 201 xHotSpot, yHotSpot); 202 } 203 } 204 205 public void processEvent(int mouseState, int x, int y) { 206 207 switch (mouseState) { 208 case 0x200: break; 210 211 case 0x202: ListIterator li = actionList.listIterator(0); 213 ActionListener al; 214 215 while (li.hasNext()) { 216 al = (ActionListener) li.next(); 217 al.actionPerformed(new ActionEvent(this, 218 ActionEvent.ACTION_PERFORMED, "PressAction", 219 System.currentTimeMillis(), 0)); 220 } 221 break; 222 223 case 0x205: if (menu != null) { 225 Point p = new Point(x, y); 226 Dimension d = menu.getPreferredSize(); 227 Dimension s = Toolkit.getDefaultToolkit().getScreenSize(); 228 p.x = p.x + d.width > s.width ? p.x - d.width : p.x; 229 p.y = p.y + d.height > s.height ? p.y - d.height : p.y; 230 popupParentFrame.setVisible(true); 231 menu.show(popupParentFrame.getContentPane(), p.x, p.y); 232 popupParentFrame.toFront(); 233 } 234 break; 235 case 0x0405: ListIterator ml = balloonListeners.listIterator(0); 237 ActionListener listener; 238 239 while (ml.hasNext()) { 240 listener = (ActionListener) ml.next(); 241 listener.actionPerformed(new ActionEvent(this, 242 ActionEvent.ACTION_PERFORMED, "PressAction", 243 System.currentTimeMillis(), 0)); 244 } 245 break; 246 } 247 } 248 249 public synchronized static void notifyEvent(int id, final int mouseState, final int x, final int y) { 250 final WinTrayIconService instance = (WinTrayIconService) map.get(new Integer (id)); 251 if(instance == null) 252 return; 253 try { 254 EventQueue.invokeLater(new Runnable () { 255 public void run() { 256 instance.processEvent(mouseState, x, y); 257 } 258 }); 259 } catch (Exception e) { 260 e.printStackTrace(); 261 } 262 } 263 264 private void updateIcon(Image iconImage) { 265 Graphics2D g; 266 if (icon != null) { 267 if (iconImage == null) { 268 iconImage = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB); 269 g = (Graphics2D) ((BufferedImage)iconImage).getGraphics(); 270 g.setComposite(AlphaComposite.Src); 271 icon.paintIcon(observer, g, 0, 0); 272 oldIconImage = iconImage; 273 } 274 275 277 BufferedImage tmpImage = new BufferedImage(WINDOWS_TASKBAR_ICON_WIDTH, WINDOWS_TASKBAR_ICON_HEIGHT, 278 BufferedImage.TYPE_INT_ARGB); 279 g = (Graphics2D) tmpImage.getGraphics(); 280 281 try { 282 g.setComposite(AlphaComposite.Src); 283 g.drawImage(iconImage, 0, 0, WINDOWS_TASKBAR_ICON_WIDTH,WINDOWS_TASKBAR_ICON_HEIGHT, null); 284 } finally { 285 g.dispose(); 286 } 287 tmpImage.flush(); 288 289 if (hicon != 0) { 291 deleteHIcon(hicon); 292 } 293 hicon = createNativeIcon(tmpImage, WINDOWS_TASKBAR_ICON_WIDTH, WINDOWS_TASKBAR_ICON_HEIGHT, 0, 0); 294 if (created) { 295 updateNativeIcon(hicon, iconID, caption); 296 } 297 else { 298 createIcon(hicon, iconID, caption); 299 } 300 } 301 } 302 303 private class AnimationObserver extends Component { 304 boolean update = true; 305 306 public void setUpdate(boolean b) { 307 update = b; 308 } 309 public boolean imageUpdate(Image img, 310 int infoflags, 311 int x, 312 int y, 313 int width, 314 int height) { 315 316 if (update && created) { 317 updateIcon(img); 318 } 319 return update; 320 } 321 } 322 323 public void setIcon(final Icon i) { 324 icon = i; 325 if (created) { 326 observer.setUpdate(false); 327 observer = new AnimationObserver(); 328 updateIcon(null); 329 } 330 } 331 332 public void setCaption(String s) { 333 caption = (s == null ? "" : s ).getBytes(); 334 if (created) { 335 observer.setUpdate(false); 336 observer = new AnimationObserver(); 337 updateIcon(null); 338 } 339 } 340 341 public void setIconAutoSize(boolean b) { 342 } 344 345 public void addActionListener(ActionListener l) { 346 actionList.add(l); 347 } 348 349 public void removeActionListener(ActionListener l) { 350 actionList.remove(l); 351 } 352 353 public Point getLocationOnScreen() { 354 int[] rect = this.getRectangleOnScreen(iconID); 355 return new Point(rect[0], rect[1]); 356 } 357 358 void remove() { 359 removeIcon(iconID); 360 if (hicon != 0) { 362 deleteHIcon(hicon); 363 } 364 map.remove(new Integer (iconID)); 365 created = false; 366 if(map.size() == 0){ 367 popupParentFrame.dispose(); 368 popupParentFrame = null; 369 } 370 } 371 private static void restartTaskbar() { 372 Iterator keyiterator = map.keySet().iterator(); 373 while (keyiterator.hasNext()) { 374 WinTrayIconService iconService = (WinTrayIconService)map.get(keyiterator.next()); 375 if (iconService.created) { 376 iconService.remove(); 377 iconService.addNotify(); 378 } 379 } 380 } 381 382 public void addBalloonActionListener(ActionListener al) { 383 balloonListeners.add(al); 384 } 385 386 public void removeBalloonActionListener(ActionListener al) { 387 balloonListeners.remove(al); 388 } 389 } 390 | Popular Tags |