1

I am using JPopupMenu for SystemTray pop up menu but the first problem is how to identify the safest location to place the pop up menu?

The second one How or when to stop display the popup menu? I saw this post but I can't understand the code.

Here is my sample code:


import java.awt.AWTException;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;

public class SampleTrayIcon implements MouseListener, MouseMotionListener {
    /**
     * System Tray
     */
    private final SystemTray tray = SystemTray.getSystemTray();

    /**
     * Note Tray icon
     */
    private final TrayIcon trayIcon;

    /**
     * Note Tray icon popup menu
     */
    private final JPopupMenu popUpMenu = new JPopupMenu();

    /**
     * constructor
     */
    public SampleTrayIcon() {
        // check system tray is supported
        if (!SystemTray.isSupported()) {
            System.err.println("System tray is not supported");
            System.exit(1);
        }

        // Create a TrayIcon image
        BufferedImage image = null;

        // try to read image from resources
        try {
            image = ImageIO.read(new URL("https://i.stack.imgur.com/lM3aS.png"));
        } catch (Exception e) {
            System.err.println("Failed to read image from resources");
            System.exit(1);
        }

        // Create a TrayIcon
        trayIcon = new TrayIcon(image, "QuickNote");

        // set icon auto resize
        trayIcon.setImageAutoSize(true);

        // Create Menu items
        var viewOnHover = new JCheckBoxMenuItem("onHover");
        var aboutMenuItem = new JMenuItem("About");
        var exitMenuItem = new JMenuItem("Exit");

        // add Menuitems to PopUpMenu
        popUpMenu.add(viewOnHover);
        popUpMenu.addSeparator();
        popUpMenu.add(aboutMenuItem);
        popUpMenu.add(exitMenuItem);

        // add mouse listener to tray icon
        trayIcon.addMouseListener(this);
        trayIcon.addMouseMotionListener(this);

        // add tray to system
        try {
            tray.add(trayIcon);
        } catch (AWTException e) {
            System.err.println("TrayIcon could not be added to system tray");
            System.exit(1);
        }
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if(SwingUtilities.isRightMouseButton(e)) {
            System.out.println(e.getPoint());
            popUpMenu.setLocation(e.getPoint());
            popUpMenu.setInvoker(popUpMenu);
            popUpMenu.setVisible(true);
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub
    }

    public static void main(String[] args) {
        new SampleTrayIcon();
    }
}

For Full Repo Please Visit Github

Output of above is following

enter image description here

First one, I need some sugessitions to create an algorithm to place the Jpopupmenu in the correct location This one also goin to help to to place undecorated UTILITY JFrame near the Tray Icon.

Second one is how or when the Jpopupmenu shoud be setvisible to false after placing in the location.

c0der
  • 18,467
  • 6
  • 33
  • 65
srilakshmikanthanp
  • 2,231
  • 1
  • 8
  • 25
  • post an [mre] please – c0der Sep 18 '21 at 17:31
  • @C0der Thanks for your responce, I have added github repo. Looking forward for your response – srilakshmikanthanp Sep 18 '21 at 17:46
  • I hope It is fine if not please let know me so i can create another code from scratch which reproduce the same problem – srilakshmikanthanp Sep 18 '21 at 17:51
  • 2
    [mre] should be posted with the question not on github. – camickr Sep 18 '21 at 18:36
  • @camickr I have edited the code now, Could you please look it now. Thanks – srilakshmikanthanp Sep 18 '21 at 19:03
  • I hope it is now okay or else let me now :-) – srilakshmikanthanp Sep 18 '21 at 19:07
  • 1) Not sure what you mean by "safest location". The popup location is automatically adjusted so that the entire menu is display where you click. 2) If you are wondering how to close the popup when you click "Exit" then read the Swing tutorial on [How to Use the System Tray](https://docs.oracle.com/javase/tutorial/uiswing/misc/systemtray.html) to see how they do it. – camickr Sep 18 '21 at 19:49
  • In order to display the JPopup, the popup needs to be added to a Window. So If you are trying to close it when you click elsewhere on the desktop then I would guess you need access to the Window so you can dispose of the window. After you make the popup visible you can try using: `SwingUtilities.windowForComponent(popUpMenu)` to get the Window. Then try adding an `WindowListener and handle the `windowDeactivated` event to dispose of the window or make the popup invisible. – camickr Sep 18 '21 at 19:54
  • Safest location means correct location to place jpopup, not in top of taskbar like in screenshot. When I click the tray icon. – srilakshmikanthanp Sep 18 '21 at 20:05

1 Answers1

2

You're creating a new JPopupMenu to show on click, but you could instead use the built-in menu for the TrayIcon. It should show in the correct location if you use the PopupMenu instead of the JPopupMenu.

PopupMenu popup = new PopupMenu();
TrayIcon trayIcon = new TrayIcon(createImage("images/bulb.gif", "tray icon"));
MenuItem aboutItem = new MenuItem("About");
popup.add(aboutItem);
trayIcon.setPopupMenu(popup);

https://docs.oracle.com/javase/tutorial/uiswing/misc/systemtray.html

https://docs.oracle.com/javase/7/docs/api/java/awt/TrayIcon.html#setPopupMenu(java.awt.PopupMenu)

Charlie
  • 8,530
  • 2
  • 55
  • 53
  • Thanks for your response, but I need to change the look and feel of the UI but the Popupmenu is not a swing component so it doesn't work. – srilakshmikanthanp Sep 19 '21 at 02:11
  • So what I really want is some suggestions to create an algorithm that calculates the proper location to place Jpopupmenu, Thanks – srilakshmikanthanp Sep 19 '21 at 02:13
  • What do you mean change the look and feel? Here's a similar question: https://stackoverflow.com/questions/14431467/how-do-i-determine-the-position-of-the-system-tray-on-the-screen – Charlie Sep 19 '21 at 03:06
  • I mean this https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html, Thanks – srilakshmikanthanp Sep 19 '21 at 03:08
  • @srilakshmikanthanp the solution posted works so I would recommend accepting the answer. If it doesn't work for you with a certain LAF post a new question with [mre] to show the problem, – c0der Sep 19 '21 at 04:09