当我在Java中左键单击TrayIcon时,如何显示PopupMenu?

目前,当我右键单击SystemTray中的TrayIcon时,PopupMenu将会出现。 但是,当我左键单击TrayIcon时,我希望它也能这样做。

我想我可以通过在TrayIcon上使用mouseListener来实现这一点,但我不知道在mouseClicked事件中调用什么方法来实现所需的结果。

icon = new TrayIcon(img, tooltip, popup); icon.addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e) { popup.setEnabled(true); } }); 

当我左键单击TrayIcon时,使用setEnabled()方法不会显示弹出菜单。 它实际上没有明显的效果。 我想知道我应该在mouseClicked()体中使用什么方法,以便在左键单击时弹出窗口显示。

基本上,在鼠标监听器中,您需要确定按下了哪个按钮(可选,多少次)。

关键的代码是……

 if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 1) { ... } 

我还添加了一些额外的代码,以确保弹出窗口不会覆盖任务栏并显示在屏幕的可视区域内(这是我的一个选择;))

 public class TestTrayIcon02 { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ex) { } try { final TrayIcon ti = new TrayIcon(ImageIO.read(getClass().getResource("/Smiley.png")), "Have a nice day"); final JPopupMenu popup = new JPopupMenu(); JMenuItem mi = new JMenuItem("Get me some"); mi.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { SystemTray.getSystemTray().remove(ti); System.exit(0); } }); popup.add(mi); ti.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 1) { Rectangle bounds = getSafeScreenBounds(e.getPoint()); Point point = e.getPoint(); int x = point.x; int y = point.y; if (y < bounds.y) { y = bounds.y; } else if (y > bounds.y + bounds.height) { y = bounds.y + bounds.height; } if (x < bounds.x) { x = bounds.x; } else if (x > bounds.x + bounds.width) { x = bounds.x + bounds.width; } if (x + popup.getPreferredSize().width > bounds.x + bounds.width) { x = (bounds.x + bounds.width) - popup.getPreferredSize().width; } if (y + popup.getPreferredSize().height > bounds.y + bounds.height) { y = (bounds.y + bounds.height) - popup.getPreferredSize().height; } popup.setLocation(x, y); popup.setVisible(true); } } }); SystemTray.getSystemTray().add(ti); } catch (Exception ex) { ex.printStackTrace(); } } }); } public static Rectangle getSafeScreenBounds(Point pos) { Rectangle bounds = getScreenBoundsAt(pos); Insets insets = getScreenInsetsAt(pos); bounds.x += insets.left; bounds.y += insets.top; bounds.width -= (insets.left + insets.right); bounds.height -= (insets.top + insets.bottom); return bounds; } public static Insets getScreenInsetsAt(Point pos) { GraphicsDevice gd = getGraphicsDeviceAt(pos); Insets insets = null; if (gd != null) { insets = Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration()); } return insets; } public static Rectangle getScreenBoundsAt(Point pos) { GraphicsDevice gd = getGraphicsDeviceAt(pos); Rectangle bounds = null; if (gd != null) { bounds = gd.getDefaultConfiguration().getBounds(); } return bounds; } public static GraphicsDevice getGraphicsDeviceAt(Point pos) { GraphicsDevice device = null; GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice lstGDs[] = ge.getScreenDevices(); ArrayList lstDevices = new ArrayList(lstGDs.length); for (GraphicsDevice gd : lstGDs) { GraphicsConfiguration gc = gd.getDefaultConfiguration(); Rectangle screenBounds = gc.getBounds(); if (screenBounds.contains(pos)) { lstDevices.add(gd); } } if (lstDevices.size() > 0) { device = lstDevices.get(0); } else { device = ge.getDefaultScreenDevice(); } return device; } } 

您要做的事情显然是不可能的:

你不能用show方法显示PopupMenu ,因为你需要指定一个JComponent但你的TrayIcon不是一个(虽然TrayIcon仍然设法做到这一点很奇怪,所以显然有一种方法,不要问我虽然.. )。 所以,正如MadProgrammer建议的那样,你应该尝试使用JPopupMenu 。 不要将它添加到TrayIcon因为这是不可能的,但是通过向TrayIcon添加MouseListener来显示JPopupMenu 。 这应该够了吧:

 final TrayIcon tray = new TrayIcon( img, tooltip, null); final JPopupMenu menu = new JPopupMenu(); ... // your menu initialization. tray.addMouseListener( new MouseAdapter() { @Override public void mouseClicked(MouseEvent evt) { menu.setLocation( evt.getPoint() ); menu.setVisible( true ); } }