3

I'm trying to create system tray icon with two popup menus, one should be called with left mouse button and another with right. AWT offers simple way to create PopupMenu but it's not posible to call menu with left mouse button without making invisible JFrame or something. So, I find out that swing JPopupMenu can be called by any of mouse buttons. But JPopupMenu have bug (I don't know if this is really a bug or I'm not so good in Java) that it's not hiding when I press mouse outside JPopupMenu. I've tried to use mouse listener's function mouseExited, but it works only on JPopupMenu border. If mouse leaves JPopupMenu border it hides and I can't press any of JPopupMenu buttons. Maybe, anyone had the same problem and could help me find out how to make it work right.

public static JPopupMenu jpm;
public static TrayIcon ti;

public static void main(String args[]) throws IOException, AWTException,
        ClassNotFoundException, InstantiationException,
        IllegalAccessException, UnsupportedLookAndFeelException {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    SystemTray st = SystemTray.getSystemTray();
    Image icon = ImageIO.read(SipLogin.class
            .getResource("/resources/phone-yellow-small.png"));

    ti = new TrayIcon(icon, "Sip login", null);

    jpm = new JPopupMenu();

    JMenuItem jmi1 = new JMenuItem("JMenuItem1");
    JMenuItem jmi2 = new JMenuItem("JMenuItem2");
    JMenuItem jmi3 = new JMenuItem("JMenuItem3");
    JMenuItem jmi4 = new JMenuItem("JMenuItem4");



    ti.addMouseListener(new MouseAdapter() {
        public void mouseReleased(MouseEvent e) {
            if (e.isPopupTrigger()) {
                jpm.setLocation(e.getX(), e.getY());
                jpm.setInvoker(jpm);
                jpm.setVisible(true);
            }
        }
    });

    jpm.add(jmi1);
    jpm.add(jmi2);
    jpm.add(jmi3);
    jpm.add(jmi4);

    jpm.addMouseListener(new MouseAdapter() {
        public void mouseExited(MouseEvent e) {
            jpm.setVisible(false);
        }
    });

    st.add(ti);




}
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
Algirdas
  • 33
  • 4
  • mKorbel, he only wants one to be shown at a time, depending on which mouse button gets pressed. – predi Jul 18 '13 at 10:54
  • I know that only one JPopup can be visible, but i can't make it hide like PopupMenu, witch hides when mouse pressed somewhere outside menu. – Algirdas Jul 18 '13 at 10:59
  • Try this [thread](http://stackoverflow.com/q/7461477/1057230), not sure though will it fulfill your requirement, but just in case :-) – nIcE cOw Jul 18 '13 at 11:00
  • I would use an undecorated JDialog and Swing timer to detect when the mouse has left it. Note that you have to take into account that when the mouse enters a sub-component, it is also leaving it's parent component! That's why `mouseExited` isn't working for ya.. – predi Jul 18 '13 at 11:08
  • Thank you, for your answers. predi, but maybe it's possible to add mouse listener for all components(component and it's sub-components). That would be the easiest way to make it work as it should. Using JDialogs and timers just make source code much longer and harder to understand... – Algirdas Jul 18 '13 at 11:47
  • [This answer](http://stackoverflow.com/a/18380840/878469) might also help. – predi Aug 22 '13 at 12:52

2 Answers2

0

Take that one mouse listener and separate the left and right click:

Change from

ti.addMouseListener(new MouseAdapter() {
    public void mouseReleased(MouseEvent e) {
        if (e.isPopupTrigger()) {
            jpm.setLocation(e.getX(), e.getY());
            jpm.setInvoker(jpm);
            jpm.setVisible(true);
        }
    }
});

to

ti.addMouseListener(new MouseAdapter() {
    public void mouseReleased(MouseEvent e) {
        if(e.getclickCount < 2){
            if(e.getButton().equals(MouseEvent.Button1){
                showPopup1();
            }
            if(e.getButton().equals(MouseEvent.Button3){
                showPopup2();
            }
        }
    }
});
gantners
  • 471
  • 4
  • 16
0

thanks for very useful conversation, but I need to add some words:

Sometimes when you add menuItems the JPopupMenu behaves in unpredictable manner (it is not closed, when you mouseover your mouse from it).

In this case you need to delete the mouse motion listeners from your menu items

JMenuItem jmi1 = new JMenuItem("JMenuItem1");

jmi1.removeMouseMotionListener(jmi1.getMouseMotionListeners()[0]);
jmi1.removeMouseListener(jmi1.getMouseListeners()[0]);
Lord Nighton
  • 1,670
  • 21
  • 15