sclass tablePopupMenu_Maker { new L menuMakers; } static Map tablePopupMenu_map = newWeakHashMap(); static new ThreadLocal tablePopupMenu_mouseEvent; static new ThreadLocal tablePopupMenu_first; // menuMaker = voidfunc(JPopupMenu, int row) static void tablePopupMenu(final JTable table, fO menuMaker) { final bool first = isTrue(getAndClearThreadLocal(tablePopupMenu_first)); swing { tablePopupMenu_Maker maker = tablePopupMenu_map.get(table); if (maker == null) { tablePopupMenu_map.put(table, maker = new tablePopupMenu_Maker); final tablePopupMenu_Maker _maker = maker; table.addMouseListener(new MouseAdapter { public void mousePressed(MouseEvent e) { displayMenu(e); } public void mouseReleased(MouseEvent e) { displayMenu(e); } void displayMenu(MouseEvent e) { if (!e.isPopupTrigger()) ret; new JPopupMenu menu; int row = table.rowAtPoint(e.getPoint()); if (table.getSelectedRowCount() < 2) table.setRowSelectionInterval(row, row); int modelRow = convertTableRowToModel(table, row); int emptyCount = menu.getComponentCount(); tablePopupMenu_mouseEvent.set(e); for (O menuMaker : _maker.menuMakers) pcallF(menuMaker, menu, modelRow); vmBus_send('showingPopupMenu, table, menu); // show menu if any items in it if (menu.getComponentCount() != emptyCount) menu.show(e.getComponent(), e.getX(), e.getY()); } }); } if (first) maker.menuMakers.add(0, menuMaker); else maker.menuMakers.add(menuMaker); } }