How do I get a PopupMenu to show up when I left-click on a TrayIcon in Java?

前端 未结 2 1838
臣服心动
臣服心动 2020-12-10 23:39

Currently, the PopupMenu will show up when I right-click on the TrayIcon in the SystemTray. However, I want it to do the same when I left-click on the TrayIcon.

I th

相关标签:
2条回答
  • 2020-12-10 23:58

    Basically, in your mouse listener, you need to determine which button was pressed (and optional, how many times).

    The critical piece of code is this...

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

    I've also included some additional code that makes sure the popup does not cover the task bar and is displayed within the viewable area of the screen (it's a nit pick of mine ;))

    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<GraphicsDevice> lstDevices = new ArrayList<GraphicsDevice>(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;
    
        }
    }
    
    0 讨论(0)
  • 2020-12-11 00:10

    What you're trying to do is apparently not possible:

    You cannot show the PopupMenu with its show method since you need to specify a JComponent but your TrayIcon isn't one (weird enough though that TrayIcon still manages to do it, so apparently there is a way, don't ask me though..). So, as MadProgrammer suggested, you should try using JPopupMenu instead. Don't add it to your TrayIcon for that won't be possible, but display your JPopupMenu by adding a MouseListener to your TrayIcon. That should do the trick:

    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 );
        }
    }
    
    0 讨论(0)
提交回复
热议问题