Class SwingBridgeEmulatorsBootstrap

java.lang.Object
vaadinx.swing.app.SwingBridgeEmulatorsBootstrap
All Implemented Interfaces:
com.vaadin.flow.server.VaadinServiceInitListener, Serializable, EventListener

public final class SwingBridgeEmulatorsBootstrap extends Object implements com.vaadin.flow.server.VaadinServiceInitListener
The single init listener a migrated app wires — one line in its own SPI file (or a Spring @Bean: the class is final and library-owned, so it is not the app's to annotate) — priming everything the SB-Emulators runtime needs per session:
// META-INF/services/com.vaadin.flow.server.VaadinServiceInitListener
vaadinx.swing.app.SwingBridgeEmulatorsBootstrap
Five legs:
  • Browser time zone — BrowserTimeZone.fetch() on every UI init, so Date↔LocalDate conversion uses the user's zone (SD_browser_timezone — without it, date-bearing inputs throw). Wired unconditionally, browser or not.
  • Focus tracking — FocusTracker.install() on every UI init, planting the one focusin listener that KeyboardFocusManager.getFocusOwner() and focus traversal read (D_focus_managers). Wired unconditionally: the listener registration is inert under Karibu, which never dispatches DOM events.
  • Emulator theme — context://emul/emulator-theme.css on every UI's page, the default-fill rules D_theme_is_lookandfeel's class mechanism resolves against.
  • Tab-close detection — the vaadin-tab-scope handshake (TabScope.setup + a destroy listener → AppTab.onTabClosed(VaadinSession, TabScope)), so a real app-tab close ends the session (D_shutdown_lifecycle). Wired unconditionally, browser or not: Karibu fakes ExtendedClientDetails, so the handshake completes browserlessly and a tab scope exists under MockService too — which M1D_former_singletons's tab-scoped FormerSingletons holder relies on.
  • "The application has ended" — SystemMessages whose session-expired notice replaces Flow's default reload, which booted a fresh app instance the moment the app ended (D_auto_shutdown). Installed only over Flow's default provider, so an app's own SystemMessagesProvider wins.

It also fails the deployment fast on a JDK older than 24, via assertSupportedRuntime(Runtime.Version) — servlet init is the last legible moment before the first modal dialog deadlocks (R_match_swing_errors case (6)).

The app wires it, never the library (R_no_spi_selfregister): an SPI-registered VaadinServiceInitListener shipped by :emulators would conflict with Spring's bean discovery, so the class ships here and the app registers it (Sampler's SPI file; a Spring app as a @Bean). It is a hard requirement — an app that skips it gets no browser-zone dates (SD_browser_timezone throw), no focus owner, and no tab-close shutdown.

Register this class; do not copy its body into a listener of your own. Legs are added over time — the theme stylesheet arrived after the migration guide's copy was written, which is how that guide came to wire one leg of four — and a copy misses the next one silently. MainWindowRoute throws on attach when this class's UI-init leg never ran (M1D_bootstrap_canonical).

See Also:
  • Constructor Details

    • SwingBridgeEmulatorsBootstrap

      public SwingBridgeEmulatorsBootstrap()
  • Method Details

    • serviceInit

      public void serviceInit(com.vaadin.flow.server.ServiceInitEvent event)
      Specified by:
      serviceInit in interface com.vaadin.flow.server.VaadinServiceInitListener
    • isWired

      public static boolean isWired(com.vaadin.flow.component.UI ui)
      Whether this class's UI-init leg ran for ui — i.e. the app wired it.
      Returns:
      false when the app registered no SwingBridgeEmulatorsBootstrap, or registered it after ui was created