Подтвердить что ты не робот

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

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

Ответ 1

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

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

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

  • Разрешение вашего значка слишком мало. Сделайте это в 64x64 или выше 128x128. AFAIK нет стандартного разрешения для значков лотков, и даже если это так, это, конечно, не 16x16.

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

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

Ответ 2

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

Ответ 3

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

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

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

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

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