java TrayIcon using image with transparent background

♀尐吖头ヾ 提交于 2019-11-27 11:14:24

问题


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);
  }
}

回答1:


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)




回答2:


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




回答3:


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.




回答4:


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




回答5:


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)




回答6:


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



来源:https://stackoverflow.com/questions/331407/java-trayicon-using-image-with-transparent-background

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!