Java TrayIcon с использованием изображения с прозрачным фоном

StackOverflow https://stackoverflow.com/questions/331407

Вопрос

Я использую следующий код для установки значка на панели задач в 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);
  }
}
Это было полезно?

Решение

Скорее всего, эта проблема не может быть решена. Это зависит от того, хорошо ли работает 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 & # 8217; цвет фона, чтобы разрешить анимацию изображения.

    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. делать? 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/

    Вы пытались вместо этого преобразовать его в формат .PNG (с прозрачностью)? Я обнаружил, что они, как правило, лучше поддерживаются Java (по моему опыту)

    Это не то ...это происходит потому, что для рендеринга прозрачности используется тема GNOME по умолчанию — она не имеет ничего общего с самим изображением — это конфликт Adobe Air / gnome — если вы переключитесь на тему gnome, где фон по умолчанию серый, тогда он был бы серым, а не белым.Он использует изображение системы по умолчанию, поэтому, даже если оно было установлено, но тема для панели имеет фоновое изображение, чтобы оно выглядело глянцевым, как, например, Vista, тогда оно будет делать это.Adobe Air/Java не знает, что вы превысили прозрачность темы по умолчанию, и поэтому использует системную настройку по умолчанию.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top