Class SJPopupMenu

java.lang.Object
com.vaadin.flow.component.Component
com.vaadin.flow.component.contextmenu.ContextMenuBase<com.vaadin.flow.component.contextmenu.ContextMenu, com.vaadin.flow.component.contextmenu.MenuItem, com.vaadin.flow.component.contextmenu.SubMenu>
com.vaadin.flow.component.contextmenu.ContextMenu
com.vaadin.swingbridge.surrogates.SJPopupMenu
All Implemented Interfaces:
com.vaadin.flow.component.AttachNotifier, com.vaadin.flow.component.contextmenu.HasMenuItems, com.vaadin.flow.component.DetachNotifier, com.vaadin.flow.component.HasElement, com.vaadin.flow.component.HasEnabled, com.vaadin.flow.component.HasSize, com.vaadin.flow.component.HasStyle, ComponentMixin, ContainerMixin, JComponentMixin, Serializable

public class SJPopupMenu extends com.vaadin.flow.component.contextmenu.ContextMenu implements JComponentMixin
Surrogate for JPopupMenu (SD_sjpopupmenu). Extends Vaadin ContextMenu directly and reproduces the Swing popup-menu surface via the same tree-rebuild engine SJMenuBar uses — MenuBar, ContextMenu, and SubMenu all implement Vaadin's HasMenuItems, so the MenuTreeBuilder walk is shared above the peer type.

Asymmetric split (same as SD_sjmenubar)

The menu-item family (JMenuItem / JMenu / JCheckBoxMenuItem / JRadioButtonMenuItem / JSeparator) stays emulator-only — no per-item surrogate classes — for the identical R_vaadin_first reason SD_sjmenubar declined them: Vaadin MenuItem's ctor needs internal collaborators. Pure-surrogate users compose with the inherited ContextMenu.addItem(String, com.vaadin.flow.component.ComponentEventListener) directly; the emulator-side :emulators.swing.JPopupMenu pushes a MenuNode snapshot via rebuildFromTree(List).

Attaching to a component

On the surrogate layer, attach via the inherited ContextMenuBase.setTarget(com.vaadin.flow.component.Component) — that's what the Swing-flavoured JComponentMixin.setComponentPopupMenu(SJPopupMenu) helper (SD_sjpopupmenu) calls underneath. ContextMenu's default open trigger is right-click / long-press, which matches Swing's right-click context menu.

Top-level separators render

Unlike SJMenuBar (whose MenuBar peer has no top-level addSeparator), ContextMenu supports separators at the root, so the shared builder's top-level separator callback maps straight to ContextMenuBase.addSeparator().

Accelerators

Per-item KeyStroke accelerators install as UI-scoped shortcuts via MenuTreeBuilder.installAccelerators(UI, Component, Map, Map), torn down on every rebuild — same machinery as SJMenuBar.
See Also:
  • Constructor Details

    • SJPopupMenu

      public SJPopupMenu()
  • Method Details

    • rebuildFromTree

      public void rebuildFromTree(List<MenuNode> tree)
      Push a fresh JDK menu-tree snapshot through to the Vaadin ContextMenu. A snapshot that changes only checked states, handlers or accelerators updates the existing items (MenuTreeBuilder.patchInPlace(List, List, List)); anything else tears the tree down and rebuilds it. Top-level separators render via ContextMenuBase.addSeparator().

      The preventRebuild re-entrancy guard short-circuits recursive calls. null / empty tree fully clears the menu.

    • onAttach

      protected void onAttach(com.vaadin.flow.component.AttachEvent attachEvent)
      Clears the Vaadin MenuItem tree. A ContextMenu root separator is an <hr> that doesn't appear in ContextMenuBase.getItems(), so the recovery walk skips separators without stepping the peer index — the same alignment MenuTreeBuilder.recoverLeafMap(List, List, Map) relies on.
      Overrides:
      onAttach in class com.vaadin.flow.component.Component
    • getCurrentTree

      public List<MenuNode> getCurrentTree()
      Convenience accessor for tests + diagnostics — the most recently pushed MenuNode snapshot (immutable copy).
    • getUIClassID

      public String getUIClassID()
      JDK matches "PopupMenuUI".
      Specified by:
      getUIClassID in interface JComponentMixin