> Markdown version of [Quick Start](https://vaadin.com/docs/v25/tools/modernization-toolkit/swing-bridge/interop/quick-start). Section index: [llms.txt](https://vaadin.com/docs/v25/tools/llms.txt)

# <a id="swing-bridge.interop.quick-start"></a>Interop Quick Start

This page walks through the minimal end-to-end setup for both interop directions, using only the defaults:

- **Vaadin → Swing**: a Vaadin button calls a `void` method on the Swing application’s main window.

- **Swing → Vaadin**: a Swing button fires an event that a Vaadin view handles with a notification.

Everything here uses the simplest possible shape — a `JFrame` target (no instance discovery configuration), `void` methods and `String` parameters (no async shapes, no domain types), and default dispatch. The following pages cover every variant: [invocation shapes and instance discovery](https://vaadin.com/docs/v25/tools/modernization-toolkit/swing-bridge/interop/calling-swing-methods.md), [dispatch modes and listener wiring](https://vaadin.com/docs/v25/tools/modernization-toolkit/swing-bridge/interop/listening-to-swing-events.md), and [passing your own types across the bridge](https://vaadin.com/docs/v25/tools/modernization-toolkit/swing-bridge/interop/sharing-domain-types.md).

> **Note: Prerequisites**
>
> You need a Swing application already embedded and rendering in a Vaadin view. If you don’t have that yet, follow the [SwingBridge Quick Start](https://vaadin.com/docs/v25/tools/modernization-toolkit/swing-bridge/quick-start-guide.md) first.

## <a id="swing-bridge.interop.quick-start.swing-side"></a>Step 1: Add the Annotations JAR to the Swing Application

The Swing side needs one compile-only JAR, `swing-bridge-annotations`. In a Maven build:

```xml
<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>swing-bridge-annotations</artifactId>
    <version>1.3.0</version>
    <scope>provided</scope>
</dependency>
```

For Gradle, Ant, IDE-managed `lib/` folders, or projects without a build tool, see [Adding the Annotations JAR](https://vaadin.com/docs/v25/tools/modernization-toolkit/swing-bridge/interop.md#swing-bridge.interop.prerequisites.annotations).

## <a id="swing-bridge.interop.quick-start.expose"></a>Step 2: Expose a Swing Method

Annotate a `public` method on the application’s main window with `@ExposedMethod`. Because the class extends `JFrame`, the framework finds the live instance automatically — no extra configuration:

```java
package com.example.swingapp;

import com.vaadin.swingbridge.interop.ExposedMethod;
import javax.swing.JFrame;

public class MainWindow extends JFrame {

    @ExposedMethod
    public void showMessage(String message) {
        statusLabel.setText(message);
    }
}
```

The class stays a normal Swing class — it imports nothing from Vaadin. Rebuild the Swing application’s JAR so the annotation is in the bytecode.

## <a id="swing-bridge.interop.quick-start.codegen"></a>Step 3: Generate the Bridge in the Vaadin Application

Add the codegen plugin to the Vaadin application’s `pom.xml`:

```xml
<build>
    <plugins>
        <plugin>
            <groupId>com.vaadin</groupId>
            <artifactId>swing-bridge-codegen-maven-plugin</artifactId>
            <version>1.3.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate-bridge</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
```

At build time the plugin scans the Swing JARs in `applibs/`, finds `MainWindow`, and emits a typed interface into `target/generated-sources/swing-bridge/`:

```java
// Generated — don't edit
package com.example.swingapp;

public interface MainWindowBridge {
    void showMessage(String message);
}
```

The generated sources are added to the Maven compile source roots automatically, so Vaadin code can import `MainWindowBridge` with no further wiring. Run `mvn compile` (or refresh the Maven project in your IDE) to see it.

## <a id="swing-bridge.interop.quick-start.call"></a>Step 4: Call the Swing Method from Vaadin

In the Vaadin view, obtain a handle with `SwingBridge.interop().of(…​)` and call the method inside `onReady`:

```java
package com.example.application;

import com.example.swingapp.MainWindowBridge;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
import com.vaadin.swingbridge.SwingBridge;

@Route("main")
public class MainView extends VerticalLayout {

    public MainView() {
        add(new SwingBridge("com.example.swingapp.SwingAppMain"));

        add(new Button("Greet Swing", click ->
                SwingBridge.interop()
                    .of(MainWindowBridge.class)
                    .onReady(main -> main.showMessage("Hello from Vaadin!"))));
    }
}
```

`onReady` runs the callback as soon as the bridge is available — immediately, if the Swing application has already started. The call is dispatched onto the Swing Event Dispatch Thread for you.

Run the application, click the button, and the Swing status label updates. That’s the whole Vaadin → Swing direction.

## <a id="swing-bridge.interop.quick-start.listen"></a>Step 5: Fire a Swing Event into Vaadin

The other direction uses a plain listener interface. Define it in the Swing application:

```java
package com.example.swingapp;

public interface MessageListener {
    void messageSubmitted(String message);
}
```

Let the main window accept a listener through an `@ExposedMethod` setter, and fire it from any Swing event handler:

```java
public class MainWindow extends JFrame {

    private MessageListener messageListener;

    @ExposedMethod
    public void setMessageListener(MessageListener listener) {
        this.messageListener = listener;
    }

    private void onSendButtonClicked() {
        if (messageListener != null) {
            messageListener.messageSubmitted(inputField.getText());
        }
    }
}
```

Rebuild the Swing JAR. The codegen plugin also emits a stub of `MessageListener` for the Vaadin side, so there’s nothing extra to share.

On the Vaadin view, implement the listener method as a `@VaadinCallback` and register it. The framework proxies the listener, hops onto the Vaadin UI thread, and invokes your handler:

```java
package com.example.application;

import com.example.swingapp.MainWindowBridge;
import com.example.swingapp.MessageListener;
import com.vaadin.flow.component.AttachEvent;
import com.vaadin.flow.component.DetachEvent;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.shared.Registration;
import com.vaadin.swingbridge.SwingBridge;
import com.vaadin.swingbridge.interop.VaadinCallback;

@Route("main")
public class MainView extends VerticalLayout {

    private Registration callbackRegistration;

    public MainView() {
        add(new SwingBridge("com.example.swingapp.SwingAppMain"));
        // ... the "Greet Swing" button from Step 4 ...
    }

    @Override
    protected void onAttach(AttachEvent attachEvent) {
        super.onAttach(attachEvent);
        callbackRegistration = SwingBridge.interop()
            .of(MainWindowBridge.class)
            .registerCallback(this);
    }

    @Override
    protected void onDetach(DetachEvent detachEvent) {
        if (callbackRegistration != null) {
            callbackRegistration.remove();
            callbackRegistration = null;
        }
        super.onDetach(detachEvent);
    }

    @VaadinCallback(observerFor = MessageListener.class)
    public void messageSubmitted(String message) {
        Notification.show("Swing says: " + message);
    }
}
```

Run the application again, type something into the Swing text field, click the Swing button — a Vaadin notification pops up with the text. That’s the Swing → Vaadin direction.

Always pair `registerCallback` in `onAttach` with `Registration.remove()` in `onDetach`, as above — it keeps listeners from piling up as the user navigates. The reasoning is in [The Cleanup Pattern](https://vaadin.com/docs/v25/tools/modernization-toolkit/swing-bridge/interop/listening-to-swing-events.md#swing-bridge.interop.listening-to-swing-events.cleanup).

## <a id="swing-bridge.interop.quick-start.next"></a>Where to Go Next

This page used the simplest variant of every ingredient. Each has more capable forms:

| You need to…                                                                                                                                                                         | Read                                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Return a value from Swing, or call a method that might block the EDT (dialogs, slow work) — the `SYNC`/`ASYNC` invocation shapes and `requestAsync`                                  | [Calling Swing Methods](https://vaadin.com/docs/v25/tools/modernization-toolkit/swing-bridge/interop/calling-swing-methods.md)                                                                           |
| Expose methods on a class that isn’t a `Window` — `@InstanceProvider` factories and static-only utility classes                                                                      | [Calling Swing Methods → Instance Discovery](https://vaadin.com/docs/v25/tools/modernization-toolkit/swing-bridge/interop/calling-swing-methods.md#swing-bridge.interop.calling-swing-methods.discovery) |
| Support multiple subscribers with clean removal, return a value from Vaadin back to Swing, or drop events safely on navigation — adder/remover wiring and the three `Dispatch` modes | [Listening to Swing Events](https://vaadin.com/docs/v25/tools/modernization-toolkit/swing-bridge/interop/listening-to-swing-events.md)                                                                   |
| Pass your own entity or DTO classes across the bridge without `ClassCastException`                                                                                                   | [Sharing Domain Types](https://vaadin.com/docs/v25/tools/modernization-toolkit/swing-bridge/interop/sharing-domain-types.md)                                                                             |
| Combine the ingredients — Vaadin-rendered lookup dialogs, navigation guards, `runInAppContext`                                                                                       | [Patterns and Cookbook](https://vaadin.com/docs/v25/tools/modernization-toolkit/swing-bridge/interop/patterns.md)                                                                                        |
