问题描述
我正在尝试开发由系统托盘图标提供的Mac OsX应用程序,因此在第一次使用最简单的代码实现它之后,我注意到mac osX上的每个应用程序托盘图标(包括系统和用户应用程序)( 10.8)允许激活相对弹出菜单,同时左右键单击它,但只有左侧(MouseEvent.BOTTON1)按钮导致弹出菜单下拉。这是我的代码:
I'm trying to develop a Mac OsX app provided by a system tray icon, so after the first attempt with the simplest code to achieve it I noticed that every apps tray icon's (both system and user apps) on mac osX (10.8) allows to activate the relative popup menu with both left and right click on it but with my project only the left (MouseEvent.BOTTON1) button causes the popup menu to pulldown. Here's my code:
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()方法在右键单击事件上触发左按钮事件,如下所示:
but how I already said, only through left mouse button click.So during a further attempt I've tried to mimic the behavior of the tray icons of every other apps using a MouseListener and firing a left button event on right click event using dispatchEvent() method like so:
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 Class不是Component子类,因此MouseEvent的源是null我得到一个NPE。这是我的MouseListener:
the event will handled by the mouse listener but obviously TrayIcon Class is not a Component subclass and therefore the source of MouseEvent is null and I get a NPE. Here's my 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) {}
对不起我的英文,我希望那些曾经有过这类项目经验的人可以帮助我。我搜索了几个小时,但没有运气。谢谢您的帮助。
Sorry for my english, I hope that someone who have ever had some experience with that kind of projects can help me. I've searched for hours but with no luck. Thank You for your help.
推荐答案
编辑:现在有一个库正在修复所有这些:
There's now a library working to fix all of this here: https://github.com/dorkbox/SystemTray
目前在Mac + Java上根本无法做到这一点。使用反射来调用底层触发器似乎没有帮助。这是一个错误。
This is simply not possible on Mac + Java currently. Using reflection to invoke the underlying triggers doesn't seem to help. This is a bug.
在某些Java版本(7u79)中,即使这已经破了,修正了......
Even this is broken in some Java versions (7u79), fixed with an upgrade...
跨平台TrayIcon支持:
虽然稍微偏离主题,我想补充一下,一些项目使用 JXTrayIcon
来完成Linux / Windows等中的一些花哨的下拉菜单。这些也是尽管以及错误。但是在Mac上,任何使用装饰菜单的尝试都会导致菜单延迟,对最终用户来说是一种非常糟糕的体验。我解决的解决方案是使用。 Java TrayIcon支持迫切需要重写。 JavaFX声称可以帮助这项计划,但它是。与此同时,我坚持。
Albeit slightly off-topic, I wanted to add, some projects use a JXTrayIcon
to accomplish some fancy drop-down menus in Linux/Windows, etc. These also cause problems on Mac despite a click-bug it already suffers from today as well as bugs with Gnome3 requiring a completely separate hack. But on Mac, any attempt to use the decorated menus causes the menu to linger and is a very bad experience for the end-user. The solution I settled on was to use AWT for Mac, Swing for everything else. The Java TrayIcon support is in dire need of a rewrite. JavaFX claims to help this initiative, but it's staged for Java 9. In the mean time, I'm sticking to OS-dependent hacks.
其他平台的相关托盘问题
此外,一些Linux发行版(如Ubuntu)默认在Unity桌面中删除了托盘图标,这引起了进一步的麻烦。
Furthermore, some Linux distributions like Ubuntu have removed the tray icon by default in the Unity desktop, causing further headaches. https://askubuntu.com/a/457212/412004
此外,图标的透明度在Gtk / Gnome或Qt / KDE驱动的桌面上被替换为灰色(OpenJDK和Oracle JRE都受此影响)
In addition, the transparency of the icon is replaced with a gray color on Gtk/Gnome or Qt/KDE powered desktops (Both OpenJDK and Oracle JRE suffer this)https://stackoverflow.com/a/3882028/3196753http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6453521
此外,Gnome3支持的桌面可能会显示在错误的角落,根本不显示,或者它可能显示但是无法点击(OpenJDK和Oracle JRE都会受此影响)
In addition, Gnome3 powered desktops may show it in the wrong corner, not at all, or it may show but be unclickable (Both OpenJDK and Oracle JRE suffer this)https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=660157https://bugzilla.redhat.com/show_bug.cgi?id=1014448
除此之外,Windows上的高DPI屏幕还有一个错误的错误:
In addition to that, high-DPI screens on Windows have a bug that draws the icon incorrectly: Windows 8 Distorts my TrayIcon
总而言之,Java系统托盘的状态没关系,但由于因素的组合在JDK6,JDK7和JDK8中非常分散和错误。
So in summary, the state of the System Tray in Java is OK, but due to the combination of factors is quite fragmented and buggy in JDK6, JDK7 and JDK8.
这篇关于java:在Mac OsX上右键单击禁用TrayIcon的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!