java TrayIcon 使用具有透明背景的图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/331407/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java TrayIcon using image with transparent background
提问by Hyman
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?
我使用以下代码在 Windows 和 Linux 中设置托盘图标。它在 Windows 中运行良好,在 Linux 中运行正常。在 Linux (Ubuntu) 中,我将面板设置为(有点)透明,当我添加 GIF(具有透明背景)时,图标的背景显示为灰色和丑陋(参见图片,绿色菱形“!”)。 ...关于如何制作我添加的 GIF 图像的任何想法“保持”其透明背景?
alt text http://unarm.org/stackoverflow/panel_task.jpg
替代文字 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
替代文字 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);
}
}
采纳答案by ypnos
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.
这个问题很可能无法解决。这取决于 Java 在 Linux 中创建托盘子窗口方面是否做得很好。如果 Jave 做错了,那么在绘制图像时就已经失去了透明度。
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.
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.
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.
Another format you could try is SVG. Only try that after making sure that the transparency of the image is the problem (see 1).
您使用的图标的真实背景值是多少?是上面显示的灰色调吗?将其设置为紫色以查看是否使用了图像的透明度(Java 默认为灰色背景)。
确保您尝试了 PNG 的两个透明度选项:透明颜色索引以及 alpha 通道。Alpha 通道在 Linux 中很常见,而在 Windows 世界中则不然。
您图标的分辨率太小。以 64x64 或更好的 128x128 分辨率执行。AFAIK 托盘图标没有标准分辨率,即使是这样,也肯定不是 16x16。
您可以尝试的另一种格式是 SVG。只有在确保图像的透明度是问题后才尝试这样做(参见 1)。
See here for background information on this issue: http://www.rasterman.com/index.php?page=News(scroll down to 2 February 2006)
有关此问题的背景信息,请参见此处:http: //www.rasterman.com/index.php?page =News(向下滚动至 2006 年 2 月 2 日)
回答by Falkster
The problem lies in the sun.awt.X11.XTrayIconPeer.IconCanvas.paint() method!
问题出在 sun.awt.X11.XTrayIconPeer.IconCanvas.paint() 方法上!
Before painting, the icon background is amateurishly cleared by simply drawing a rectangle of IconCanvas' background color, to allow image animations.
在绘制之前,通过简单地绘制一个 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();
}
}
}
}
see: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6453521
见:http: //bugs.java.com/bugdatabase/view_bug.do?bug_id=6453521
回答by taksan
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):
对于那些寻找“真正”解决方案的人,我开发了一个小型库,它能够显示托盘图标以尊重透明度,并且还接受 SVG 图标(适用于所有平台):
http://skype2gmail.blogspot.com/2011/05/java-tray-icon-transparency.html
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
https://github.com/taksan/native-tray-adapter
The library work arounds the problem by providing a JNI alternative (with GTK) when running under linux.
该库通过在 linux 下运行时提供 JNI 替代方案(使用 GTK)来解决该问题。
回答by Somatik
JDIC has a tray icon, they might support transparency in linux... https://jdic.dev.java.net/
JDIC 有一个托盘图标,它们可能支持 linux 中的透明度... https://jdic.dev.java.net/
回答by freshfitteds
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
这并不是说 。. . 这很开心,因为它使用默认的 GNOME 主题来呈现透明度 - 它与图像本身无关 - 这是 adobe air / gnome 冲突 - 如果您切换到 gnome 主题,则默认背景为灰色它将是灰色而不是白色。它使用系统默认图像,因此即使设置了它,但面板的主题具有 BG 图像,使其看起来像 vista 一样有光泽,而不是这样做。Adobe Air / Java 不知道您通过透明的主题默认设置,因此它使用系统默认设置
回答by Richard Walton
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)
您是否尝试将其转换为 .PNG(具有透明度)?我发现 Java 往往能更好地支持它们(以我的经验)

