java TrayIcon using image with transparent background
Asked Answered
N

6

23

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);
  }
}
Nganngc answered 1/12, 2008 at 16:49 Comment(3)
I guess you'll have to switch to a square icon :( :( I'm glad you find the SystemTray as a good alternative for your deamon app. What is this new app all about? :) is it a secret?Spiegelman
question, does this icon image looks opaque when displayed somewhere else? A webpage for instance?Spiegelman
It's somewhat of a secret but I plan on releasing it most likely as an open source project pretty soon here. The image looks fine when displayed anywhere else. You can see I have embedded below the my task-bar image and above the code.Nganngc
C
2

Chances are this problem cannot be resolved. It depends on wether Java is doing a good job in creating the tray subwindow in Linux or not. If Jave does it wrong, transparency is already lost when the image is drawn.

  1. What is the real background value of the icon you are using? Is it the gray tone shown above? Set it to purple to see if the transparency of the image is used (Java defaults to gray background) or not.

  2. Make sure you tried both transparency options of PNG: transparent color index as well as alpha channel. Alpha channel is very common in Linux, not so in the Windows world.

  3. The resolution of your icon is too small. Do it in 64x64 or better 128x128. AFAIK there is no standard resolution for tray icons, and even if so, it is certainly not 16x16.

  4. Another format you could try is SVG. Only try that after making sure that the transparency of the image is the problem (see 1).

See here for background information on this issue: http://www.rasterman.com/index.php?page=News (scroll down to 2 February 2006)

Cramoisy answered 1/12, 2008 at 18:26 Comment(3)
Thanks. 1)It's transparent ( checkered background)...I tried making it purple and it showed up as purple in the tray. 2)I tried all the different PNG options when saving in GIMP and they all had the same result 3)I also tried different size icons w/the same result 4)I tried SVG...showed up all grey.Nganngc
Sorry, ran out of space. Thanks for the ideas. Do you happen to have any other ideas?Nganngc
So if Java doesn't really understand the image's transparency, that's really weird. Perhaps try drawing an image inside the application. Or perhaps there are specific options for these images. I don't know what to do else (perhaps other API available than SystemTray?)Cramoisy
I
17

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

Intreat answered 7/10, 2010 at 13:18 Comment(0)
J
10

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.

Jota answered 24/5, 2011 at 13:13 Comment(2)
I've noticed this GitHub repo hasn't had an abundance of activity since 2011. Is this still a viable solution? I've documented some other platform tray issues here: https://mcmap.net/q/585832/-java-trayicon-right-click-disabled-on-mac-osx. It would be nice to have a solution that works reliably, cross platform.Deadfall
In some language ecosystems (like the Erlang, Haskell and Clojure worlds), the lack of activity and opening of issues means it wasn't broken to begin with. I look for libraries that have been around with a shrinking number of issues, ideally zero.Impregnate
C
2

Chances are this problem cannot be resolved. It depends on wether Java is doing a good job in creating the tray subwindow in Linux or not. If Jave does it wrong, transparency is already lost when the image is drawn.

  1. What is the real background value of the icon you are using? Is it the gray tone shown above? Set it to purple to see if the transparency of the image is used (Java defaults to gray background) or not.

  2. Make sure you tried both transparency options of PNG: transparent color index as well as alpha channel. Alpha channel is very common in Linux, not so in the Windows world.

  3. The resolution of your icon is too small. Do it in 64x64 or better 128x128. AFAIK there is no standard resolution for tray icons, and even if so, it is certainly not 16x16.

  4. Another format you could try is SVG. Only try that after making sure that the transparency of the image is the problem (see 1).

See here for background information on this issue: http://www.rasterman.com/index.php?page=News (scroll down to 2 February 2006)

Cramoisy answered 1/12, 2008 at 18:26 Comment(3)
Thanks. 1)It's transparent ( checkered background)...I tried making it purple and it showed up as purple in the tray. 2)I tried all the different PNG options when saving in GIMP and they all had the same result 3)I also tried different size icons w/the same result 4)I tried SVG...showed up all grey.Nganngc
Sorry, ran out of space. Thanks for the ideas. Do you happen to have any other ideas?Nganngc
So if Java doesn't really understand the image's transparency, that's really weird. Perhaps try drawing an image inside the application. Or perhaps there are specific options for these images. I don't know what to do else (perhaps other API available than SystemTray?)Cramoisy
S
1

JDIC has a tray icon, they might support transparency in linux... https://jdic.dev.java.net/

Snowmobile answered 2/12, 2008 at 15:57 Comment(0)
M
0

Have you tried converting it to a .PNG (with transparency) instead? I've found they tend to be better supported by Java (In my experience)

Magree answered 1/12, 2008 at 17:2 Comment(0)
Y
0

its not that . . . this is happing because it is using the default GNOME theme for rendering the transparency - it has nothing to do with the image it self - this is an adobe air / gnome conflict - if you switch to a gnome theme were the default background is grey then it would be grey instead of white. It uses the system default image so even if it was set but the theme for the panel to have a BG image to make it look glossy like vista for example than it would do that. Adobe Air / Java doesn't know that you over road the theme default with transparency and therefor it is using the system default

Yoshida answered 21/4, 2010 at 0:12 Comment(1)
I just test this "theory" and it is indeed trueYoshida

© 2022 - 2024 — McMap. All rights reserved.