Java TrayIcon, используя изображение с прозрачным фоном
Я использую следующий код для установки иконки в трее в Windows и Linux. Он прекрасно работает в Windows и нормально работает в Linux. В Linux (Ubuntu) моя панель настроена (несколько) прозрачной, и когда я добавляю GIF (с прозрачным фоном), фон значка отображается серым и уродливым (см. Изображение, зеленый ромб "!").... Есть идеи, как сделать изображение GIF, которое я добавляю, "сохранить" его прозрачный фон?
http://unarm.org/stackru/panel_task.jpg
и изображение, которое я использую, если вы хотите проверить:
http://unarm.org/stackru/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 ответов
Скорее всего, эта проблема не может быть решена. Это зависит от того, хорошо ли работает Java в создании подокна в Linux или нет. Если Jave делает это неправильно, прозрачность уже теряется при рисовании изображения.
Каково реальное фоновое значение иконки, которую вы используете? Это серый тон, показанный выше? Установите фиолетовый цвет, чтобы увидеть, используется ли прозрачность изображения (для Java по умолчанию используется серый фон) или нет.
Убедитесь, что вы опробовали оба варианта прозрачности PNG: прозрачный индекс цвета, а также альфа-канал. Альфа-канал очень распространен в Linux, но не так в мире Windows.
Разрешение вашей иконки слишком мало. Сделайте это в 64x64 или лучше 128x128. У AFAIK нет стандартного разрешения для значков в трее, и даже если это так, оно определенно не 16x16.
Другой формат, который вы можете попробовать, это SVG. Попробуйте только после того, как убедитесь, что проблема заключается в прозрачности изображения (см. 1).
Смотрите здесь дополнительную информацию по этому вопросу: http://www.rasterman.com/index.php?page=News (прокрутите до 2 февраля 2006 г.)
Проблема заключается в методе 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
Для тех, кто ищет "реальное" решение, я разработал небольшую библиотеку, которая способна отображать значок в трее с учетом прозрачности, а также принимает значки SVG (для всех платформ):
http://skype2gmail.blogspot.com/2011/05/java-tray-icon-transparency.html
Это библиотека с открытым исходным кодом, и исходный код можно найти здесь:
https://github.com/taksan/native-tray-adapter
Библиотека обходит проблему, предоставляя альтернативу JNI (с GTK) при работе под Linux.
У JDIC есть иконка в трее, они могут поддерживать прозрачность в Linux... https://jdic.dev.java.net/
Это не то.,, это происходит потому, что для рендеринга прозрачности используется тема GNOME по умолчанию - она не имеет никакого отношения к самому изображению - это конфликт Adobe Air / GNOME - если вы переключитесь на тему GNOME, если фон по умолчанию серый, тогда это было бы серым вместо белого. Он использует системное изображение по умолчанию, поэтому, даже если он был установлен, но тема для панели имеет изображение BG, чтобы оно выглядело, например, как глянцевый, как vista, чем это было бы. Adobe Air / Java не знает, что вы переопределяете тему по умолчанию прозрачностью и поэтому используете системную настройку по умолчанию.
Вы пытались вместо этого преобразовать его в формат.PNG (с прозрачностью)? Я обнаружил, что они, как правило, лучше поддерживаются Java (по моему опыту)