Skip to main content

Using JPopupMenu in TrayIcon

Posted by ixmal on May 4, 2006 at 5:23 AM PDT

What's the problem?



Tray icons introduced in Mustang have several properties and methods corresponding to image for the icon, tooltip text, popup menu and ability to show some message to the user. Let's inspect the popup menu more closely.



Popup menu used in tray icons must be an instance of java.awt.PopupMenu. This class represents a menu and allows to insert or delete simple menu items and separators. You cannot change its appearance or even provide an image for particular menu item.


Use JPopupMenu instead



There is another class to create popup menus provided by Swing: javax.swing.JPoupMenu. As all Swing components this class can be customized in any way and makes use of the current Look&Feel. Here is a short illustrating example how it can be used:



First, create a tray icon with a null popup since we're going to use our own one:


    TrayIcon trayIcon = new TrayIcon(someImage, "Tooltip", null);

Then, create a custom JPopupMenu:


    JPopupMenu jpopup = new JPopupMenu();

    JMenuItem javaCupMI = new JMenuItem("Example", new ImageIcon("javacup.gif"));
    jpopup.add(javaCupMI);

    jpopup.addSeparator();

    JMenuItem exitMI = new JMenuItem("Exit");
    jpopup.add(exitMI);

At last, show the popup menu when user clicks a right mouse button on the tray icon:


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



And enjoy the result:



Magic?



You may probably ask me: "What is that magic line 'jpopup.setInvoker(jpopup);' for?" The answer is not as simple as quiestion is, though.



JavaDoc for JPopupMenu.setInvoker() method says that invoker is the component in which the popup menu menu is to be displayed. This property can be set to null, but it leads to popup menu to operate incorrectly.



Setting popup's invoker to itself has some side-effect too. Usually, if you dispose all the windows in your application, Java exits automatically. If you show JPopupMenu with self invoker, it won't, so the only way to terminate the whole application is to call to System.exit().



Both of these issues are well known to Swing team and will be corrected before the Mustang final release. See 6421284 and 6400183 for details.


Related Topics >>

Comments

it doesn't work on linux. (ubuntu 10.04) anybody knows how ...

it doesn't work on linux. (ubuntu 10.04)
anybody knows how fix this?

thanks

finally, I solved this problem changing this line: if ...

necman wrote:
it doesn't work on linux. (ubuntu 10.04)
anybody knows how fix this?

thanks

finally, I solved this problem changing this line:
if (e.isPopupTrigger()) {

for this line:
if (e.getButton() == MouseEvent.BUTTON3) {

trayIcon.addMouseListener(new MouseAdapter() {
                public void mouseReleased(MouseEvent e) {
                    if (e.getButton() == MouseEvent.BUTTON3) {
                        popup.setInvoker(popup);
                        popup.setVisible(true);
                        popup.setLocation(e.getX(), e.getY() - popup.getHeight());
                    }
                }
            });

Using JPopupMenu in TrayIcon

Hi there.

Your code works great excepts in this case:
When you click outside the JpopupMenu after you have clicked and it appeared its doesn't disappear and it should
Do you know how to solve this issue?

Tanks

Hi there.  Nice work Artem .Actually there was an ...

Hi there.

Nice work Artem .Actually there was an issue which was the JPopupMenu remained even after the mouse left the popup.It can be handled by adding a mouseListener and making popup invisible when the mouse left. :) Thanks