I am using the following code to set a tray icon in Windows and Linux. It works wonderful in Windows and works okay in Linux. In Linux (Ubuntu) I have my panel set to be (somewhat) transparent and when I add a GIF (with a transparent background) the background of the icon shows up all grey and ugly (see image, green diamond "!")....Any ideas on how to make the GIF image I am adding "keep" its transparent background?
alt text http://unarm.org/stackoverflow/panel_task.jpg
and the image I am using, if you'd like to test:
alt text http://unarm.org/stackoverflow/green_info.gif
import java.awt.*; import java.awt.event.*; public class TrayFun { static class ShowMessageListener implements ActionListener { TrayIcon trayIcon; String title; String message; TrayIcon.MessageType messageType; ShowMessageListener( TrayIcon trayIcon, String title, String message, TrayIcon.MessageType messageType) { this.trayIcon = trayIcon; this.title = title; this.message = message; this.messageType = messageType; } public void actionPerformed(ActionEvent e) { trayIcon.displayMessage(title, message, messageType); } } public static void main(String args[]) { Runnable runner = new Runnable() { public void run() { if (SystemTray.isSupported()) { final SystemTray tray = SystemTray.getSystemTray(); Image image = Toolkit.getDefaultToolkit().getImage("green_info.png"); PopupMenu popup = new PopupMenu(); final TrayIcon trayIcon = new TrayIcon(image, "The Tip Text", popup); trayIcon.setImageAutoSize(true); MenuItem item = new MenuItem("Close"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { tray.remove(trayIcon); } }); popup.add(item); try { tray.add(trayIcon); } catch (AWTException e) { System.err.println("Can't add to tray"); } } else { System.err.println("Tray unavailable"); } } }; EventQueue.invokeLater(runner); } }
The problem lies in the sun.awt.X11.XTrayIconPeer.IconCanvas.paint() method!
Before painting, the icon background is amateurishly cleared by simply drawing a rectangle of IconCanvas’ background color, to allow image animations.
public void paint(Graphics g) { if (g != null && curW > 0 && curH > 0) { BufferedImage bufImage = new BufferedImage(curW, curH, BufferedImage.TYPE_INT_ARGB); Graphics2D gr = bufImage.createGraphics(); if (gr != null) { try { gr.setColor(getBackground()); gr.fillRect(0, 0, curW, curH); gr.drawImage(image, 0, 0, curW, curH, observer); gr.dispose(); g.drawImage(bufImage, 0, 0, curW, curH, null); } finally { gr.dispose(); } } } }
see: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6453521
For those looking for a "real" solution, I developed a small library that is capable of displaying the tray icon honoring the transparency and also accepts SVG icons (for all platforms):
http://skype2gmail.blogspot.com/2011/05/java-tray-icon-transparency.html
It is an open source library and the source code can be found here:
https://github.com/taksan/native-tray-adapter
The library work arounds the problem by providing a JNI alternative (with GTK) when running under linux.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With