Java: щелчок правой кнопкой мыши на TrayIcon отключен на Mac OsX
Я пытаюсь разработать приложение для Mac OsX с помощью иконки в системном трее, поэтому после первой попытки с простым кодом для этого я заметил, что пиктограммы на каждом трее приложений (как системных, так и пользовательских) на Mac OSX (10.8) позволяют чтобы активировать относительное всплывающее меню левой и правой кнопкой мыши, но в моем проекте только левая кнопка (MouseEvent.BOTTON1) вызывает раскрывающееся меню. Вот мой код:
public class SystemTrayDemo
{
private SystemTray tray;
private TrayIcon tray_icon;
public SystemTrayDemo()
{
if (!SystemTray.isSupported())
{
JOptionPane.showMessageDialog(null, "System tray not supported!");
return;
}
else
tray = SystemTray.getSystemTray();
final PopupMenu popup = new PopupMenu();
MenuItem exit = new MenuItem("Exit");
exit.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if (tray != null)
{
tray.remove(tray_icon);
System.exit(0);
}
}
});
popup.add(exit);
//add tray icon
tray_icon = new TrayIcon(getIcon("images/wifi.png"), "Open documents...", popup);
tray_icon.setImageAutoSize(true);
try
{
tray.add(tray_icon); // adds icon
}
catch (AWTException ex) {}
}
private Image getIcon(String name)
{
URL _url = getClass().getResource(name);
return new ImageIcon(_url).getImage();
}
public static void main(String args[])
{
new SystemTrayDemo();
}
}
но, как я уже сказал, только с помощью левой кнопки мыши. Поэтому во время следующей попытки я попытался имитировать поведение значков на панели задач всех других приложений, используя MouseListener и вызывая событие левой кнопки при событии правой кнопки мыши, используя метод dispatchEvent(), например так:
public static void fireMouseEvent(Component c)
{
MouseEvent me = new MouseEvent(c, // which
MouseEvent.MOUSE_CLICKED, // what
System.currentTimeMillis(), // when
MouseEvent.BUTTON1_MASK, // no modifiers
0, 0, // where: at (10, 10}
1, // only 1 click
true); // popup trigger
c.dispatchEvent(me);
}
событие будет обработано слушателем мыши, но, очевидно, класс TrayIcon не является подклассом компонента, и поэтому источник MouseEvent имеет значение null, и я получаю NPE. Вот мой MouseListener:
class MouseAdapt extends java.awt.event.MouseAdapter
{
public void mouseClicked(java.awt.event.MouseEvent me)
{
int button = me.getButton();
if(button == java.awt.event.MouseEvent.BUTTON3)
{
fireMouseEvent(me.getComponent());
}
}
}
try
{
tray.add(tray_icon); // aggiungi l'icona
tray_icon.addMouseListener(new MouseAdapt());
}
catch (AWTException ex) {}
Извините за мой английский, я надеюсь, что тот, кто когда-либо имел опыт работы с подобными проектами, сможет мне помочь. Я искал несколько часов, но безуспешно. Спасибо за помощь.
1 ответ
Изменить: теперь есть библиотека, чтобы исправить все это здесь: https://github.com/dorkbox/SystemTray
чтобы активировать относительное всплывающее меню [TrayIcon], щелкните левой и правой кнопкой мыши
Это просто невозможно на Mac + Java в настоящее время. Использование отражения для вызова основных триггеров, похоже, не помогает. Это ошибка.
https://bugs.openjdk.java.net/browse/JDK-8041890
только левая кнопка (MouseEvent.BOTTON1) вызывает раскрывающееся меню. Вот мой код
Даже это не работает в некоторых версиях Java (7u79), исправленных с помощью обновления...
https://bugs.openjdk.java.net/browse/JDK-7158615
Кроссплатформенная поддержка TrayIcon:
Хоть и немного не по теме, хотел бы добавить, некоторые проекты используют JXTrayIcon
выполнить некоторые изящные выпадающие меню в Linux/Windows и т. д. Это также вызывает проблемы на Mac, несмотря на ошибку щелчка, от которой он уже страдает сегодня, а также ошибки с Gnome3, требующие совершенно отдельного взлома. Но на Mac любая попытка использовать оформленные меню заставляет меню задерживаться и является очень плохим опытом для конечного пользователя. Решением, на котором я остановился, было использование AWT для Mac, Swing для всего остального. Поддержка Java TrayIcon остро нуждается в переписывании. JavaFX утверждает, что помогает этой инициативе, но он подготовлен для Java 9. В то же время я придерживаюсь OS-зависимых хаков.
Связанные проблемы с лотками для других платформ
Кроме того, некоторые дистрибутивы Linux, такие как Ubuntu, по умолчанию убирают значок в трее на рабочем столе Unity, что вызывает дополнительные головные боли. /questions/13246050/ispolzuya-zagolovki-http/13246065#13246065
Кроме того, прозрачность значка заменяется серым цветом на рабочих столах с поддержкой Gtk/Gnome или Qt/KDE (страдают как OpenJDK, так и Oracle JRE) /questions/45557654/java-trayicon-ispolzuya-izobrazhenie-s-prozrachnyim-fonom/45557672#45557672 http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6453521
Кроме того, рабочие столы с поддержкой Gnome3 могут показывать его не в том углу, или вообще не показывать, но это может быть неактивным (страдают как OpenJDK, так и Oracle JRE) https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=660157 https://bugzilla.redhat.com/show_bug.cgi?id=1014448
В дополнение к этому на экранах с высоким разрешением в Windows есть ошибка, которая неправильно отображает значок: Windows 8 искажает мой TrayIcon
Итак, в итоге, состояние System Tray в Java в порядке, но из-за сочетания факторов в JDK6, JDK7 и JDK8 довольно фрагментированы и глючат.