Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java TrayIcon using image with transparent background

Tags:

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);   } } 
like image 201
Jack Avatar asked Dec 01 '08 16:12

Jack


2 Answers

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

like image 70
Falkster Avatar answered Sep 20 '22 17:09

Falkster


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.

like image 26
taksan Avatar answered Sep 18 '22 17:09

taksan