package com.jeans.trayicon; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SwingTrayPopup extends JPopupMenu { // Swing popup menu for a TrayIcon WindowsTrayIcon m_Icon; MouseListener m_Listener; public SwingTrayPopup() { } // Attach the menu to a TrayIcon public void setTrayIcon(WindowsTrayIcon icon) { if (icon != null) { m_Icon = icon; m_Icon.initJAWT(); m_Icon.initHook(); m_Listener = new ActivateListener(); m_Icon.addMouseListener(m_Listener); } else { if (m_Icon != null) { m_Icon.removeMouseListener(m_Listener); m_Icon = null; } } } // Show the popup menu (internal use only) public void showMenu(int xp, int yp) { TrayDummyComponent frame = WindowsTrayIcon.getDummyComponent(); // This should show the menu at a better location :-) // * Thanks to Danny for the // setAlwaysOnTop and updateUI() hint WindowsTrayIcon.setMouseClickHook(new ClickListener()); WindowsTrayIcon.setAlwaysOnTop(frame, true); Dimension d = getPreferredSize(); show(frame, xp-d.width, yp-d.height); updateUI(); } // Test if mouse is in menu or submenu private boolean componentContains(JComponent comp, int xp, int yp) { if (!comp.isVisible()) return false; Point pt = comp.getLocationOnScreen(); Dimension s = comp.getSize(); boolean contains = xp > pt.x && xp < pt.x+s.width && yp > pt.y && yp < pt.y+s.height; if (contains) return true; for (int i = 0; i < comp.getComponentCount(); i++) { JComponent child = (JComponent)comp.getComponent(i); if (child instanceof JMenu) { JMenu submenu = (JMenu)child; if (componentContains(submenu.getPopupMenu(), xp, yp)) { return true; } } } return false; } // Test if mouse is in menu or submenu private boolean menuContains(int xp, int yp) { return componentContains(this, xp, yp); } // Callback listener handles icon events (Mouse hook) private class ClickListener extends MouseAdapter { public void mousePressed(MouseEvent evt) { if (!menuContains(evt.getX(), evt.getY())) { setVisible(false); WindowsTrayIcon.setMouseClickHook(null); } } } // Callback listener handles icon events private class ActivateListener extends MouseAdapter { public void mousePressed(MouseEvent evt) { if (evt.isPopupTrigger() && (evt.getModifiers() & MouseEvent.BUTTON2_MASK) != 0 && evt.getClickCount() == 1) { showMenu(evt.getX(), evt.getY()); } } } }