From d9813dc1f68a58414bfebf5acac35dccb9e53545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eftun=20T=C3=BCrkmen?= Date: Fri, 8 May 2026 11:44:51 +0300 Subject: [PATCH 1/5] feat: improve swingbridge taxonomy and improve documentation content --- .../modernization-toolkit/swing-bridge.adoc | 417 ------------------ .../swing-bridge/adding-your-app.adoc | 166 +++++++ .../swing-bridge/authoring-guidelines.adoc | 235 ++++++++++ .../swing-bridge/configuration.adoc | 82 ++++ .../swing-bridge/getting-started.adoc | 74 ++++ .../swing-bridge/index.adoc | 31 ++ .../swing-bridge/installation.adoc | 311 +++++++++++++ .../swing-bridge/reference.adoc | 126 ++++++ .../swing-bridge/running-and-debugging.adoc | 85 ++++ .../swing-bridge/troubleshooting.adoc | 77 ++++ 10 files changed, 1187 insertions(+), 417 deletions(-) delete mode 100644 articles/tools/modernization-toolkit/swing-bridge.adoc create mode 100644 articles/tools/modernization-toolkit/swing-bridge/adding-your-app.adoc create mode 100644 articles/tools/modernization-toolkit/swing-bridge/authoring-guidelines.adoc create mode 100644 articles/tools/modernization-toolkit/swing-bridge/configuration.adoc create mode 100644 articles/tools/modernization-toolkit/swing-bridge/getting-started.adoc create mode 100644 articles/tools/modernization-toolkit/swing-bridge/index.adoc create mode 100644 articles/tools/modernization-toolkit/swing-bridge/installation.adoc create mode 100644 articles/tools/modernization-toolkit/swing-bridge/reference.adoc create mode 100644 articles/tools/modernization-toolkit/swing-bridge/running-and-debugging.adoc create mode 100644 articles/tools/modernization-toolkit/swing-bridge/troubleshooting.adoc diff --git a/articles/tools/modernization-toolkit/swing-bridge.adoc b/articles/tools/modernization-toolkit/swing-bridge.adoc deleted file mode 100644 index 600814222e..0000000000 --- a/articles/tools/modernization-toolkit/swing-bridge.adoc +++ /dev/null @@ -1,417 +0,0 @@ ---- -title: SwingBridge -page-title: How to Use SwingBridge | Vaadin Tools -description: Wrap your Swing application to serve UI over web. -meta-description: Learn how to install and use SwingBridge -order: 140 ---- - -include::{articles}/_vaadin-version.adoc[] - -= [since:com.vaadin:vaadin@V25.1]#SwingBridge# - -pass:[] - -Your existing Swing application runs in a web browser without requiring you to rewrite any of your Swing code. Users interact with it through their browser while the actual Swing application runs on the server. - -The following guide helps you use SwingBridge to integrate your Swing applications into a modern web interface. - -== Prerequisites - -Before getting started, ensure that your application meets the following requirements: - -- **Java 21 or later**: SwingBridge requires Java 21 as the minimum supported version (same as Vaadin). -- **Maven** (optional): Required only if you choose to <>. The <> includes Maven Wrapper scripts, so a separate Maven installation is not needed for that approach. - -== License Installation - -SwingBridge requires a commercial Vaadin subscription or a trial license. You can get one automatically or install it manually. Automatic license installation is the preferred choice. You are asked to either create a new vaadin.com account or login to an existing one in the following process. - -=== Automated Installation - -When you launch your application that uses SwingBridge or any other commercial Vaadin component, you are asked to login to https://vaadin.com/[vaadin.com]. This process downloads the relevant files to the directory shown below and the application proceeds to execute the commercial components automatically. You may proceed with the Project Installation section if you prefer this approach. - -[.example] --- -[source,filesystem] ----- - -%userprofile%\.vaadin\proKey ----- - -[source,filesystem] ----- - -~/.vaadin/proKey ----- --- - -=== Manual Installation - -Create a Vaadin account if you don’t have one by visiting https://vaadin.com/register - -Under the menu:My Account[Licences] section, click Start Trial button to start a trial License if you don’t have an active subscription. - -Follow the instructions on “Licenses” section after logging in to your account to make sure you have a valid license, or at least a trial license (`proKey` and `userKey` files) in the following directory: - - -[.example] --- -[source,filesystem] ----- - -%userprofile%\.vaadin\ ----- - -[source,filesystem] ----- - -~/.vaadin/ ----- --- - -For more information about licensing see <>. - -== Project Setup - -You can set up a SwingBridge project in two ways: <>, which includes sample applications and preconfigured settings, or <>. The skeleton starter is the recommended approach when experiencing SwingBridge for the first time. It includes Maven Wrapper scripts and binaries, so you do not need to install Maven separately. - -[[using-the-skeleton-starter]] -=== Using the Skeleton Starter - -Clone or download the https://github.com/vaadin/skeleton-starter-vaadin-swing-bridge[skeleton starter project] from GitHub: - -[source,terminal] ----- -git clone https://github.com/vaadin/skeleton-starter-vaadin-swing-bridge.git -cd skeleton-starter-vaadin-swing-bridge ----- - -This project comes with sample Swing applications, Maven Wrapper, and all necessary Maven configuration ready to go. Run the project in development mode: - -[.example] --- -[source,terminal] ----- - -./mvnw spring-boot:run ----- - -[source,terminal] ----- - -mvnw.cmd spring-boot:run ----- --- - -Visit `http://localhost:8888` to see the sample applications running inside SwingBridge. - -The project uses an `applibs` directory where Swing application JAR files and their dependencies are placed. All files in this folder are automatically available on the SwingBridge classpath. - -[NOTE] -==== -The `applibs` directory name is case-sensitive. To use a custom directory, pass `-Dapplibs.dir=` on the command line or configure it in the `` section of your `pom.xml`. -==== - -[[setting-up-from-scratch]] -=== Setting Up from Scratch - -Add the following parent section, properties, and dependencies to your `pom.xml`: - -.`pom.xml` -[source,xml,subs="+attributes"] ----- - - 21 - {vaadin-version} - {swing-bridge-version} - ${settings.localRepository}/com/vaadin - - - - org.springframework.boot - spring-boot-starter-parent - {spring-boot-version} - - - - - - - com.vaadin - vaadin-bom - ${vaadin.version} - pom - import - - - - - - - com.vaadin - swing-bridge-patch - ${swing-bridge.version} - - - com.vaadin - swing-bridge-graphics - ${swing-bridge.version} - - - com.vaadin - swing-bridge-flow - ${swing-bridge.version} - - - org.apache.logging.log4j - log4j-slf4j2-impl - - - - - - com.vaadin - vaadin - - - com.vaadin - vaadin-spring-boot-starter - - - com.vaadin - vaadin-dev - true - - ----- - -SwingBridge requires certain JVM flags so that Maven can access internal Java modules during compilation. Create a `.mvn/jvm.config` file in the project root with the following content: - -.`.mvn/jvm.config` -[source] ----- ---add-exports=java.desktop/sun.font=ALL-UNNAMED ---add-exports=java.desktop/sun.awt=ALL-UNNAMED ---add-exports=java.desktop/sun.awt.dnd=ALL-UNNAMED ---add-exports=java.desktop/sun.awt.dnd.peer=ALL-UNNAMED ---add-exports=java.base/sun.nio.cs=ALL-UNNAMED ---add-exports=java.desktop/sun.java2d=ALL-UNNAMED ---add-exports=java.desktop/sun.java2d.pipe=ALL-UNNAMED ---add-exports=java.desktop/sun.awt.datatransfer=ALL-UNNAMED ---add-exports=java.desktop/sun.awt.image=ALL-UNNAMED ---add-exports=java.desktop/java.awt.peer=ALL-UNNAMED ---add-exports=java.desktop/java.awt.dnd=ALL-UNNAMED ---add-exports=java.desktop/java.awt.dnd.peer=ALL-UNNAMED ---add-exports=java.desktop/sun.print=ALL-UNNAMED ---add-exports=java.desktop/sun.swing=ALL-UNNAMED ---add-opens=java.desktop/java.awt.event=ALL-UNNAMED ---add-opens=java.desktop/sun.awt=ALL-UNNAMED ---add-opens=java.desktop/java.awt.dnd=ALL-UNNAMED ---add-reads=java.desktop=ALL-UNNAMED ----- - -These flags are applied to the Maven JVM process itself, allowing the compiler to access the internal `java.desktop` module APIs that SwingBridge depends on. This is separate from the runtime JVM arguments configured in the build plugin below. - -To launch the application through Maven CLI, add the following build plugin to your `pom.xml`: - -.`pom.xml` -[source,xml] ----- - - spring-boot:run - - - com.vaadin - vaadin-maven-plugin - ${vaadin.version} - - - - prepare-frontend - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - --patch-module java.desktop=${swing-bridge.path}/swing-bridge-patch/${swing-bridge.version}/swing-bridge-patch-${swing-bridge.version}.jar - -Xbootclasspath/a:${swing-bridge.path}/swing-bridge-graphics/${swing-bridge.version}/swing-bridge-graphics-${swing-bridge.version}.jar - --add-reads=java.desktop=ALL-UNNAMED - --add-exports=java.desktop/sun.font=ALL-UNNAMED - --add-exports=java.desktop/sun.awt=ALL-UNNAMED - --add-exports=java.desktop/sun.awt.dnd=ALL-UNNAMED - --add-exports=java.desktop/sun.awt.dnd.peer=ALL-UNNAMED - --add-exports=java.base/sun.nio.cs=ALL-UNNAMED - --add-exports=java.desktop/sun.java2d=ALL-UNNAMED - --add-exports=java.desktop/sun.java2d.pipe=ALL-UNNAMED - --add-exports=java.desktop/sun.awt.datatransfer=ALL-UNNAMED - --add-exports=java.desktop/sun.awt.image=ALL-UNNAMED - --add-exports=java.desktop/java.awt.peer=ALL-UNNAMED - --add-exports=java.desktop/java.awt.dnd=ALL-UNNAMED - --add-exports=java.desktop/java.awt.dnd.peer=ALL-UNNAMED - --add-exports=java.desktop/sun.print=ALL-UNNAMED - --add-exports=java.desktop/sun.swing=ALL-UNNAMED - --add-opens=java.desktop/java.awt.event=ALL-UNNAMED - --add-opens=java.desktop/sun.awt=ALL-UNNAMED - --add-opens=java.desktop/java.awt.dnd=ALL-UNNAMED - -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 - - - - - false - - - - - - ----- - -== Add Your Swing Application - -The following applies to both cases above: either you cloned from GitHub or created from scratch. - -Copy your Swing application’s main jar binary and all its dependencies into the `applibs` folder in the project you created in the first section. The sample Swing application’s jar file is included if you cloned the skeleton project directly from GitHub. All files placed in this folder are visible on the SwingBridge classpath. - -== Create a Vaadin View for Your Swing Application - -Refer to the class that contains the main() method of your Swing application inside a Vaadin View. - -[source,java] ----- -@Route("myapp") -public class MyAppView extends VerticalLayout { - public MyAppView() { - add(new SwingBridge("com.mycompany.swingapp.MySwingAppMain")); - setSizeFull(); - } -} - ----- - -Start the server: - -[source,terminal] ----- -mvn spring-boot:run ----- - -Navigate to `http://localhost:8888` to see the application. If you configured a custom port in your project (the Spring Boot default is `8080`), navigate to that port instead. - -== Running and Debugging - -=== Running from the Command Line - -SwingBridge requires special JVM flags to access internal Java modules. Because of this, running the application by clicking the green play button in IntelliJ IDEA or the equivalent in VS Code is not supported at this time. - -To run the application, use Maven from the command line as described in the <> or <> sections. - -[NOTE] -==== -Hotswap Agent and Spring Boot DevTools automatic restart are not fully supported with SwingBridge yet. If you detect unexpected behavior, try running the application without them. -==== - -=== Remote Debugging - -After starting the application through Maven, you can debug it using remote debugging. The skeleton starter project already includes the necessary JVM argument for this. If you set up from scratch, add the following to the `` section in your `spring-boot-maven-plugin` configuration: - -[source] ----- --agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 ----- - -For IDE-specific setup instructions, see <> and <>. - -== What Happens Under the Hood - -Once you've set up your SwingBridge subclass, the framework handles: - -- Launching your Swing application in the background when the component attaches -- Capturing the UI as images and streaming them to the browser -- Handling user interactions like clicks, keyboard input, and window resizing -- Managing dialogs and popups that your Swing application creates -- Updating the display continuously so users see a live view of your application - -[.collapsible-list] -== Frequently Asked Questions - -.What is SwingBridge? -[%collapsible] -==== -SwingBridge is a Vaadin component that allows you to run existing Swing applications in a web browser without rewriting them. It captures the Swing UI as images and streams them to the browser while handling user interactions. -==== - -.Does the existing Swing code need modification? -[%collapsible] -==== -Swing applications originally are designed and built with single tenancy in mind. Local resource usages like filesystem access, serial devices etc. should be refactored to achieve full multi-tenancy. Vaadin has relevant tooling to automate code refactoring. -==== - -.What Swing components are supported? -[%collapsible] -==== -All standard Swing components are supported, as well as your customized Swing components. -- `JFrame`, `JDialog`, `JWindow` -- JPopupMenu and combo box popups -- JFileChooser (with special upload handling) -- Tooltips -- All standard Swing widgets (buttons, text fields, tables, etc.) -==== - -.How does SwingBridge work? -[%collapsible] -==== -SwingBridge runs your Swing application on the server and continuously inspects the Swing UI for changes. As soon as a change is detected, dirty regions are streamed to the browser to keep the updates as lightweight as possible. User interactions (clicks, keyboard input) are sent back to the server and replayed on the actual Swing components. -==== - -[.collapsible-list] -== IDE Remote Debug Configuration - -[[remote-debug-intellij]] -.IntelliJ IDEA -[%collapsible] -==== -To set up remote debugging in IntelliJ IDEA: - -. Open menu:Run[Edit Configurations...]. -. Click the btn:[+] button and select *Remote JVM Debug*. -. Set the *Name* to something descriptive, such as `SwingBridge Remote Debug`. -. Ensure *Debugger mode* is set to *Attach to remote JVM*. -. Set *Host* to `localhost` and *Port* to `5005`. -. Click btn:[OK] to save the configuration. - -Start the application through Maven first, then launch this debug configuration. The debugger attaches to the running application, and you can set breakpoints and step through code as usual. -==== - -[[remote-debug-vscode]] -.VS Code -[%collapsible] -==== -To set up remote debugging in VS Code: - -. Open or create the `.vscode/launch.json` file in your project. -. Add the following configuration: -+ -[source,json] ----- -{ - "type": "java", - "name": "SwingBridge Remote Debug", - "request": "attach", - "hostName": "localhost", - "port": 5005 -} ----- - -. Start the application through Maven first. -. Open the *Run and Debug* view and select *SwingBridge Remote Debug*. -. Click the green play button to attach the debugger. - -You can now set breakpoints and debug the running application. -==== diff --git a/articles/tools/modernization-toolkit/swing-bridge/adding-your-app.adoc b/articles/tools/modernization-toolkit/swing-bridge/adding-your-app.adoc new file mode 100644 index 0000000000..96a4eec9b3 --- /dev/null +++ b/articles/tools/modernization-toolkit/swing-bridge/adding-your-app.adoc @@ -0,0 +1,166 @@ +--- +title: Adding Your Swing Application +page-title: Add a Swing App to SwingBridge | Vaadin Tools +description: Wire your Swing application's JARs into SwingBridge and create a Vaadin view that hosts it. +meta-description: Bring your Swing JAR into a SwingBridge project, choose a JAR-loading strategy, and wrap the application in a Vaadin Flow view. +order: 3 +--- + +include::{articles}/_vaadin-version.adoc[] + +[[swing-bridge.adding-your-app]] += Adding Your Swing Application + +This page covers two things: + +. *Make your Swing JAR (and its dependencies) visible to SwingBridge* using one of two loading strategies — the `applibs` directory or a `swing-app-jar-list.conf` file. +. *Create a Vaadin Flow view* that wraps the Swing application's `main` class. + +The instructions apply equally whether you started from the skeleton starter (<>) or set up the project from scratch (<>). + + +[[swing-bridge.adding-your-app.jar-loading]] +== JAR Loading Strategies + +SwingBridge needs to load your Swing application from a separate classloader so that each user session gets an isolated `AppContext`. There are two ways to provide it the JARs. + +[cols="1,3,3", options="header"] +|=== +| | `applibs` directory | `swing-app-jar-list.conf` + +| When to use +| Default. You drop JARs into a directory and SwingBridge picks them all up. +| You want explicit control over the order and identity of each JAR (useful for hand-curated classpath ordering, or for loading from a non-standard location). + +| Format +| Any number of `.jar` files in the directory. +| One JAR path per line. Lines starting with `#` are comments; blank lines are ignored. + +| Default location +| `applibs/` next to the running application JAR or, in dev, next to the project root. +| `swing-app-jar-list.conf` at the classpath root (in a Spring Boot project, that is `src/main/resources/`). + +| Override +| `-Dapplibs.dir=` +| Paths inside the file resolve against `-Dswingbridge.jarlist.baseDir=` (defaults to the working directory). +|=== + +[NOTE] +==== +The `applibs` directory name is case-sensitive. The `swing-app-jar-list.conf` filename is also fixed. +==== + + +[[swing-bridge.adding-your-app.jar-loading.applibs]] +=== Using the `applibs` Directory + +Copy your Swing application's main JAR and all its dependency JARs into `applibs`. All `.jar` files in the directory become part of the SwingBridge classpath at runtime. + +[source,filesystem] +---- +my-swingbridge-project/ +├── pom.xml +├── applibs/ +│ ├── my-swing-app.jar +│ ├── dependency-a.jar +│ └── dependency-b.jar +└── src/... +---- + +To use a custom directory, pass `-Dapplibs.dir=` on the command line or configure it under `` in your `pom.xml` (see <>). + + +[[swing-bridge.adding-your-app.jar-loading.jar-list]] +=== Using `swing-app-jar-list.conf` + +Place a file named `swing-app-jar-list.conf` at the classpath root (`src/main/resources/swing-app-jar-list.conf` in a Spring Boot project) listing one JAR path per line: + +[source] +---- +# My Swing application's classpath (order matters) +${maven.multiModuleProjectDirectory}/my-app/target/my-app.jar +${maven.multiModuleProjectDirectory}/libs/legacy-utils.jar +/opt/shared-libs/customer-shared.jar +---- + +Path resolution rules: + +- Lines beginning with `#` and blank lines are skipped. +- The placeholder `${maven.multiModuleProjectDirectory}` expands to the system property of the same name (set automatically by Maven for multi‑module builds). +- Absolute paths are kept as‑is. +- Relative paths resolve against `-Dswingbridge.jarlist.baseDir=` if set, otherwise against `user.dir` (the JVM's working directory). +- Order is preserved on the classloader, so place override JARs ahead of the JARs they shadow. + + +[[swing-bridge.adding-your-app.view]] +== Create a Vaadin View + +Wrap the Swing application's `main` class in a Vaadin view by passing its fully qualified name to `[classname]`SwingBridge``: + +[source,java] +---- +@Route("myapp") +public class MyAppView extends VerticalLayout { + public MyAppView() { + add(new SwingBridge("com.mycompany.swingapp.MySwingAppMain")); + setSizeFull(); + } +} +---- + +Start the server: + +[source,terminal] +---- +mvn spring-boot:run +---- + +Navigate to `http://localhost:8888/myapp` to see the application. If you configured a custom port (the Spring Boot default is `8080`), navigate to that port instead. + + +[[swing-bridge.adding-your-app.constructors]] +== Constructor Variants + +`[classname]`SwingBridge`` provides three constructors for the common cases: + +[source,java] +---- +// 1. Main-class FQN, default classloader (uses the applibs directory) +new SwingBridge("com.mycompany.swingapp.MySwingAppMain"); + +// 2. Main-class FQN with command-line arguments forwarded to main() +new SwingBridge("com.mycompany.swingapp.MySwingAppMain", + new String[] { "--config", "production" }); + +// 3. Main-class FQN with a custom classloader supplier +new SwingBridge("com.mycompany.swingapp.MySwingAppMain", + () -> SwingBridgeRunner.createClassLoader( + SwingBridgeRunner.loadSwingAppJarList(), + getClass().getClassLoader())); +---- + +The third form is the most explicit — it pairs the Swing app with a JAR list (or a directory load) of your choice. For example, to use the `swing-app-jar-list.conf` file described above, subclass `[classname]`SwingBridge`` and override the supplier: + +[source,java] +---- +public class MyApp extends SwingBridge { + public MyApp() { + super("com.mycompany.swingapp.MySwingAppMain"); + } + + @Override + protected Supplier createClassLoaderSupplier() { + return () -> SwingBridgeRunner.createClassLoader( + SwingBridgeRunner.loadSwingAppJarList(), + getClass().getClassLoader()); + } +} +---- + + +[[swing-bridge.adding-your-app.next-steps]] +== Next Steps + +- Tune behaviour with system properties (frame rate, error reporting): <>. +- Public API surface and lifecycle hooks (`beforeInit`, `afterInit`): <>. +- Run and debug from your IDE: <>. diff --git a/articles/tools/modernization-toolkit/swing-bridge/authoring-guidelines.adoc b/articles/tools/modernization-toolkit/swing-bridge/authoring-guidelines.adoc new file mode 100644 index 0000000000..15ba46a094 --- /dev/null +++ b/articles/tools/modernization-toolkit/swing-bridge/authoring-guidelines.adoc @@ -0,0 +1,235 @@ +--- +title: Authoring Guidelines (internal) +page-title: SwingBridge Docs Authoring Guidelines +description: Conventions for writing pages under tools/modernization-toolkit/swing-bridge. +meta-description: Internal authoring guidelines for SwingBridge documentation contributors. +order: 99 +section-nav: hidden +--- + +[[swing-bridge.authoring-guidelines]] += Authoring Guidelines (Internal) + +This page is for contributors adding or editing pages under +`articles/tools/modernization-toolkit/swing-bridge/`. It is hidden from +the customer-facing sidebar. + +For broader Vaadin docs conventions, see the upstream +<<../../../../contributing/docs/styleguide#, Style Guide>> and +<<../../../../contributing/docs/types#, Documentation Types>>; this +page only adds the SwingBridge-specific decisions. + + +[[swing-bridge.authoring-guidelines.front-matter]] +== Front Matter + +Every page starts with YAML front matter. Required keys: + +[source,yaml] +---- +--- +title: Page Title +order: +--- +---- + +Recommended keys: + +[cols="1,4", options="header"] +|=== +|Key |Notes + +|`page-title` +|Browser tab and search-result title. Aim for 50–60 characters; include "Vaadin" and the tool name (for example `Run and Debug SwingBridge \| Vaadin Tools`). + +|`description` +|One‑line subtitle for site listings. + +|`meta-description` +|SEO snippet rendered into the page's ``. Aim for 150–160 characters. + +|`section-nav` +|`hidden` keeps the page out of the sidebar (for contributor-only pages like this one). `commercial` adds the commercial badge. Omit for ordinary pages. +|=== + + +[[swing-bridge.authoring-guidelines.file-naming]] +== File Naming and Subdirectories + +- *kebab-case* `.adoc` files (`adding-your-app.adoc`, not `AddingYourApp.adoc` or `adding_your_app.adoc`). +- `index.adoc` is the section landing page. Renaming a single file to a directory of the same name and dropping `index.adoc` inside preserves the URL. +- Files starting with `_` are includes only (partials) and never appear in nav. + + +[[swing-bridge.authoring-guidelines.headings]] +== Headings and Anchors + +- Exactly one `=` (H1) per page, immediately after front matter. +- Anchors use a dot-separated, lowercase path that mirrors the page hierarchy: ++ +[source,asciidoc] +---- +[[swing-bridge.installation.jvm-flags]] +== JVM Flags Reference +---- ++ +Anchors are link contracts; do not rename them once published. + +- Section headings use *Title Case* ("Running and Debugging", not "Running And Debugging" and not "Running and debugging"). + + +[[swing-bridge.authoring-guidelines.cross-refs]] +== Cross-References + +Within the SwingBridge subdirectory: + +[source,asciidoc] +---- +<> +---- + +To other Vaadin docs sections: + +[source,asciidoc] +---- +<> +---- + +Prefer `<<…>>` to `xref:` to match the surrounding tools/modernization-toolkit pages. + + +[[swing-bridge.authoring-guidelines.code-blocks]] +== Code Blocks + +Use the language-specific block style: + +[source,asciidoc] +---- +[source,java] +---- +new SwingBridge("com.mycompany.swingapp.MainClass"); +---- +---- + +For OS-tabbed snippets: + +[source,asciidoc] +---- +[.example] +-- +[source,terminal] +---- + +./mvnw spring-boot:run +---- + +[source,terminal] +---- + +mvnw.cmd spring-boot:run +---- +-- +---- + +For XML and properties that need attribute substitution (Vaadin version, etc.) include `_vaadin-version.adoc` and add `subs="+attributes"` on the source block: + +[source,asciidoc] +---- +include::{articles}/_vaadin-version.adoc[] + +[source,xml,subs="+attributes"] +---- +{vaadin-version} +---- +---- + +When the same code lives in the skeleton starter or playground, prefer including it from there with `tags=…` so the snippet stays in sync with the source rather than copy-pasting. + + +[[swing-bridge.authoring-guidelines.admonitions]] +== Admonitions + +Use sparingly. The catalog: + +[source,asciidoc] +---- +[NOTE] +==== +Soft hint a reader may otherwise miss in flowing prose. +==== + +[IMPORTANT] +==== +Load-bearing fact (the `java.awt.headless=false` style of thing). +==== + +[WARNING] +==== +Doing X breaks Y in a way that is not obvious from the code. +==== + +[TIP] +==== +Optional optimisation or alternative. +==== +---- + +For FAQs and other Q&A content, use the collapsible block pattern: + +[source,asciidoc] +---- +[.collapsible-list] +== Frequently Asked Questions + +.Question heading +[%collapsible] +==== +Answer body. +==== +---- + + +[[swing-bridge.authoring-guidelines.style]] +== Style + +- Present tense, active voice, professional tone. +- American English (`color`, `behavior`, `customize`). +- Title Case for headings. +- No `!` or `?` in body text. Question marks are allowed only in FAQ titles. +- Use the Oxford comma in lists. +- Spell out "for example" rather than `e.g.` in body text. +- For new APIs and features, mark them with the version badge: ++ +[source,asciidoc] +---- += [since:com.vaadin:vaadin@V25.1]#SwingBridge# +---- + + +[[swing-bridge.authoring-guidelines.what-not-to-publish]] +== What Not To Publish + +The following are *internal* and must not appear on customer pages under +`articles/tools/modernization-toolkit/swing-bridge/`: + +- Internal hostnames and staging URLs (`mtk-*`, `localdev.*`, `*.stg.vaadin.com`). +- Internal repositories not on github.com/vaadin (any `j-lawyer-*`, customer reference apps, partner-only forks). +- Customer email addresses or seat IDs from the licensing system. +- Slack channels, JIRA tickets, internal wiki links. + +The repo's project README and `CLAUDE.md` may legitimately contain +local-development URLs (for example a self-signed `localdev.vaadin.com` +certificate trick). Those stay in the project repository and do *not* +get copied into public docs. + + +[[swing-bridge.authoring-guidelines.discussion-id]] +== Discussion IDs + +Roughly a third of Vaadin docs pages end with a unique +`[discussion-id]\`UUID\`` line that wires the page into the public +comments system. It is optional. For SwingBridge pages we currently +*do not* use it, matching the parent +`tools/modernization-toolkit/index.adoc`. If you decide to enable +comments on a page, generate a fresh UUID with `uuidgen` and add it as +the last line. diff --git a/articles/tools/modernization-toolkit/swing-bridge/configuration.adoc b/articles/tools/modernization-toolkit/swing-bridge/configuration.adoc new file mode 100644 index 0000000000..60b9f62a7a --- /dev/null +++ b/articles/tools/modernization-toolkit/swing-bridge/configuration.adoc @@ -0,0 +1,82 @@ +--- +title: Configuration +page-title: Configure SwingBridge | Vaadin Tools +description: System properties and runtime knobs for tuning SwingBridge. +meta-description: Reference for the system properties that control SwingBridge frame rate, JAR loading, and the launch-failure error view. +order: 4 +--- + +include::{articles}/_vaadin-version.adoc[] + +[[swing-bridge.configuration]] += Configuration + +This page lists the runtime knobs SwingBridge reads from JVM system properties, plus the in‑page error view that activates when the embedded Swing application fails to launch. + + +[[swing-bridge.configuration.system-properties]] +== System Properties Reference + +[cols="3,1,5", options="header"] +|=== +|Property |Default |Description + +|`java.awt.headless` +|— +|*Required.* Must be set to `false`. SwingBridge needs a real (non-headless) AWT toolkit to render Swing components into images on the server. + +|`applibs.dir` +|`applibs/` next to the application JAR (or the project root in dev) +|Override the directory SwingBridge scans for application JARs. See <>. + +|`swingbridge.jarlist.baseDir` +|JVM working directory (`user.dir`) +|Base directory used to resolve *relative* paths in `swing-app-jar-list.conf`. See <>. + +|`swingbridge.frameUpdateInterval` +|`100` (milliseconds, minimum `71`) +|How often SwingBridge polls each Swing window for changes and pushes the dirty regions to the browser. Lower values feel more responsive at the cost of CPU; higher values save CPU at the cost of perceived latency. + +|`swingbridge.errorReporting.enabled` +|`true` +|When set to `false`, the launch-failure error view shows only the failure header — the exception type, message, and stack trace are suppressed and the report-submission form is hidden. See <<#swing-bridge.configuration.error-reporting, Launch Failure Error View>> below. +|=== + +For Spring Boot, set system properties through `` on the `spring-boot-maven-plugin` (see <>) or pass `-D` flags on the command line. For a packaged JAR, pass them with `-D` on the command line: + +[source,terminal] +---- +java -Dswingbridge.errorReporting.enabled=false -jar my-app.jar +---- + + +[[swing-bridge.configuration.error-reporting]] +== Launch Failure Error View + +When a Swing application embedded via `[classname]`SwingBridge`` fails to start — for example because the configured main class cannot be loaded, the AWT toolkit cannot initialize, or no `JFrame` becomes visible within the launch timeout — the canvas area is replaced with an in-page error view that shows: + +- A failure title and a short explainer. +- The error type and message. +- The full stack trace, including any `Caused by` chain (collapsible). +- An optional email field and a *Submit report* button that posts a report to Vaadin so the cause can be investigated. +- A *Preview report content* button that opens a draggable, resizable dialog showing the exact JSON that would be submitted (with the stack trace rendered as plain text in a separate section). +- A link to the link:https://vaadin.com/privacy-policy[Vaadin Privacy Policy] explaining how reports are processed. + +The intent is that a developer integrating SwingBridge sees a meaningful error in the browser instead of a blank canvas. + +[[swing-bridge.configuration.error-reporting.disable]] +=== Disabling for Production + +Set `swingbridge.errorReporting.enabled=false` to suppress all exception details in the error view. Only the *Failed to launch the Swing application* header is shown; the message, stack trace, email field, and submit button are all hidden so that no diagnostic information leaks into the page or onto a report endpoint. Diagnose the cause from server-side logs instead. + +For a Spring Boot run, add the flag to the `` in `spring-boot-maven-plugin`. For a packaged JAR: + +[source,terminal] +---- +java -Dswingbridge.errorReporting.enabled=false -jar my-app.jar +---- + +[IMPORTANT] +==== +Stack traces can contain customer data (file paths, hostnames, query parameters). Disable error reporting in any deployment where this information must not reach end-users or third parties. +==== diff --git a/articles/tools/modernization-toolkit/swing-bridge/getting-started.adoc b/articles/tools/modernization-toolkit/swing-bridge/getting-started.adoc new file mode 100644 index 0000000000..710bfbd083 --- /dev/null +++ b/articles/tools/modernization-toolkit/swing-bridge/getting-started.adoc @@ -0,0 +1,74 @@ +--- +title: Getting Started +page-title: Get Started with SwingBridge | Vaadin Tools +description: Run a Swing application in the browser in five minutes with the SwingBridge skeleton starter. +meta-description: Clone the SwingBridge skeleton starter, drop your Swing JAR into applibs, and run it in the browser. Five-minute happy path. +order: 1 +--- + +include::{articles}/_vaadin-version.adoc[] + +[[swing-bridge.getting-started]] += Getting Started + +This page walks through the fastest path to a running SwingBridge application. The goal is to get the bundled sample Swing app rendering in your browser, so you can see what SwingBridge does end‑to‑end before adapting it to your own code. + +For a from‑scratch Maven project (no skeleton), see <>. To replace the sample app with your own JAR, see <>. + + +[[swing-bridge.getting-started.prerequisites]] +== Before You Start + +You need: + +- *Java 21 or later*. SwingBridge requires the same minimum JDK as Vaadin. +- *A Vaadin commercial subscription or trial license* installed in your home directory (`~/.vaadin/proKey` on macOS or Linux, `%userprofile%\.vaadin\proKey` on Windows). The first commercial Vaadin run prompts you to log in and downloads the license automatically; for the manual route see <>. + +Maven is *not* required separately — the skeleton starter ships with Maven Wrapper. + + +[[swing-bridge.getting-started.clone]] +== Clone the Skeleton Starter + +[source,terminal] +---- +git clone https://github.com/vaadin/skeleton-starter-vaadin-swing-bridge.git +cd skeleton-starter-vaadin-swing-bridge +---- + +The starter ships with a sample Swing application in the `applibs` directory, a Vaadin view that wraps it, and the Maven configuration with the JVM flags SwingBridge needs. + + +[[swing-bridge.getting-started.run]] +== Run the Application + +[.example] +-- +[source,terminal] +---- + +./mvnw spring-boot:run +---- + +[source,terminal] +---- + +mvnw.cmd spring-boot:run +---- +-- + +Open `http://localhost:8888` in your browser. The sample Swing application renders inside a Vaadin view; mouse, keyboard, dialogs, and popups all work as they would on the desktop. + +[NOTE] +==== +SwingBridge needs special JVM flags to access internal Java modules, so the IDE green play button does not work. Always launch through Maven from the terminal — see <> for details and remote‑debug setup. +==== + + +[[swing-bridge.getting-started.next-steps]] +== Next Steps + +- Replace the sample with your own application: <>. +- Tune system properties (frame rate, JAR locations, error reporting): <>. +- Set up remote debugging from your IDE: <>. +- If something goes wrong: <>. diff --git a/articles/tools/modernization-toolkit/swing-bridge/index.adoc b/articles/tools/modernization-toolkit/swing-bridge/index.adoc new file mode 100644 index 0000000000..b1764a5a33 --- /dev/null +++ b/articles/tools/modernization-toolkit/swing-bridge/index.adoc @@ -0,0 +1,31 @@ +--- +title: SwingBridge +page-title: How to Use SwingBridge | Vaadin Tools +description: Wrap your Swing application to serve UI over web. +meta-description: Run an existing Swing application in a web browser by wrapping it with Vaadin SwingBridge. +order: 140 +--- + +include::{articles}/_vaadin-version.adoc[] + += [since:com.vaadin:vaadin@V25.1]#SwingBridge# + +pass:[] + +Your existing Swing application runs in a web browser without requiring you to rewrite any of your Swing code. Users interact with it through their browser while the actual Swing application runs on the server. + + +== When to Use SwingBridge + +SwingBridge fits when: + +- The Swing application is feature-complete and tested, and a full rewrite is not justified. +- Users need access through a browser instead of installing a desktop client. +- A staged modernization is preferred over a one-shot port to a web stack. + +For deeper refactoring of the Swing source itself, see the sister tools listed under <<../index#, Modernization Toolkit>>. + + +== Topics + +section_outline::[] diff --git a/articles/tools/modernization-toolkit/swing-bridge/installation.adoc b/articles/tools/modernization-toolkit/swing-bridge/installation.adoc new file mode 100644 index 0000000000..2e52dd9d94 --- /dev/null +++ b/articles/tools/modernization-toolkit/swing-bridge/installation.adoc @@ -0,0 +1,311 @@ +--- +title: Installation +page-title: Install and Configure SwingBridge | Vaadin Tools +description: Install the SwingBridge license and set up a Maven project from scratch. +meta-description: Step-by-step license installation and from-scratch Maven configuration for Vaadin SwingBridge, including the full JVM flag reference. +order: 2 +--- + +include::{articles}/_vaadin-version.adoc[] + +[[swing-bridge.installation]] += Installation + +This page covers the installation steps for a SwingBridge project that is not based on the skeleton starter: + +. Install the Vaadin commercial license. +. Configure a Maven project from scratch. +. Apply the JVM flags SwingBridge needs at compile time and at runtime. + +If you only want a quick try-out, the <> page uses the skeleton starter and skips most of the manual configuration below. + + +[[swing-bridge.installation.license]] +== License Installation + +SwingBridge requires a commercial Vaadin subscription or a trial license. You can get one automatically or install it manually. Automatic license installation is the preferred choice. You are asked to either create a new vaadin.com account or login to an existing one in the following process. + + +[[swing-bridge.installation.license.automated]] +=== Automated License Installation + +When you launch your application that uses SwingBridge or any other commercial Vaadin component, you are asked to login to https://vaadin.com/[vaadin.com]. This process downloads the relevant files to the directory shown below and the application proceeds to execute the commercial components automatically. You may proceed with the project setup if you prefer this approach. + +[.example] +-- +[source,filesystem] +---- + +%userprofile%\.vaadin\proKey +---- + +[source,filesystem] +---- + +~/.vaadin/proKey +---- +-- + + +[[swing-bridge.installation.license.manual]] +=== Manual License Installation + +Create a Vaadin account if you don't have one by visiting https://vaadin.com/register + +Under menu:My Account[Licences], click *Start Trial* to start a trial license if you don't have an active subscription. + +Follow the instructions in the *Licenses* section after logging in to your account to make sure you have a valid license, or at least a trial license (`proKey` and `userKey` files) in the following directory: + +[.example] +-- +[source,filesystem] +---- + +%userprofile%\.vaadin\ +---- + +[source,filesystem] +---- + +~/.vaadin/ +---- +-- + +For more information about licensing see <>. + + +[[swing-bridge.installation.project-setup]] +== Project Setup + +Add the following parent section, properties, and dependencies to your `pom.xml`: + +.`pom.xml` +[source,xml,subs="+attributes"] +---- + + 21 + {vaadin-version} + {swing-bridge-version} + ${settings.localRepository}/com/vaadin + + + + org.springframework.boot + spring-boot-starter-parent + {spring-boot-version} + + + + + + + com.vaadin + vaadin-bom + ${vaadin.version} + pom + import + + + + + + + com.vaadin + swing-bridge-patch + ${swing-bridge.version} + + + com.vaadin + swing-bridge-graphics + ${swing-bridge.version} + + + com.vaadin + swing-bridge-flow + ${swing-bridge.version} + + + org.apache.logging.log4j + log4j-slf4j2-impl + + + + + + com.vaadin + vaadin + + + com.vaadin + vaadin-spring-boot-starter + + + com.vaadin + vaadin-dev + true + + +---- + +SwingBridge requires certain JVM flags so that Maven can access internal Java modules during compilation. Create a `.mvn/jvm.config` file in the project root with the following content: + +.`.mvn/jvm.config` +[source] +---- +--add-exports=java.desktop/sun.font=ALL-UNNAMED +--add-exports=java.desktop/sun.awt=ALL-UNNAMED +--add-exports=java.desktop/sun.awt.dnd=ALL-UNNAMED +--add-exports=java.desktop/sun.awt.dnd.peer=ALL-UNNAMED +--add-exports=java.base/sun.nio.cs=ALL-UNNAMED +--add-exports=java.desktop/sun.java2d=ALL-UNNAMED +--add-exports=java.desktop/sun.java2d.pipe=ALL-UNNAMED +--add-exports=java.desktop/sun.awt.datatransfer=ALL-UNNAMED +--add-exports=java.desktop/sun.awt.image=ALL-UNNAMED +--add-exports=java.desktop/java.awt.peer=ALL-UNNAMED +--add-exports=java.desktop/java.awt.dnd=ALL-UNNAMED +--add-exports=java.desktop/java.awt.dnd.peer=ALL-UNNAMED +--add-exports=java.desktop/sun.print=ALL-UNNAMED +--add-exports=java.desktop/sun.swing=ALL-UNNAMED +--add-opens=java.desktop/java.awt.event=ALL-UNNAMED +--add-opens=java.desktop/sun.awt=ALL-UNNAMED +--add-opens=java.desktop/java.awt.dnd=ALL-UNNAMED +--add-reads=java.desktop=ALL-UNNAMED +---- + +These flags are applied to the Maven JVM process itself, allowing the compiler to access the internal `java.desktop` module APIs that SwingBridge depends on. This is separate from the runtime JVM arguments configured in the build plugin below. + +To launch the application through Maven CLI, add the following build plugin to your `pom.xml`: + +.`pom.xml` +[source,xml] +---- + + spring-boot:run + + + com.vaadin + vaadin-maven-plugin + ${vaadin.version} + + + + prepare-frontend + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + --patch-module java.desktop=${swing-bridge.path}/swing-bridge-patch/${swing-bridge.version}/swing-bridge-patch-${swing-bridge.version}.jar + -Xbootclasspath/a:${swing-bridge.path}/swing-bridge-graphics/${swing-bridge.version}/swing-bridge-graphics-${swing-bridge.version}.jar + --add-reads=java.desktop=ALL-UNNAMED + --add-exports=java.desktop/sun.font=ALL-UNNAMED + --add-exports=java.desktop/sun.awt=ALL-UNNAMED + --add-exports=java.desktop/sun.awt.dnd=ALL-UNNAMED + --add-exports=java.desktop/sun.awt.dnd.peer=ALL-UNNAMED + --add-exports=java.base/sun.nio.cs=ALL-UNNAMED + --add-exports=java.desktop/sun.java2d=ALL-UNNAMED + --add-exports=java.desktop/sun.java2d.pipe=ALL-UNNAMED + --add-exports=java.desktop/sun.awt.datatransfer=ALL-UNNAMED + --add-exports=java.desktop/sun.awt.image=ALL-UNNAMED + --add-exports=java.desktop/java.awt.peer=ALL-UNNAMED + --add-exports=java.desktop/java.awt.dnd=ALL-UNNAMED + --add-exports=java.desktop/java.awt.dnd.peer=ALL-UNNAMED + --add-exports=java.desktop/sun.print=ALL-UNNAMED + --add-exports=java.desktop/sun.swing=ALL-UNNAMED + --add-opens=java.desktop/java.awt.event=ALL-UNNAMED + --add-opens=java.desktop/sun.awt=ALL-UNNAMED + --add-opens=java.desktop/java.awt.dnd=ALL-UNNAMED + -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 + + + + + false + + + + + + +---- + +The trailing `-agentlib:jdwp=…` flag enables remote debugging on port 5005. Remove it (or change `suspend=n` to `suspend=y`) to suit your needs — see <>. + +[IMPORTANT] +==== +The `java.awt.headless=false` system property is mandatory. SwingBridge needs a real (non‑headless) AWT toolkit to render Swing components into images on the server. Without it, the application throws `HeadlessException` on startup. +==== + + +[[swing-bridge.installation.jvm-flags]] +== JVM Flags Reference + +The runtime `` block above bundles three categories of flags. The table below lists each one with its purpose, so you can tell which lines are load-bearing versus which only widen access for specific Swing APIs. + +[cols="3,5", options="header"] +|=== +|Flag |Purpose + +|`--patch-module java.desktop=…/swing-bridge-patch-.jar` +|Replaces internal `java.desktop` classes with SwingBridge's patched versions. Required. + +|`-Xbootclasspath/a:…/swing-bridge-graphics-.jar` +|Prepends SwingBridge's graphics interception JAR to the bootstrap classpath so it is available before `Toolkit.getDefaultToolkit()` runs. Required. + +|`--add-reads=java.desktop=ALL-UNNAMED` +|Allows the patched `java.desktop` to read classes loaded from the unnamed module (the application's own JARs). + +|`--add-exports=java.desktop/sun.font=ALL-UNNAMED` +|Exposes the internal font manager to SwingBridge's font handling. + +|`--add-exports=java.desktop/sun.awt=ALL-UNNAMED` +|Exposes core internal AWT classes (`AppContext`, `SunToolkit`, …) used by SwingBridge's per‑session isolation. + +|`--add-exports=java.desktop/sun.awt.dnd=ALL-UNNAMED` + +`--add-exports=java.desktop/sun.awt.dnd.peer=ALL-UNNAMED` + +`--add-exports=java.desktop/java.awt.dnd=ALL-UNNAMED` + +`--add-exports=java.desktop/java.awt.dnd.peer=ALL-UNNAMED` +|Drag-and-drop internals. Needed because SwingBridge replaces the default `DragSource` to keep one user's drag from blocking another. + +|`--add-exports=java.base/sun.nio.cs=ALL-UNNAMED` +|Charset internals used during text rendering. + +|`--add-exports=java.desktop/sun.java2d=ALL-UNNAMED` + +`--add-exports=java.desktop/sun.java2d.pipe=ALL-UNNAMED` +|Java 2D internals — `SurfaceManager`, `SurfaceData`, `Region` — needed for the off‑screen image SwingBridge draws into. + +|`--add-exports=java.desktop/sun.awt.datatransfer=ALL-UNNAMED` +|Clipboard internals used by SwingBridge's per‑session clipboard. + +|`--add-exports=java.desktop/sun.awt.image=ALL-UNNAMED` +|Image-pipeline internals used by the synthetic image peers. + +|`--add-exports=java.desktop/java.awt.peer=ALL-UNNAMED` +|AWT peer interfaces required to install SwingBridge's custom peers. + +|`--add-exports=java.desktop/sun.print=ALL-UNNAMED` +|Printing internals (used opportunistically by some Swing apps). + +|`--add-exports=java.desktop/sun.swing=ALL-UNNAMED` +|Swing internals — `SwingUtilities` helpers and the repaint manager hook. + +|`--add-opens=java.desktop/java.awt.event=ALL-UNNAMED` + +`--add-opens=java.desktop/sun.awt=ALL-UNNAMED` + +`--add-opens=java.desktop/java.awt.dnd=ALL-UNNAMED` +|Reflective access. SwingBridge reads/writes a small number of private fields (focus state, drag flag, event queue) to plumb its multi-tenant model. +|=== + +The dev-time list in `.mvn/jvm.config` is the same minus `--patch-module` and `-Xbootclasspath/a` — those only apply at runtime. + + +[[swing-bridge.installation.next-steps]] +== Next Steps + +- Bring in your own Swing JAR: <>. +- Tune frame rate, JAR-loading paths, and error reporting: <>. +- Run, debug, and attach an IDE: <>. diff --git a/articles/tools/modernization-toolkit/swing-bridge/reference.adoc b/articles/tools/modernization-toolkit/swing-bridge/reference.adoc new file mode 100644 index 0000000000..8dc91b477c --- /dev/null +++ b/articles/tools/modernization-toolkit/swing-bridge/reference.adoc @@ -0,0 +1,126 @@ +--- +title: Reference +page-title: SwingBridge Reference | Vaadin Tools +description: Public API summary, lifecycle hooks, and bundled sample applications. +meta-description: Reference for the SwingBridge public Java API, lifecycle hooks, and the sample Swing applications shipped with the skeleton starter. +order: 7 +--- + +include::{articles}/_vaadin-version.adoc[] + +[[swing-bridge.reference]] += Reference + +This page summarizes the public Java API surface of SwingBridge and lists the sample applications that ship with the skeleton starter. + + +[[swing-bridge.reference.under-the-hood]] +== What Happens Under the Hood + +Once you've set up your `[classname]`SwingBridge`` subclass (or instance), the framework handles: + +- Launching your Swing application in the background when the component attaches. +- Capturing the UI as images and streaming the changed regions to the browser. +- Routing user interactions — clicks, keyboard input, window resizing — back into the AWT event queue. +- Managing dialogs, popups, and tooltips that your Swing application creates. +- Updating the display continuously so users see a live view of your application. + +Every browser session runs the Swing application inside its own isolated `[classname]`AppContext``, so two users do not share static state, focus, clipboard, or drag-and-drop status. + + +[[swing-bridge.reference.swingbridge]] +== `SwingBridge` Component + +The `[classname]`SwingBridge`` class is the entry point. It is a Vaadin Flow `[classname]`Div`` that, on attach, launches the Swing application and renders it into the page. + +[[swing-bridge.reference.swingbridge.constructors]] +=== Constructors + +[source,java] +---- +new SwingBridge(String mainClassFQN); +new SwingBridge(String mainClassFQN, String[] args); +new SwingBridge(String mainClassFQN, Supplier classLoaderSupplier); +---- + +The first form uses the default classloader supplier (loads JARs from the `applibs/` directory). The second forwards the given arguments to the Swing application's `main` method. The third hands full control of classloader construction to the caller — pair it with `[classname]`SwingBridgeRunner``'s helpers to load JARs from a `swing-app-jar-list.conf` file or a custom location. + +[[swing-bridge.reference.swingbridge.hooks]] +=== Lifecycle Hooks + +`[classname]`SwingBridge`` exposes two protected hooks. Override them in a subclass to run custom code before or after the Swing application is wired into the view. + +[cols="2,5", options="header"] +|=== +|Hook |When it runs + +|`[methodname]`beforeInit(Component component)`` +|After the Swing application has launched and produced a visible `[classname]`JFrame``, but before SwingBridge wires that frame into its canvas. Useful for last-minute configuration of the Swing component itself (sizing, native look-and-feel tweaks). + +|`[methodname]`afterInit(Component component)`` +|After SwingBridge has wired the frame into its canvas and frame updates are ready to flow. Useful for hooking up listeners on the Swing component or signalling readiness to the rest of the Vaadin view. +|=== + +A custom classloader supplier is contributed via `[methodname]`createClassLoaderSupplier()``, which subclasses also override (see <>). + + +[[swing-bridge.reference.swingbridge-runner]] +== `SwingBridgeRunner` Helpers + +`[classname]`SwingBridgeRunner`` is a static utility used by the component itself, but several of its methods are public and useful when you build a custom classloader supplier. + +[cols="3,4", options="header"] +|=== +|Method |Use + +|`[methodname]`createSession(String mainClassFQN)`` +|Create a `[classname]`SwingBridgeSession`` that ties the Vaadin session to a specific main class. Pass it to `[methodname]`runSwingApp(...)``. + +|`[methodname]`runSwingApp(SwingBridgeSession, …)`` +|Launch the Swing application in an isolated `[classname]`AppContext``. Returns a `[classname]`CompletableFuture`` that resolves when the first window appears (or completes exceptionally on launch failure). + +|`[methodname]`loadSwingAppJarList()`` +|Read a `swing-app-jar-list.conf` from the classpath root and return the JAR paths it lists. Combine with `[methodname]`createClassLoader(...)``. + +|`[methodname]`loadJarsFromDirectory()`` +|Read every `.jar` in the configured `applibs` directory. + +|`[methodname]`createClassLoader(List jars, ClassLoader parent)`` +|Build a `[classname]`URLClassLoader`` from the supplied JAR paths. +|=== + + +[[swing-bridge.reference.samples]] +== Sample Applications + +The link:https://github.com/vaadin/skeleton-starter-vaadin-swing-bridge[skeleton starter] bundles a number of small Swing applications that demonstrate different features. They live under `simple-swing-apps/` in the source tree and are loaded into the playground via `swing-app-jar-list.conf`. + +[cols="3,4", options="header"] +|=== +|Main class |What it shows + +|`com.mycompany.swingapp.SimpleSwingApp2` +|Minimal Swing form (`JFrame` + `JTextField` + `JButton`). The smoke-test app. + +|`com.mycompany.swingapp.warehouse.WarehouseInventoryApp1` +|Larger UI with a `JSplitPane`, tree, and tables. Demonstrates resize handling and grid rendering. + +|`com.mycompany.swingapp.swingx.JXDatePickerApp` +|SwingX `JXDatePicker` to confirm popup support for non-standard Swing libraries. + +|`com.mycompany.swingapp.dnd.DndTestApp` +|Drag-and-drop within a single Swing window. + +|`com.jinternalframe.JInternalFrameTilingDemo` +|`JInternalFrame` tiling inside a `JDesktopPane`. +|=== + +Each sample is a starting point you can adapt to your own application — copy the view class from the playground, change the main-class FQN, and adjust the `applibs/` contents. + + +[[swing-bridge.reference.next-steps]] +== Next Steps + +- Bring in your own Swing JAR and wire up a Vaadin view: <>. +- Tune runtime behaviour: <>. +- Diagnose launch failures: <>. diff --git a/articles/tools/modernization-toolkit/swing-bridge/running-and-debugging.adoc b/articles/tools/modernization-toolkit/swing-bridge/running-and-debugging.adoc new file mode 100644 index 0000000000..1dc973efdb --- /dev/null +++ b/articles/tools/modernization-toolkit/swing-bridge/running-and-debugging.adoc @@ -0,0 +1,85 @@ +--- +title: Running and Debugging +page-title: Run and Debug SwingBridge | Vaadin Tools +description: Run SwingBridge applications from Maven and attach a remote debugger from IntelliJ IDEA or VS Code. +meta-description: How to run a SwingBridge application from the command line and attach a remote Java debugger from IntelliJ IDEA or VS Code. +order: 5 +--- + +include::{articles}/_vaadin-version.adoc[] + +[[swing-bridge.running-and-debugging]] += Running and Debugging + + +[[swing-bridge.running-and-debugging.cli]] +== Running from the Command Line + +SwingBridge requires special JVM flags to access internal Java modules. Because of this, running the application by clicking the green play button in IntelliJ IDEA or the equivalent in VS Code is not supported at this time. + +To run the application, use Maven from the command line as described in <> (skeleton starter) or <> (from-scratch project). + +[NOTE] +==== +Hotswap Agent and Spring Boot DevTools automatic restart are not fully supported with SwingBridge yet. If you detect unexpected behavior, try running the application without them. +==== + + +[[swing-bridge.running-and-debugging.remote-debug]] +== Remote Debugging + +After starting the application through Maven, you can debug it using remote debugging. The skeleton starter project already includes the necessary JVM argument for this. If you set up from scratch, add the following to the `` section in your `spring-boot-maven-plugin` configuration: + +[source] +---- +-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 +---- + +For IDE-specific setup instructions, see <<#swing-bridge.running-and-debugging.intellij, IntelliJ IDEA>> and <<#swing-bridge.running-and-debugging.vscode, VS Code>> below. + + +[.collapsible-list] +== IDE Remote Debug Configuration + +[[swing-bridge.running-and-debugging.intellij]] +.IntelliJ IDEA +[%collapsible] +==== +To set up remote debugging in IntelliJ IDEA: + +. Open menu:Run[Edit Configurations...]. +. Click the btn:[+] button and select *Remote JVM Debug*. +. Set the *Name* to something descriptive, such as `SwingBridge Remote Debug`. +. Ensure *Debugger mode* is set to *Attach to remote JVM*. +. Set *Host* to `localhost` and *Port* to `5005`. +. Click btn:[OK] to save the configuration. + +Start the application through Maven first, then launch this debug configuration. The debugger attaches to the running application, and you can set breakpoints and step through code as usual. +==== + +[[swing-bridge.running-and-debugging.vscode]] +.VS Code +[%collapsible] +==== +To set up remote debugging in VS Code: + +. Open or create the `.vscode/launch.json` file in your project. +. Add the following configuration: ++ +[source,json] +---- +{ + "type": "java", + "name": "SwingBridge Remote Debug", + "request": "attach", + "hostName": "localhost", + "port": 5005 +} +---- + +. Start the application through Maven first. +. Open the *Run and Debug* view and select *SwingBridge Remote Debug*. +. Click the green play button to attach the debugger. + +You can now set breakpoints and debug the running application. +==== diff --git a/articles/tools/modernization-toolkit/swing-bridge/troubleshooting.adoc b/articles/tools/modernization-toolkit/swing-bridge/troubleshooting.adoc new file mode 100644 index 0000000000..28f4b82cad --- /dev/null +++ b/articles/tools/modernization-toolkit/swing-bridge/troubleshooting.adoc @@ -0,0 +1,77 @@ +--- +title: Troubleshooting +page-title: Troubleshoot SwingBridge | Vaadin Tools +description: Common SwingBridge launch failures and how to fix them. +meta-description: Diagnose and resolve common SwingBridge launch failures, including missing JVM flags, missing main class, and headless toolkit errors. +order: 6 +--- + +include::{articles}/_vaadin-version.adoc[] + +[[swing-bridge.troubleshooting]] += Troubleshooting + +When SwingBridge cannot start the embedded Swing application, the canvas is replaced with an in-page error view that shows the underlying cause (see <>). Use the table below to map the error you see in that view (or in the server log) to the most likely fix. + + +[[swing-bridge.troubleshooting.failure-modes]] +== Common Failure Modes + +[cols="3,4", options="header"] +|=== +|Symptom |Likely cause and fix + +|`AWTError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.` (Linux) +or +`UnsatisfiedLinkError` loading `libawt_xawt.so` / `awt.dll` early in startup. +|The runtime JVM flags are missing — specifically `--patch-module java.desktop=…` and `-Xbootclasspath/a:…`. Without them the JDK falls back to the native AWT toolkit and tries to open a real display. Apply the full flag set from <>. + +|`HeadlessException` on startup, or "no graphics environment" errors. +|`java.awt.headless` is `true` (or unset and defaulting to `true` in your environment). Set `-Djava.awt.headless=false` (or add it under `` in `spring-boot-maven-plugin`). + +|Stack trace contains `java.lang.ClassNotFoundException: `. +|The Swing application's main class is not on the SwingBridge classpath. Confirm the JAR is in `applibs/` (or named in `swing-app-jar-list.conf`) and that the fully qualified main-class name passed to `[classname]`SwingBridge`` matches a class that JAR contains. See <>. + +|Error view says "Swing application did not display any window within the launch timeout." +|The Swing application is loading but never makes a `JFrame` visible — the most common causes are a `main` method that returns immediately without scheduling work on the EDT, a long-running blocking operation in `main`, or an unhandled exception in `main` that gets swallowed before a window is shown. Run the application locally (outside SwingBridge) to confirm it actually opens a window, then check server-side logs for an exception. + +|Missing or boxed glyphs on Linux ("tofu", squares, replacement characters). +|System fonts that the patched font path does not include, or no fonts installed at all. Install the standard fonts your Swing application expects (typically Liberation, DejaVu, or Microsoft Core Fonts on Linux) into one of the standard system font directories (`/usr/share/fonts/...`). + +|`License is invalid` or trial key prompt on startup. +|No valid Vaadin commercial license in `~/.vaadin/` (or `%userprofile%\.vaadin\`). See <>. +|=== + + +[.collapsible-list] +== Frequently Asked Questions + +.What is SwingBridge? +[%collapsible] +==== +SwingBridge is a Vaadin component that allows you to run existing Swing applications in a web browser without rewriting them. It captures the Swing UI as images and streams them to the browser while handling user interactions. +==== + +.Does the existing Swing code need modification? +[%collapsible] +==== +Swing applications originally are designed and built with single tenancy in mind. Local resource usages like filesystem access, serial devices etc. should be refactored to achieve full multi-tenancy. Vaadin has relevant tooling to automate code refactoring. +==== + +.What Swing components are supported? +[%collapsible] +==== +All standard Swing components are supported, as well as your customized Swing components. + +- `JFrame`, `JDialog`, `JWindow` +- JPopupMenu and combo box popups +- JFileChooser (with special upload handling) +- Tooltips +- All standard Swing widgets (buttons, text fields, tables, etc.) +==== + +.How does SwingBridge work? +[%collapsible] +==== +SwingBridge runs your Swing application on the server and continuously inspects the Swing UI for changes. As soon as a change is detected, dirty regions are streamed to the browser to keep the updates as lightweight as possible. User interactions (clicks, keyboard input) are sent back to the server and replayed on the actual Swing components. +==== From 889dd43e26a4726936f252d68363e5a653782ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eftun=20T=C3=BCrkmen?= Date: Fri, 8 May 2026 12:00:10 +0300 Subject: [PATCH 2/5] fix: improve wording and remove authoring-guidelines --- .../swing-bridge/authoring-guidelines.adoc | 235 ------------------ .../swing-bridge/reference.adoc | 34 +-- 2 files changed, 6 insertions(+), 263 deletions(-) delete mode 100644 articles/tools/modernization-toolkit/swing-bridge/authoring-guidelines.adoc diff --git a/articles/tools/modernization-toolkit/swing-bridge/authoring-guidelines.adoc b/articles/tools/modernization-toolkit/swing-bridge/authoring-guidelines.adoc deleted file mode 100644 index 15ba46a094..0000000000 --- a/articles/tools/modernization-toolkit/swing-bridge/authoring-guidelines.adoc +++ /dev/null @@ -1,235 +0,0 @@ ---- -title: Authoring Guidelines (internal) -page-title: SwingBridge Docs Authoring Guidelines -description: Conventions for writing pages under tools/modernization-toolkit/swing-bridge. -meta-description: Internal authoring guidelines for SwingBridge documentation contributors. -order: 99 -section-nav: hidden ---- - -[[swing-bridge.authoring-guidelines]] -= Authoring Guidelines (Internal) - -This page is for contributors adding or editing pages under -`articles/tools/modernization-toolkit/swing-bridge/`. It is hidden from -the customer-facing sidebar. - -For broader Vaadin docs conventions, see the upstream -<<../../../../contributing/docs/styleguide#, Style Guide>> and -<<../../../../contributing/docs/types#, Documentation Types>>; this -page only adds the SwingBridge-specific decisions. - - -[[swing-bridge.authoring-guidelines.front-matter]] -== Front Matter - -Every page starts with YAML front matter. Required keys: - -[source,yaml] ----- ---- -title: Page Title -order: ---- ----- - -Recommended keys: - -[cols="1,4", options="header"] -|=== -|Key |Notes - -|`page-title` -|Browser tab and search-result title. Aim for 50–60 characters; include "Vaadin" and the tool name (for example `Run and Debug SwingBridge \| Vaadin Tools`). - -|`description` -|One‑line subtitle for site listings. - -|`meta-description` -|SEO snippet rendered into the page's ``. Aim for 150–160 characters. - -|`section-nav` -|`hidden` keeps the page out of the sidebar (for contributor-only pages like this one). `commercial` adds the commercial badge. Omit for ordinary pages. -|=== - - -[[swing-bridge.authoring-guidelines.file-naming]] -== File Naming and Subdirectories - -- *kebab-case* `.adoc` files (`adding-your-app.adoc`, not `AddingYourApp.adoc` or `adding_your_app.adoc`). -- `index.adoc` is the section landing page. Renaming a single file to a directory of the same name and dropping `index.adoc` inside preserves the URL. -- Files starting with `_` are includes only (partials) and never appear in nav. - - -[[swing-bridge.authoring-guidelines.headings]] -== Headings and Anchors - -- Exactly one `=` (H1) per page, immediately after front matter. -- Anchors use a dot-separated, lowercase path that mirrors the page hierarchy: -+ -[source,asciidoc] ----- -[[swing-bridge.installation.jvm-flags]] -== JVM Flags Reference ----- -+ -Anchors are link contracts; do not rename them once published. - -- Section headings use *Title Case* ("Running and Debugging", not "Running And Debugging" and not "Running and debugging"). - - -[[swing-bridge.authoring-guidelines.cross-refs]] -== Cross-References - -Within the SwingBridge subdirectory: - -[source,asciidoc] ----- -<> ----- - -To other Vaadin docs sections: - -[source,asciidoc] ----- -<> ----- - -Prefer `<<…>>` to `xref:` to match the surrounding tools/modernization-toolkit pages. - - -[[swing-bridge.authoring-guidelines.code-blocks]] -== Code Blocks - -Use the language-specific block style: - -[source,asciidoc] ----- -[source,java] ----- -new SwingBridge("com.mycompany.swingapp.MainClass"); ----- ----- - -For OS-tabbed snippets: - -[source,asciidoc] ----- -[.example] --- -[source,terminal] ----- - -./mvnw spring-boot:run ----- - -[source,terminal] ----- - -mvnw.cmd spring-boot:run ----- --- ----- - -For XML and properties that need attribute substitution (Vaadin version, etc.) include `_vaadin-version.adoc` and add `subs="+attributes"` on the source block: - -[source,asciidoc] ----- -include::{articles}/_vaadin-version.adoc[] - -[source,xml,subs="+attributes"] ----- -{vaadin-version} ----- ----- - -When the same code lives in the skeleton starter or playground, prefer including it from there with `tags=…` so the snippet stays in sync with the source rather than copy-pasting. - - -[[swing-bridge.authoring-guidelines.admonitions]] -== Admonitions - -Use sparingly. The catalog: - -[source,asciidoc] ----- -[NOTE] -==== -Soft hint a reader may otherwise miss in flowing prose. -==== - -[IMPORTANT] -==== -Load-bearing fact (the `java.awt.headless=false` style of thing). -==== - -[WARNING] -==== -Doing X breaks Y in a way that is not obvious from the code. -==== - -[TIP] -==== -Optional optimisation or alternative. -==== ----- - -For FAQs and other Q&A content, use the collapsible block pattern: - -[source,asciidoc] ----- -[.collapsible-list] -== Frequently Asked Questions - -.Question heading -[%collapsible] -==== -Answer body. -==== ----- - - -[[swing-bridge.authoring-guidelines.style]] -== Style - -- Present tense, active voice, professional tone. -- American English (`color`, `behavior`, `customize`). -- Title Case for headings. -- No `!` or `?` in body text. Question marks are allowed only in FAQ titles. -- Use the Oxford comma in lists. -- Spell out "for example" rather than `e.g.` in body text. -- For new APIs and features, mark them with the version badge: -+ -[source,asciidoc] ----- -= [since:com.vaadin:vaadin@V25.1]#SwingBridge# ----- - - -[[swing-bridge.authoring-guidelines.what-not-to-publish]] -== What Not To Publish - -The following are *internal* and must not appear on customer pages under -`articles/tools/modernization-toolkit/swing-bridge/`: - -- Internal hostnames and staging URLs (`mtk-*`, `localdev.*`, `*.stg.vaadin.com`). -- Internal repositories not on github.com/vaadin (any `j-lawyer-*`, customer reference apps, partner-only forks). -- Customer email addresses or seat IDs from the licensing system. -- Slack channels, JIRA tickets, internal wiki links. - -The repo's project README and `CLAUDE.md` may legitimately contain -local-development URLs (for example a self-signed `localdev.vaadin.com` -certificate trick). Those stay in the project repository and do *not* -get copied into public docs. - - -[[swing-bridge.authoring-guidelines.discussion-id]] -== Discussion IDs - -Roughly a third of Vaadin docs pages end with a unique -`[discussion-id]\`UUID\`` line that wires the page into the public -comments system. It is optional. For SwingBridge pages we currently -*do not* use it, matching the parent -`tools/modernization-toolkit/index.adoc`. If you decide to enable -comments on a page, generate a fresh UUID with `uuidgen` and add it as -the last line. diff --git a/articles/tools/modernization-toolkit/swing-bridge/reference.adoc b/articles/tools/modernization-toolkit/swing-bridge/reference.adoc index 8dc91b477c..a8ac2a4f5d 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/reference.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/reference.adoc @@ -1,8 +1,8 @@ --- title: Reference page-title: SwingBridge Reference | Vaadin Tools -description: Public API summary, lifecycle hooks, and bundled sample applications. -meta-description: Reference for the SwingBridge public Java API, lifecycle hooks, and the sample Swing applications shipped with the skeleton starter. +description: Public API summary, lifecycle hooks, and the recommended sample project. +meta-description: Reference for the SwingBridge public Java API and lifecycle hooks, with a pointer to the SwingBridge skeleton starter project. order: 7 --- @@ -11,7 +11,7 @@ include::{articles}/_vaadin-version.adoc[] [[swing-bridge.reference]] = Reference -This page summarizes the public Java API surface of SwingBridge and lists the sample applications that ship with the skeleton starter. +This page summarizes the public Java API surface of SwingBridge and points at the skeleton starter project. [[swing-bridge.reference.under-the-hood]] @@ -90,32 +90,10 @@ A custom classloader supplier is contributed via `[methodname]`createClassLoader |=== -[[swing-bridge.reference.samples]] -== Sample Applications +[[swing-bridge.reference.sample-project]] +== Sample Project -The link:https://github.com/vaadin/skeleton-starter-vaadin-swing-bridge[skeleton starter] bundles a number of small Swing applications that demonstrate different features. They live under `simple-swing-apps/` in the source tree and are loaded into the playground via `swing-app-jar-list.conf`. - -[cols="3,4", options="header"] -|=== -|Main class |What it shows - -|`com.mycompany.swingapp.SimpleSwingApp2` -|Minimal Swing form (`JFrame` + `JTextField` + `JButton`). The smoke-test app. - -|`com.mycompany.swingapp.warehouse.WarehouseInventoryApp1` -|Larger UI with a `JSplitPane`, tree, and tables. Demonstrates resize handling and grid rendering. - -|`com.mycompany.swingapp.swingx.JXDatePickerApp` -|SwingX `JXDatePicker` to confirm popup support for non-standard Swing libraries. - -|`com.mycompany.swingapp.dnd.DndTestApp` -|Drag-and-drop within a single Swing window. - -|`com.jinternalframe.JInternalFrameTilingDemo` -|`JInternalFrame` tiling inside a `JDesktopPane`. -|=== - -Each sample is a starting point you can adapt to your own application — copy the view class from the playground, change the main-class FQN, and adjust the `applibs/` contents. +The link:https://github.com/vaadin/skeleton-starter-vaadin-swing-bridge[skeleton starter] is the recommended starting point. It is a working SwingBridge project — Maven configuration, JVM flags, and a Vaadin view wired up — that you can clone and adapt to your own Swing application by replacing the JARs in `applibs/`. See <> for the walkthrough. [[swing-bridge.reference.next-steps]] From 28ceee58d1f9cd10c660c29269c2f2de230d2cd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eftun=20T=C3=BCrkmen?= Date: Fri, 15 May 2026 15:29:46 +0300 Subject: [PATCH 3/5] chore: fix wording and polish formatting --- .../swing-bridge/adding-your-app.adoc | 8 +-- .../swing-bridge/configuration.adoc | 6 +-- .../swing-bridge/faq.adoc | 40 +++++++++++++++ .../swing-bridge/getting-started.adoc | 8 +-- .../swing-bridge/index.adoc | 2 +- .../swing-bridge/installation.adoc | 2 +- .../swing-bridge/reference.adoc | 49 +++++++------------ .../swing-bridge/running-and-debugging.adoc | 2 +- .../swing-bridge/troubleshooting.adoc | 33 ------------- 9 files changed, 72 insertions(+), 78 deletions(-) create mode 100644 articles/tools/modernization-toolkit/swing-bridge/faq.adoc diff --git a/articles/tools/modernization-toolkit/swing-bridge/adding-your-app.adoc b/articles/tools/modernization-toolkit/swing-bridge/adding-your-app.adoc index 96a4eec9b3..8da4cacf2f 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/adding-your-app.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/adding-your-app.adoc @@ -95,7 +95,7 @@ Path resolution rules: [[swing-bridge.adding-your-app.view]] == Create a Vaadin View -Wrap the Swing application's `main` class in a Vaadin view by passing its fully qualified name to `[classname]`SwingBridge``: +Wrap the Swing application's `main` class in a Vaadin view by passing its fully qualified name to `SwingBridge`: [source,java] ---- @@ -121,7 +121,7 @@ Navigate to `http://localhost:8888/myapp` to see the application. If you configu [[swing-bridge.adding-your-app.constructors]] == Constructor Variants -`[classname]`SwingBridge`` provides three constructors for the common cases: +`SwingBridge` provides three constructors for the common cases: [source,java] ---- @@ -139,7 +139,7 @@ new SwingBridge("com.mycompany.swingapp.MySwingAppMain", getClass().getClassLoader())); ---- -The third form is the most explicit — it pairs the Swing app with a JAR list (or a directory load) of your choice. For example, to use the `swing-app-jar-list.conf` file described above, subclass `[classname]`SwingBridge`` and override the supplier: +The third form is the most explicit — it pairs the Swing app with a JAR list (or a directory load) of your choice. For example, to use the `swing-app-jar-list.conf` file described above, subclass `SwingBridge` and override the supplier: [source,java] ---- @@ -161,6 +161,6 @@ public class MyApp extends SwingBridge { [[swing-bridge.adding-your-app.next-steps]] == Next Steps -- Tune behaviour with system properties (frame rate, error reporting): <>. +- Tune behaviour with system properties: <>. - Public API surface and lifecycle hooks (`beforeInit`, `afterInit`): <>. - Run and debug from your IDE: <>. diff --git a/articles/tools/modernization-toolkit/swing-bridge/configuration.adoc b/articles/tools/modernization-toolkit/swing-bridge/configuration.adoc index 60b9f62a7a..3c09ff6293 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/configuration.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/configuration.adoc @@ -53,7 +53,7 @@ java -Dswingbridge.errorReporting.enabled=false -jar my-app.jar [[swing-bridge.configuration.error-reporting]] == Launch Failure Error View -When a Swing application embedded via `[classname]`SwingBridge`` fails to start — for example because the configured main class cannot be loaded, the AWT toolkit cannot initialize, or no `JFrame` becomes visible within the launch timeout — the canvas area is replaced with an in-page error view that shows: +When a Swing application embedded via `SwingBridge` fails to start — for example because the configured main class cannot be loaded, the AWT toolkit cannot initialize, or no `JFrame` becomes visible within the launch timeout — the canvas area is replaced with an in-page error view that shows: - A failure title and a short explainer. - The error type and message. @@ -62,8 +62,6 @@ When a Swing application embedded via `[classname]`SwingBridge`` fails to start - A *Preview report content* button that opens a draggable, resizable dialog showing the exact JSON that would be submitted (with the stack trace rendered as plain text in a separate section). - A link to the link:https://vaadin.com/privacy-policy[Vaadin Privacy Policy] explaining how reports are processed. -The intent is that a developer integrating SwingBridge sees a meaningful error in the browser instead of a blank canvas. - [[swing-bridge.configuration.error-reporting.disable]] === Disabling for Production @@ -78,5 +76,5 @@ java -Dswingbridge.errorReporting.enabled=false -jar my-app.jar [IMPORTANT] ==== -Stack traces can contain customer data (file paths, hostnames, query parameters). Disable error reporting in any deployment where this information must not reach end-users or third parties. +Stack traces can contain sensitive data (file paths, hostnames, query parameters). Disable error reporting in any deployment where this information must not reach end-users or third parties. ==== diff --git a/articles/tools/modernization-toolkit/swing-bridge/faq.adoc b/articles/tools/modernization-toolkit/swing-bridge/faq.adoc new file mode 100644 index 0000000000..d53b8fd62c --- /dev/null +++ b/articles/tools/modernization-toolkit/swing-bridge/faq.adoc @@ -0,0 +1,40 @@ +--- +title: Frequently Asked Questions +page-title: Frequently Asked Questions for SwingBridge | Vaadin Tools +description: Frequently Asked Questions for SwingBridge +meta-description: Frequently Asked Questions for SwingBridge and their answers in a non technical way +order: 7 +--- + +[.collapsible-list] +== Frequently Asked Questions + +.What is SwingBridge? +[%collapsible] +==== +SwingBridge is a Vaadin component that allows you to run existing Swing applications in a web browser without rewriting them. It captures the Swing UI as images and streams them to the browser while handling user interactions. +==== + +.Does the existing Swing code need modification? +[%collapsible] +==== +Swing applications originally are designed and built with single tenancy in mind. Local resource usages like filesystem access, serial devices etc. should be refactored to achieve full multi-tenancy. Vaadin has relevant tooling to automate code refactoring. +==== + +.What Swing components are supported? +[%collapsible] +==== +All standard Swing components are supported, as well as your customized Swing components. + +- `JFrame`, `JDialog`, `JWindow` +- JPopupMenu and combo box popups +- JFileChooser (with special upload handling) +- Tooltips +- All standard Swing widgets (buttons, text fields, tables, etc.) +==== + +.How does SwingBridge work? +[%collapsible] +==== +SwingBridge runs your Swing application on the server and continuously inspects the Swing UI for changes. As soon as a change is detected, dirty regions are streamed to the browser to keep the updates as lightweight as possible. User interactions (clicks, keyboard input) are sent back to the server and replayed on the actual Swing components. +==== \ No newline at end of file diff --git a/articles/tools/modernization-toolkit/swing-bridge/getting-started.adoc b/articles/tools/modernization-toolkit/swing-bridge/getting-started.adoc index 710bfbd083..3a241c4975 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/getting-started.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/getting-started.adoc @@ -1,7 +1,7 @@ --- title: Getting Started page-title: Get Started with SwingBridge | Vaadin Tools -description: Run a Swing application in the browser in five minutes with the SwingBridge skeleton starter. +description: Run a Swing application in the browser in minutes with the SwingBridge skeleton starter. meta-description: Clone the SwingBridge skeleton starter, drop your Swing JAR into applibs, and run it in the browser. Five-minute happy path. order: 1 --- @@ -22,7 +22,7 @@ For a from‑scratch Maven project (no skeleton), see <>. +- *A Vaadin commercial subscription or trial license* installed in your home directory (`~/.vaadin/proKey` on macOS or Linux, `%userprofile%\.vaadin\proKey` on Windows). The first execution prompts you to log in and downloads the license automatically; for the manual route see <>. Maven is *not* required separately — the skeleton starter ships with Maven Wrapper. @@ -61,7 +61,7 @@ Open `http://localhost:8888` in your browser. The sample Swing application rende [NOTE] ==== -SwingBridge needs special JVM flags to access internal Java modules, so the IDE green play button does not work. Always launch through Maven from the terminal — see <> for details and remote‑debug setup. +SwingBridge needs special JVM flags to access internal Java modules, so the IDE's default launch configurations needs extra configuration. Always launch through Maven from the terminal — see <> for details and remote‑debug setup. ==== @@ -69,6 +69,6 @@ SwingBridge needs special JVM flags to access internal Java modules, so the IDE == Next Steps - Replace the sample with your own application: <>. -- Tune system properties (frame rate, JAR locations, error reporting): <>. +- Tune system properties (JAR locations, error reporting): <>. - Set up remote debugging from your IDE: <>. - If something goes wrong: <>. diff --git a/articles/tools/modernization-toolkit/swing-bridge/index.adoc b/articles/tools/modernization-toolkit/swing-bridge/index.adoc index b1764a5a33..57191a7161 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/index.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/index.adoc @@ -23,7 +23,7 @@ SwingBridge fits when: - Users need access through a browser instead of installing a desktop client. - A staged modernization is preferred over a one-shot port to a web stack. -For deeper refactoring of the Swing source itself, see the sister tools listed under <<../index#, Modernization Toolkit>>. +For deeper refactoring of the Swing source itself, see the tools listed under <<../index#, Modernization Toolkit>>. == Topics diff --git a/articles/tools/modernization-toolkit/swing-bridge/installation.adoc b/articles/tools/modernization-toolkit/swing-bridge/installation.adoc index 2e52dd9d94..c5365fa1a8 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/installation.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/installation.adoc @@ -307,5 +307,5 @@ The dev-time list in `.mvn/jvm.config` is the same minus `--patch-module` and `- == Next Steps - Bring in your own Swing JAR: <>. -- Tune frame rate, JAR-loading paths, and error reporting: <>. +- Tune JAR-loading paths, and error reporting: <>. - Run, debug, and attach an IDE: <>. diff --git a/articles/tools/modernization-toolkit/swing-bridge/reference.adoc b/articles/tools/modernization-toolkit/swing-bridge/reference.adoc index a8ac2a4f5d..4ad1b0f322 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/reference.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/reference.adoc @@ -17,7 +17,7 @@ This page summarizes the public Java API surface of SwingBridge and points at th [[swing-bridge.reference.under-the-hood]] == What Happens Under the Hood -Once you've set up your `[classname]`SwingBridge`` subclass (or instance), the framework handles: +Once you've set up your `SwingBridge` subclass (or instance), the framework handles: - Launching your Swing application in the background when the component attaches. - Capturing the UI as images and streaming the changed regions to the browser. @@ -25,13 +25,13 @@ Once you've set up your `[classname]`SwingBridge`` subclass (or instance), the f - Managing dialogs, popups, and tooltips that your Swing application creates. - Updating the display continuously so users see a live view of your application. -Every browser session runs the Swing application inside its own isolated `[classname]`AppContext``, so two users do not share static state, focus, clipboard, or drag-and-drop status. +Every browser session runs the Swing application inside its own isolated `AppContext`, so two users do not share static state, focus, clipboard, or drag-and-drop status. [[swing-bridge.reference.swingbridge]] == `SwingBridge` Component -The `[classname]`SwingBridge`` class is the entry point. It is a Vaadin Flow `[classname]`Div`` that, on attach, launches the Swing application and renders it into the page. +The `SwingBridge` class is the entry point. It is a Vaadin Flow `Div` that, on attach, launches the Swing application and renders it into the page. [[swing-bridge.reference.swingbridge.constructors]] === Constructors @@ -43,62 +43,51 @@ new SwingBridge(String mainClassFQN, String[] args); new SwingBridge(String mainClassFQN, Supplier classLoaderSupplier); ---- -The first form uses the default classloader supplier (loads JARs from the `applibs/` directory). The second forwards the given arguments to the Swing application's `main` method. The third hands full control of classloader construction to the caller — pair it with `[classname]`SwingBridgeRunner``'s helpers to load JARs from a `swing-app-jar-list.conf` file or a custom location. +The first form uses the default classloader supplier (loads JARs from the `applibs/` directory). The second forwards the given arguments to the Swing application's `main` method. The third hands full control of classloader construction to the caller — pair it with `SwingBridgeRunner`'s helpers to load JARs from a `swing-app-jar-list.conf` file or a custom location. [[swing-bridge.reference.swingbridge.hooks]] === Lifecycle Hooks -`[classname]`SwingBridge`` exposes two protected hooks. Override them in a subclass to run custom code before or after the Swing application is wired into the view. +`SwingBridge` exposes two protected hooks. Override them in a subclass to run custom code before or after the Swing application is wired into the view. [cols="2,5", options="header"] |=== |Hook |When it runs -|`[methodname]`beforeInit(Component component)`` -|After the Swing application has launched and produced a visible `[classname]`JFrame``, but before SwingBridge wires that frame into its canvas. Useful for last-minute configuration of the Swing component itself (sizing, native look-and-feel tweaks). +|`beforeInit(Component component)` +|After the Swing application has launched and produced a visible `JFrame`, but before SwingBridge wires that frame into its canvas. Useful for last-minute configuration of the Swing component itself (sizing, native look-and-feel tweaks). -|`[methodname]`afterInit(Component component)`` +|`afterInit(Component component)` |After SwingBridge has wired the frame into its canvas and frame updates are ready to flow. Useful for hooking up listeners on the Swing component or signalling readiness to the rest of the Vaadin view. |=== -A custom classloader supplier is contributed via `[methodname]`createClassLoaderSupplier()``, which subclasses also override (see <>). +A custom classloader supplier is contributed via `createClassLoaderSupplier()`, which subclasses also override (see <>). [[swing-bridge.reference.swingbridge-runner]] == `SwingBridgeRunner` Helpers -`[classname]`SwingBridgeRunner`` is a static utility used by the component itself, but several of its methods are public and useful when you build a custom classloader supplier. +`SwingBridgeRunner` is a static utility used by the component itself, but several of its methods are public and useful when you build a custom classloader supplier. [cols="3,4", options="header"] |=== |Method |Use -|`[methodname]`createSession(String mainClassFQN)`` -|Create a `[classname]`SwingBridgeSession`` that ties the Vaadin session to a specific main class. Pass it to `[methodname]`runSwingApp(...)``. +|`createSession(String mainClassFQN)` +|Create a `SwingBridgeSession` that ties the Vaadin session to a specific main class. Pass it to `runSwingApp(...)`. -|`[methodname]`runSwingApp(SwingBridgeSession, …)`` -|Launch the Swing application in an isolated `[classname]`AppContext``. Returns a `[classname]`CompletableFuture`` that resolves when the first window appears (or completes exceptionally on launch failure). +|`runSwingApp(SwingBridgeSession, …)` +|Launch the Swing application in an isolated `AppContext`. Returns a `CompletableFuture` that resolves when the first window appears (or completes exceptionally on launch failure). -|`[methodname]`loadSwingAppJarList()`` -|Read a `swing-app-jar-list.conf` from the classpath root and return the JAR paths it lists. Combine with `[methodname]`createClassLoader(...)``. +|`loadSwingAppJarList()` +|Read a `swing-app-jar-list.conf` from the classpath root and return the JAR paths it lists. Combine with `createClassLoader(...)`. -|`[methodname]`loadJarsFromDirectory()`` +|`loadJarsFromDirectory()` |Read every `.jar` in the configured `applibs` directory. -|`[methodname]`createClassLoader(List jars, ClassLoader parent)`` -|Build a `[classname]`URLClassLoader`` from the supplied JAR paths. +|`createClassLoader(List jars, ClassLoader parent)` +|Build a `URLClassLoader` from the supplied JAR paths. |=== -[[swing-bridge.reference.sample-project]] -== Sample Project -The link:https://github.com/vaadin/skeleton-starter-vaadin-swing-bridge[skeleton starter] is the recommended starting point. It is a working SwingBridge project — Maven configuration, JVM flags, and a Vaadin view wired up — that you can clone and adapt to your own Swing application by replacing the JARs in `applibs/`. See <> for the walkthrough. - - -[[swing-bridge.reference.next-steps]] -== Next Steps - -- Bring in your own Swing JAR and wire up a Vaadin view: <>. -- Tune runtime behaviour: <>. -- Diagnose launch failures: <>. diff --git a/articles/tools/modernization-toolkit/swing-bridge/running-and-debugging.adoc b/articles/tools/modernization-toolkit/swing-bridge/running-and-debugging.adoc index 1dc973efdb..eb7d2dc26a 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/running-and-debugging.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/running-and-debugging.adoc @@ -15,7 +15,7 @@ include::{articles}/_vaadin-version.adoc[] [[swing-bridge.running-and-debugging.cli]] == Running from the Command Line -SwingBridge requires special JVM flags to access internal Java modules. Because of this, running the application by clicking the green play button in IntelliJ IDEA or the equivalent in VS Code is not supported at this time. +SwingBridge requires special JVM flags to access internal Java modules. Because of this, running the application through IDE requires configuring it with the required JVM flags. (The famous green play button) To run the application, use Maven from the command line as described in <> (skeleton starter) or <> (from-scratch project). diff --git a/articles/tools/modernization-toolkit/swing-bridge/troubleshooting.adoc b/articles/tools/modernization-toolkit/swing-bridge/troubleshooting.adoc index 28f4b82cad..9b60a6900d 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/troubleshooting.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/troubleshooting.adoc @@ -42,36 +42,3 @@ or |No valid Vaadin commercial license in `~/.vaadin/` (or `%userprofile%\.vaadin\`). See <>. |=== - -[.collapsible-list] -== Frequently Asked Questions - -.What is SwingBridge? -[%collapsible] -==== -SwingBridge is a Vaadin component that allows you to run existing Swing applications in a web browser without rewriting them. It captures the Swing UI as images and streams them to the browser while handling user interactions. -==== - -.Does the existing Swing code need modification? -[%collapsible] -==== -Swing applications originally are designed and built with single tenancy in mind. Local resource usages like filesystem access, serial devices etc. should be refactored to achieve full multi-tenancy. Vaadin has relevant tooling to automate code refactoring. -==== - -.What Swing components are supported? -[%collapsible] -==== -All standard Swing components are supported, as well as your customized Swing components. - -- `JFrame`, `JDialog`, `JWindow` -- JPopupMenu and combo box popups -- JFileChooser (with special upload handling) -- Tooltips -- All standard Swing widgets (buttons, text fields, tables, etc.) -==== - -.How does SwingBridge work? -[%collapsible] -==== -SwingBridge runs your Swing application on the server and continuously inspects the Swing UI for changes. As soon as a change is detected, dirty regions are streamed to the browser to keep the updates as lightweight as possible. User interactions (clicks, keyboard input) are sent back to the server and replayed on the actual Swing components. -==== From c1b055649739a5caedfb00830a84f34be9e1889e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eftun=20T=C3=BCrkmen?= Date: Thu, 21 May 2026 16:33:17 +0300 Subject: [PATCH 4/5] Update naming chore: change from getting-started to quick-start chore: change from installation to installation-from-scratch chore: clarify confusion in adding-your-app --- .../swing-bridge/adding-your-app.adoc | 8 +++---- .../swing-bridge/configuration.adoc | 2 +- ...on.adoc => installation-from-scratch.adoc} | 22 +++++++++---------- ...ng-started.adoc => quick-start-guide.adoc} | 20 ++++++++--------- .../swing-bridge/running-and-debugging.adoc | 2 +- .../swing-bridge/troubleshooting.adoc | 4 ++-- 6 files changed, 29 insertions(+), 29 deletions(-) rename articles/tools/modernization-toolkit/swing-bridge/{installation.adoc => installation-from-scratch.adoc} (94%) rename articles/tools/modernization-toolkit/swing-bridge/{getting-started.adoc => quick-start-guide.adoc} (81%) diff --git a/articles/tools/modernization-toolkit/swing-bridge/adding-your-app.adoc b/articles/tools/modernization-toolkit/swing-bridge/adding-your-app.adoc index 8da4cacf2f..1e098c3f3f 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/adding-your-app.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/adding-your-app.adoc @@ -2,7 +2,7 @@ title: Adding Your Swing Application page-title: Add a Swing App to SwingBridge | Vaadin Tools description: Wire your Swing application's JARs into SwingBridge and create a Vaadin view that hosts it. -meta-description: Bring your Swing JAR into a SwingBridge project, choose a JAR-loading strategy, and wrap the application in a Vaadin Flow view. +meta-description: Bring your Swing JAR into a SwingBridge project, choose a JAR-loading strategy, and wrap the application in a Vaadin view. order: 3 --- @@ -14,9 +14,9 @@ include::{articles}/_vaadin-version.adoc[] This page covers two things: . *Make your Swing JAR (and its dependencies) visible to SwingBridge* using one of two loading strategies — the `applibs` directory or a `swing-app-jar-list.conf` file. -. *Create a Vaadin Flow view* that wraps the Swing application's `main` class. +. *Create a Vaadin view* that wraps the Swing application's `main` class. -The instructions apply equally whether you started from the skeleton starter (<>) or set up the project from scratch (<>). +The instructions apply equally whether you started from the skeleton starter (<>) or set up the project from scratch (<>). [[swing-bridge.adding-your-app.jar-loading]] @@ -67,7 +67,7 @@ my-swingbridge-project/ └── src/... ---- -To use a custom directory, pass `-Dapplibs.dir=` on the command line or configure it under `` in your `pom.xml` (see <>). +To use a custom directory, pass `-Dapplibs.dir=` on the command line or configure it under `` in your `pom.xml` (see <>). [[swing-bridge.adding-your-app.jar-loading.jar-list]] diff --git a/articles/tools/modernization-toolkit/swing-bridge/configuration.adoc b/articles/tools/modernization-toolkit/swing-bridge/configuration.adoc index 3c09ff6293..01d8bc0a13 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/configuration.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/configuration.adoc @@ -42,7 +42,7 @@ This page lists the runtime knobs SwingBridge reads from JVM system properties, |When set to `false`, the launch-failure error view shows only the failure header — the exception type, message, and stack trace are suppressed and the report-submission form is hidden. See <<#swing-bridge.configuration.error-reporting, Launch Failure Error View>> below. |=== -For Spring Boot, set system properties through `` on the `spring-boot-maven-plugin` (see <>) or pass `-D` flags on the command line. For a packaged JAR, pass them with `-D` on the command line: +For Spring Boot, set system properties through `` on the `spring-boot-maven-plugin` (see <>) or pass `-D` flags on the command line. For a packaged JAR, pass them with `-D` on the command line: [source,terminal] ---- diff --git a/articles/tools/modernization-toolkit/swing-bridge/installation.adoc b/articles/tools/modernization-toolkit/swing-bridge/installation-from-scratch.adoc similarity index 94% rename from articles/tools/modernization-toolkit/swing-bridge/installation.adoc rename to articles/tools/modernization-toolkit/swing-bridge/installation-from-scratch.adoc index c5365fa1a8..c9a388c385 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/installation.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/installation-from-scratch.adoc @@ -1,6 +1,6 @@ --- -title: Installation -page-title: Install and Configure SwingBridge | Vaadin Tools +title: Installation from Scratch +page-title: Install SwingBridge from Scratch | Vaadin Tools description: Install the SwingBridge license and set up a Maven project from scratch. meta-description: Step-by-step license installation and from-scratch Maven configuration for Vaadin SwingBridge, including the full JVM flag reference. order: 2 @@ -8,8 +8,8 @@ order: 2 include::{articles}/_vaadin-version.adoc[] -[[swing-bridge.installation]] -= Installation +[[swing-bridge.installation-from-scratch]] += Installation from Scratch This page covers the installation steps for a SwingBridge project that is not based on the skeleton starter: @@ -17,16 +17,16 @@ This page covers the installation steps for a SwingBridge project that is not ba . Configure a Maven project from scratch. . Apply the JVM flags SwingBridge needs at compile time and at runtime. -If you only want a quick try-out, the <> page uses the skeleton starter and skips most of the manual configuration below. +If you only want a quick try-out, the <> page uses the skeleton starter and skips most of the manual configuration below. -[[swing-bridge.installation.license]] +[[swing-bridge.installation-from-scratch.license]] == License Installation SwingBridge requires a commercial Vaadin subscription or a trial license. You can get one automatically or install it manually. Automatic license installation is the preferred choice. You are asked to either create a new vaadin.com account or login to an existing one in the following process. -[[swing-bridge.installation.license.automated]] +[[swing-bridge.installation-from-scratch.license.automated]] === Automated License Installation When you launch your application that uses SwingBridge or any other commercial Vaadin component, you are asked to login to https://vaadin.com/[vaadin.com]. This process downloads the relevant files to the directory shown below and the application proceeds to execute the commercial components automatically. You may proceed with the project setup if you prefer this approach. @@ -47,7 +47,7 @@ When you launch your application that uses SwingBridge or any other commercial V -- -[[swing-bridge.installation.license.manual]] +[[swing-bridge.installation-from-scratch.license.manual]] === Manual License Installation Create a Vaadin account if you don't have one by visiting https://vaadin.com/register @@ -74,7 +74,7 @@ Follow the instructions in the *Licenses* section after logging in to your accou For more information about licensing see <>. -[[swing-bridge.installation.project-setup]] +[[swing-bridge.installation-from-scratch.project-setup]] == Project Setup Add the following parent section, properties, and dependencies to your `pom.xml`: @@ -242,7 +242,7 @@ The `java.awt.headless=false` system property is mandatory. SwingBridge needs a ==== -[[swing-bridge.installation.jvm-flags]] +[[swing-bridge.installation-from-scratch.jvm-flags]] == JVM Flags Reference The runtime `` block above bundles three categories of flags. The table below lists each one with its purpose, so you can tell which lines are load-bearing versus which only widen access for specific Swing APIs. @@ -303,7 +303,7 @@ The runtime `` block above bundles three categories of flags. The The dev-time list in `.mvn/jvm.config` is the same minus `--patch-module` and `-Xbootclasspath/a` — those only apply at runtime. -[[swing-bridge.installation.next-steps]] +[[swing-bridge.installation-from-scratch.next-steps]] == Next Steps - Bring in your own Swing JAR: <>. diff --git a/articles/tools/modernization-toolkit/swing-bridge/getting-started.adoc b/articles/tools/modernization-toolkit/swing-bridge/quick-start-guide.adoc similarity index 81% rename from articles/tools/modernization-toolkit/swing-bridge/getting-started.adoc rename to articles/tools/modernization-toolkit/swing-bridge/quick-start-guide.adoc index 3a241c4975..3b0cc43cd3 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/getting-started.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/quick-start-guide.adoc @@ -1,6 +1,6 @@ --- -title: Getting Started -page-title: Get Started with SwingBridge | Vaadin Tools +title: Quick Start +page-title: Quick Start with SwingBridge | Vaadin Tools description: Run a Swing application in the browser in minutes with the SwingBridge skeleton starter. meta-description: Clone the SwingBridge skeleton starter, drop your Swing JAR into applibs, and run it in the browser. Five-minute happy path. order: 1 @@ -8,26 +8,26 @@ order: 1 include::{articles}/_vaadin-version.adoc[] -[[swing-bridge.getting-started]] -= Getting Started +[[swing-bridge.quick-start-guide]] += Quick Start This page walks through the fastest path to a running SwingBridge application. The goal is to get the bundled sample Swing app rendering in your browser, so you can see what SwingBridge does end‑to‑end before adapting it to your own code. -For a from‑scratch Maven project (no skeleton), see <>. To replace the sample app with your own JAR, see <>. +For a from‑scratch Maven project (no skeleton), see <>. To replace the sample app with your own JAR, see <>. -[[swing-bridge.getting-started.prerequisites]] +[[swing-bridge.quick-start-guide.prerequisites]] == Before You Start You need: - *Java 21 or later*. SwingBridge requires the same minimum JDK as Vaadin. -- *A Vaadin commercial subscription or trial license* installed in your home directory (`~/.vaadin/proKey` on macOS or Linux, `%userprofile%\.vaadin\proKey` on Windows). The first execution prompts you to log in and downloads the license automatically; for the manual route see <>. +- *A Vaadin commercial subscription or trial license* installed in your home directory (`~/.vaadin/proKey` on macOS or Linux, `%userprofile%\.vaadin\proKey` on Windows). The first execution prompts you to log in and downloads the license automatically; for the manual route see <>. Maven is *not* required separately — the skeleton starter ships with Maven Wrapper. -[[swing-bridge.getting-started.clone]] +[[swing-bridge.quick-start-guide.clone]] == Clone the Skeleton Starter [source,terminal] @@ -39,7 +39,7 @@ cd skeleton-starter-vaadin-swing-bridge The starter ships with a sample Swing application in the `applibs` directory, a Vaadin view that wraps it, and the Maven configuration with the JVM flags SwingBridge needs. -[[swing-bridge.getting-started.run]] +[[swing-bridge.quick-start-guide.run]] == Run the Application [.example] @@ -65,7 +65,7 @@ SwingBridge needs special JVM flags to access internal Java modules, so the IDE' ==== -[[swing-bridge.getting-started.next-steps]] +[[swing-bridge.quick-start-guide.next-steps]] == Next Steps - Replace the sample with your own application: <>. diff --git a/articles/tools/modernization-toolkit/swing-bridge/running-and-debugging.adoc b/articles/tools/modernization-toolkit/swing-bridge/running-and-debugging.adoc index eb7d2dc26a..216f6b341b 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/running-and-debugging.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/running-and-debugging.adoc @@ -17,7 +17,7 @@ include::{articles}/_vaadin-version.adoc[] SwingBridge requires special JVM flags to access internal Java modules. Because of this, running the application through IDE requires configuring it with the required JVM flags. (The famous green play button) -To run the application, use Maven from the command line as described in <> (skeleton starter) or <> (from-scratch project). +To run the application, use Maven from the command line as described in <> (skeleton starter) or <> (from-scratch project). [NOTE] ==== diff --git a/articles/tools/modernization-toolkit/swing-bridge/troubleshooting.adoc b/articles/tools/modernization-toolkit/swing-bridge/troubleshooting.adoc index 9b60a6900d..4fc132494e 100644 --- a/articles/tools/modernization-toolkit/swing-bridge/troubleshooting.adoc +++ b/articles/tools/modernization-toolkit/swing-bridge/troubleshooting.adoc @@ -24,7 +24,7 @@ When SwingBridge cannot start the embedded Swing application, the canvas is repl |`AWTError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.` (Linux) or `UnsatisfiedLinkError` loading `libawt_xawt.so` / `awt.dll` early in startup. -|The runtime JVM flags are missing — specifically `--patch-module java.desktop=…` and `-Xbootclasspath/a:…`. Without them the JDK falls back to the native AWT toolkit and tries to open a real display. Apply the full flag set from <>. +|The runtime JVM flags are missing — specifically `--patch-module java.desktop=…` and `-Xbootclasspath/a:…`. Without them the JDK falls back to the native AWT toolkit and tries to open a real display. Apply the full flag set from <>. |`HeadlessException` on startup, or "no graphics environment" errors. |`java.awt.headless` is `true` (or unset and defaulting to `true` in your environment). Set `-Djava.awt.headless=false` (or add it under `` in `spring-boot-maven-plugin`). @@ -39,6 +39,6 @@ or |System fonts that the patched font path does not include, or no fonts installed at all. Install the standard fonts your Swing application expects (typically Liberation, DejaVu, or Microsoft Core Fonts on Linux) into one of the standard system font directories (`/usr/share/fonts/...`). |`License is invalid` or trial key prompt on startup. -|No valid Vaadin commercial license in `~/.vaadin/` (or `%userprofile%\.vaadin\`). See <>. +|No valid Vaadin commercial license in `~/.vaadin/` (or `%userprofile%\.vaadin\`). See <>. |=== From 956a13ff303174cf1884e0c2e6f1b59e253bd7cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eftun=20T=C3=BCrkmen?= <134262032+eftunv@users.noreply.github.com> Date: Fri, 22 May 2026 14:07:52 +0300 Subject: [PATCH 5/5] Update swing-bridge version to 1.1.2 --- articles/_vaadin-version.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/_vaadin-version.adoc b/articles/_vaadin-version.adoc index 2e84762c4c..c0f4c7a0b2 100644 --- a/articles/_vaadin-version.adoc +++ b/articles/_vaadin-version.adoc @@ -5,4 +5,4 @@ :vaadin-seven-version: 7.7.49 :vaadin-eight-version: 8.28.4 :spring-boot-version: 4.0.6 -:swing-bridge-version: 1.1.1 +:swing-bridge-version: 1.1.2