sclass listPopupMenu_Maker { new L menuMakers; } static Map listPopupMenu_map = new WeakHashMap; static new ThreadLocal listPopupMenu_mouseEvent; static new ThreadLocal listPopupMenu_first; // menuMaker = voidfunc(JPopupMenu, S item) static void listPopupMenu(final JList list, fO menuMaker) { final bool first = isTrue(getAndClearThreadLocal(listPopupMenu_first)); awtIfNecessary { listPopupMenu_Maker maker = listPopupMenu_map.get(list); if (maker == null) { listPopupMenu_map.put(list, maker = new listPopupMenu_Maker); final listPopupMenu_Maker _maker = maker; list.addMouseListener(new MouseAdapter { public void mousePressed(MouseEvent e) { displayMenu(e); } public void mouseReleased(MouseEvent e) { displayMenu(e); } void displayMenu(MouseEvent e) { if (e.isPopupTrigger()) { new JPopupMenu menu; int idx = list.locationToIndex(e.getPoint()); O item = list.getModel().getElementAt(idx); list.setSelectedIndex(idx); int emptyCount = menu.getComponentCount(); listPopupMenu_mouseEvent.set(e); for (O menuMaker : _maker.menuMakers) pcallF(menuMaker, menu, item); // show menu if any items in it if (menu.getComponentCount() == emptyCount) ret; vmBus_send('showingPopupMenu, list, menu); menu.show(e.getComponent(), e.getX(), e.getY()); } } }); } if (first) maker.menuMakers.add(0, menuMaker); else maker.menuMakers.add(menuMaker); } }