代码之家  ›  专栏  ›  技术社区  ›  Jack

java TrayIcon使用透明背景图像

  •  22
  • Jack  · 技术社区  · 16 年前

    我使用以下代码在Windows和Linux中设置托盘图标。它在Windows中工作得很好,在Linux中工作得很好。在Linux(Ubuntu)中,我将我的面板设置为(某种程度上)透明,当我添加GIF(背景透明)时,图标的背景显示为灰色和难看(请参见图像,绿色菱形“!”)……关于如何使我添加的GIF图像“保持”其透明背景的想法?

    alt text http://unarm.org/stackoverflow/panel_task.jpg

    我使用的图像,如果你想测试:

    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);
      }
    }
    
    6 回复  |  直到 16 年前
        1
  •  17
  •   flying sheep    11 年前

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

    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

        2
  •  10
  •   taksan    14 年前

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

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

    它是一个开源库,源代码可在以下位置找到:

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

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

        3
  •  2
  •   ypnos    16 年前

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

    2. 图标的分辨率太小。在64x64或更好的128x128中执行此操作。AFAIK没有托盘图标的标准分辨率,即使如此,也肯定不是16x16。

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

    http://www.rasterman.com/index.php?page=News (向下滚动至2006年2月2日)

        4
  •  1
  •   Somatik    16 年前
        5
  •  0
  •   Richard Walton    16 年前

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

        6
  •  0
  •   freshfitteds    15 年前

    并不是说。这是因为它使用默认GNOME主题渲染透明度-它与图像本身无关-这是adobe air/GNOME冲突-如果切换到GNOME主题,则默认背景为灰色,则它将为灰色而不是白色。它使用系统默认图像,因此即使已设置,但面板的主题也应具有BG图像,以使其看起来像vista一样有光泽,例如,它不会这样做。AdobeAIR/Java不知道您使用透明的默认主题,因此它使用的是系统默认