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

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

person Jack    schedule 01.12.2008    source источник
comment
Я думаю, вам придется переключиться на квадратную иконку :( :( Я рад, что вы нашли SystemTray хорошей альтернативой для вашего приложения Deamon. Что это за новое приложение? :) Это секрет?   -  person OscarRyz    schedule 01.12.2008
comment
вопрос, выглядит ли это изображение значка непрозрачным при отображении в другом месте? Веб-страница, например?   -  person OscarRyz    schedule 01.12.2008
comment
Это своего рода секрет, но я планирую выпустить его, скорее всего, как проект с открытым исходным кодом, довольно скоро. Изображение выглядит нормально, когда отображается в любом другом месте. Вы можете видеть, что я встроил ниже изображения моей панели задач и над кодом.   -  person Jack    schedule 01.12.2008


Ответы (6)


Скорее всего, эта проблема не может быть решена. Это зависит от того, хорошо ли Java справляется с созданием подокна в трее в Linux или нет. Если Jave сделает это неправильно, прозрачность уже будет потеряна при отрисовке изображения.

  1. Каково реальное фоновое значение значка, который вы используете? Это серый тон, показанный выше? Установите фиолетовый цвет, чтобы увидеть, используется ли прозрачность изображения (по умолчанию для Java используется серый фон) или нет.

  2. Убедитесь, что вы попробовали оба варианта прозрачности PNG: прозрачный цветовой индекс, а также альфа-канал. Альфа-канал очень распространен в Linux, но не в мире Windows.

  3. Разрешение вашего значка слишком маленькое. Делайте это в разрешении 64х64 или лучше 128х128. На мой взгляд стандартного разрешения для иконок в трее нет, а если и есть, то уж точно не 16х16.

  4. Другой формат, который вы можете попробовать, это SVG. Попробуйте это только после того, как убедитесь, что проблема заключается в прозрачности изображения (см. 1).

Справочную информацию по этому вопросу см. здесь: http://www.rasterman.com/index.php?page=News (прокрутите вниз до 2 февраля 2006 г.)

person ypnos    schedule 01.12.2008
comment
Спасибо. 1) Он прозрачный (клетчатый фон)... Я попытался сделать его фиолетовым, и он появился в трее как фиолетовый. 2) Я пробовал все разные варианты PNG при сохранении в GIMP, и все они имели одинаковый результат 3) Я также пробовал значки разных размеров с тем же результатом 4) Я пробовал SVG ... все отображалось серым. - person Jack; 01.12.2008
comment
Извините, закончилось место. Спасибо за идеи. У вас случайно нет других идей? - person Jack; 01.12.2008
comment
Поэтому, если Java на самом деле не понимает прозрачность изображения, это действительно странно. Возможно, попробуйте нарисовать изображение внутри приложения. Или, возможно, есть определенные варианты этих изображений. Я не знаю, что делать еще (возможно, доступен другой API, кроме SystemTray?) - person ypnos; 02.12.2008

Проблема заключается в методе 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

person Falkster    schedule 07.10.2010

Для тех, кто ищет «настоящее» решение, я разработал небольшую библиотеку, способную отображать значок в трее с соблюдением прозрачности, а также принимать значки SVG (для всех платформ):

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

Это библиотека с открытым исходным кодом, и исходный код можно найти здесь:

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

Библиотека решает эту проблему, предоставляя альтернативу JNI (с GTK) при работе под Linux.

person taksan    schedule 24.05.2011
comment
Я заметил, что этот репозиторий GitHub не проявлял особой активности с 2011 года. Это все еще жизнеспособное решение? Я задокументировал некоторые другие проблемы с лотком платформы здесь: stackoverflow.com/a/35919788/3196753. Было бы неплохо иметь надежно работающее кроссплатформенное решение. - person tresf; 07.04.2016
comment
В некоторых языковых экосистемах (например, в мирах Erlang, Haskell и Clojure) отсутствие активности и открытых проблем означает, что он не был сломан с самого начала. Я ищу библиотеки с уменьшающимся количеством проблем, в идеале с нулевым. - person Petrus Theron; 18.05.2018

У JDIC есть значок в трее, они могут поддерживать прозрачность в Linux... https://jdic.dev.java.net/

person Somatik    schedule 02.12.2008

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

person Richard Walton    schedule 01.12.2008

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

person freshfitteds    schedule 21.04.2010
comment
Я просто проверяю эту теорию, и она действительно верна - person freshfitteds; 21.04.2010