DomUI

PopupMenu2

A small menu that opens at a component, does one thing and disappears again.

button.setClicked(() -> {
    PopupMenu2 pm = new PopupMenu2(a);                  // Opens at the button
    pm.text("Play it").icon(Icon.faMusic).click(() -> play(album)).append();
    pm.text("Add to the cart").icon(Icon.faShoppingCart).click(() -> order(album)).append();
    pm.show(a);
});

One item at a time

An item is described by chaining calls and then appended, which is what actually adds it:

Call What it says about the next item
text(String) / text(IBundleCode, Object...) its text
icon(IIconRef) its icon
hint(String) / hint(IBundleCode, Object...) its tooltip
click(IExecute) what choosing it does
disableReason(String) it cannot be chosen, and why
testId(String) the test id on its row, for Selenium
append() ...and now it is an item

Every one of those refuses to overwrite a value that is already set, so a forgotten append() throws instead of quietly merging two items into one. An item needs at least a text or an icon; without either, append() throws as well.

A disabled item is drawn greyed out and does not answer a click. Its reason becomes its tooltip - after the hint, if it has one.

The menu adapts to what is in it. An icon column is written only when some item has an icon, and a text column only when some item has a text; a menu of nothing but icons is a row of icons with tooltips, not a row of icons and empty space.

Showing it

Call What it does
new PopupMenu2(NodeContainer owner) the menu opens at this component
above() / below() which side of the owner it opens on; below by default
show(NodeContainer) put it on the page

show() adds the menu to the page rather than to whatever is around the owner, and javascript then positions it against the owner and fades it in.

It closes itself

The menu goes away when an item is chosen, and when the mouse is pressed anywhere outside it - and going away means it removes itself from the page. There is nothing to close, nothing to hide and nothing to clean up.

So a PopupMenu2 is built in the click handler that opens it, every time, and is never kept in a field:

//-- Right: a new menu each time, thrown away when it closes
button.setClicked(() -> {
    PopupMenu2 pm = new PopupMenu2(a);
    ...
    pm.show(a);
});

The shorter way to the same menu

Where the entries are actions - which already know their name, their icon and the reason they cannot be used - an ActionButton builds this menu for you:

ActionButton b = new ActionButton(album, play);
b.addAction(album, order);
b.addAction(album, delete);

The chevron on the button opens a PopupMenu2 filled from those actions. Build the menu by hand when there are no actions to reuse, or when the entries are not operations on one record.

The menu is written under .ui-pome2, one .ui-pome2-r per row.

Last modified: 2026/09/06