23

我正在使用以下代码在 Windows 和 Linux 中设置托盘图标。它在 Windows 中运行良好,在 Linux 中运行良好。在 Linux(Ubuntu)中,我将面板设置为(有点)透明,当我添加 GIF(具有透明背景)时,图标的背景显示为灰色和丑陋的(见图,绿色菱形“!”)。 ...关于如何使我添加的 GIF 图像“保持”其透明背景的任何想法?

替代文字 http://unarm.org/stackoverflow/panel_task.jpg

以及我正在使用的图像,如果您想测试:

替代文字 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);
  }
}
4

6 回答 6

17

问题出在 sun.awt.X11.XTrayIconPeer.IconCanvas.paint() 方法上!

在绘画之前,通过简单地绘制一个 IconCanvas 背景颜色的矩形来业余地清除图标背景,以允许图像动画。

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

见:http ://bugs.java.com/bugdatabase/view_bug.do?bug_id=6453521

于 2010-10-07T13:18:47.383 回答
10

对于那些寻找“真正”解决方案的人,我开发了一个小型库,它能够显示托盘图标以尊重透明度,并且还接受 SVG 图标(适用于所有平台):

http://skype2gmail.blogspot.com/2011/05/java-tray-icon-transparency.html

它是一个开源库,源代码可以在这里找到:

https://github.com/taksan/native-tray-adapter

该库通过在 linux 下运行时提供 JNI 替代方案(使用 GTK)来解决该问题。

于 2011-05-24T13:13:59.813 回答
2

这个问题很有可能无法解决。这取决于 Java 在 Linux 中创建托盘子窗口方面是否做得很好。如果 Jave 做错了,则在绘制图像时透明度已经丢失。

  1. 您正在使用的图标的真实背景值是多少?是上面显示的灰色调吗?将其设置为紫色以查看是否使用图像的透明度(Java 默认为灰色背景)。

  2. 确保您尝试了 PNG 的两种透明度选项:透明颜色索引和 alpha 通道。Alpha 通道在 Linux 中很常见,而在 Windows 世界中则不然。

  3. 您的图标分辨率太小。在 64x64 或更好的 128x128 中进行。AFAIK 托盘图标没有标准分辨率,即使是这样,它也肯定不是 16x16。

  4. 您可以尝试的另一种格式是 SVG。只有在确保图像的透明度是问题后才能尝试(参见 1)。

有关此问题的背景信息,请参见此处: http ://www.rasterman.com/index.php?page=News (向下滚动至 2006 年 2 月 2 日)

于 2008-12-01T18:26:03.643 回答
1

JDIC 有一个托盘图标,它们可能支持 linux 中的透明度... https://jdic.dev.java.net/

于 2008-12-02T15:57:04.067 回答
0

您是否尝试过将其转换为 .PNG(具有透明度)?我发现 Java 往往会更好地支持它们(根据我的经验)

于 2008-12-01T17:02:04.577 回答
0

这并不是说 。. . 这很高兴,因为它使用默认的 GNOME 主题来呈现透明度 - 它与它自身的图像无关 - 这是 adobe air / gnome 冲突 - 如果您切换到 gnome 主题,那么默认背景是灰色的它将是灰色而不是白色。它使用系统默认图像,因此即使它已设置,但面板的主题具有 BG 图像,使其看起来像 vista 一样有光泽,例如,它会这样做。Adobe Air / Java 不知道您使用透明主题默认设置,因此它使用系统默认设置

于 2010-04-21T00:12:25.727 回答