package org.limewire.ui.swing.action; import java.awt.Component; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.Action; import javax.swing.JComponent; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; public class PopupUtil { public static JPopupMenu addPopupMenus(JComponent component, Action... actions) { return addPopupMenus(component, AlwaysShowPopup.get(), actions); } public static JPopupMenu addPopupMenus(JComponent component, PopupDecider decider, Action... actions) { JPopupMenu menu = new JPopupMenu(); for(Action action : actions) { menu.add(action); } PopupListener popupListener = new PopupListener(menu, decider); component.addMouseListener(popupListener); menu.addPopupMenuListener(popupListener); return menu; } private static class AlwaysShowPopup implements PopupDecider { private static AlwaysShowPopup INSTANCE = new AlwaysShowPopup(); private AlwaysShowPopup(){} public static PopupDecider get() { return INSTANCE; } @Override public boolean shouldDisplay(MouseEvent e) { return true; } } /** * Handles displaying the popup. Also sets the enablement of each menuitem in a JPopupMenu * based on its action's enablement. */ private static class PopupListener extends MouseAdapter implements PopupMenuListener { private final JPopupMenu popup; private final PopupDecider decider; public PopupListener(JPopupMenu popup, PopupDecider decider) { this.popup = popup; this.decider = decider; } @Override public void mousePressed(MouseEvent e) { maybeShowPopup(e); } @Override public void mouseReleased(MouseEvent e) { maybeShowPopup(e); } private void maybeShowPopup(MouseEvent e) { if (e.isPopupTrigger() && decider.shouldDisplay(e)) { popup.show(e.getComponent(), e.getX(), e.getY()); } } @Override public void popupMenuCanceled(PopupMenuEvent e) { //no-op } @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { //no-op } @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { for(Component comp : popup.getComponents()) { if (comp instanceof JMenuItem) { JMenuItem item = (JMenuItem)comp; Action action = item.getAction(); if (action != null) { item.setEnabled(action.isEnabled()); } //This is a hack to let the action modify aspects about the item before display if (action instanceof ItemNotifyable) { ItemNotifyable notifyable = (ItemNotifyable)action; notifyable.notifyItem(item); } } } } } }