Swing interoperability
Edit pageLast modified: 29 November 2024Here, you'll learn about using Swing components in the Compose Multiplatform application and vice versa, the limitations and advantages of this interoperability, and when you should or shouldn't use this approach.
The interoperability between Compose Multiplatform and Swing aims to help you:
Simplify and smooth the migration process of Swing applications to Compose Multiplatform.
Enhance Compose Multiplatform applications using Swing components when no Compose analogues are available.
In many cases, it's more effective to implement a missing component directly in Compose Multiplatform (and contribute it to the community) rather than using a Swing component within a Compose Multiplatform application.
Swing interop use cases and limitations
Compose Multiplatform component in a Swing app
The first use case involves adding a Compose Multiplatform component to a Swing application. You can achieve it using the ComposePanel
Swing component to render the Compose Multiplatform part of the application. From Swing's perspective, ComposePanel
is another Swing component, and handles it accordingly.
Note that all Compose Multiplatform components, including popups, tooltips, and context menus, are rendered within Swing's ComposePanel
and positioned and resized inside it. Therefore, consider replacing these components with Swing-based implementations, or try two new experimental features:
- Off-screen rendering
Allows rendering of compose panels directly on Swing components.
- Separate platform views for popups, dialogs, and dropdowns
Popups are no longer limited by the initial composable canvas or the app window.
Here are several scenarios for using ComposePanel
:
Embed animated objects or a whole panel of animated objects into your application (for example, selection of emoticons or a toolbar with animated reactions to events).
Implement an interactive rendering area such as graphics or infographics in your application, which is easier and more convenient to accomplish using Compose Multiplatform.
Integrate a complex rendering area (potentially even animated) into your application, which is simpler with Compose Multiplatform.
Replace complex parts of the user interface in your Swing-based application, as Compose Multiplatform provides a convenient component layout system and a wide range of built-in components and options for quickly creating custom components.
Swing component in a Compose Multiplatform app
Another use case is when you need to use a component that exists in Swing but has no analog in Compose Multiplatform. If creating its new implementation from scratch is too time-consuming, try SwingPanel
. The SwingPanel
function serves as a wrapper that manages the size, position, and rendering of a Swing component placed on top of a Compose Multiplatform component.
Note that the Swing component within SwingPanel
will always be layered above the Compose Multiplatform component, so anything positioned underneath your SwingPanel
will be clipped by the Swing component. To avoid clipping and overlapping issues, try experimental interop blending. If there is still a risk of incorrect rendering, you can redesign the UI accordingly or avoid using SwingPanel
and try implementing the missing component, contributing to technology development.
Here are scenarios for using SwingPanel
:
Your application does not require popups, tooltips, or context menus, or at least they are not inside your
SwingPanel
.SwingPanel
remains in a fixed position. In this case, you reduce the risk of glitches and artifacts when the Swing component's position changes. However, this condition is not mandatory and should be tested for each particular case.
Compose Multiplatform and Swing can be combined in both ways, allowing for flexible UI design. You can place a SwingPanel
inside a ComposePanel
, which can also be inside another SwingPanel
. However, before using such nested combinations, consider potential rendering glitches. Refer to Layout with nested SwingPanel
and ComposePanel
for a code sample.
Use Compose Multiplatform in a Swing application
ComposePanel
allows you to create a UI with Compose Multiplatform within a Swing-based application. Add an instance of ComposePanel
to your Swing layout and define the composition inside setContent
:
composePanel.setContent { ComposeContent() }
{...}

Experimental off-screen rendering
An experimental mode allows rendering compose panels directly on Swing components. This prevents transitional rendering issues when panels are shown, hidden, or resized. It also enables proper layering when combining Swing components and compose panels: a Swing component can be shown above or beneath a ComposePanel
.
warning
Off-screen rendering is Experimental, and you should use it only for evaluation purposes.
To enable off-screen rendering, use the compose.swing.render.on.graphics
system property. The property must be set before executing any Compose code in your application, so it is recommended to enable it using the -D
command-line JVM argument at startup:
-Dcompose.swing.render.on.graphics=true
Alternatively, use System.setProperty()
at the entry point:
fun main() {
System.setProperty("compose.swing.render.on.graphics", "true")
...
}
Experimental separate views for popups
It can be important that popup elements such as tooltips and dropdown menus are not limited by the initial composable canvas or the app window. For example, when the composable view does not occupy the full screen but needs to spawn an alert dialog.
warning
Creating separate views or windows for popups is Experimental. Opt-in is required (see details below), and you should use it only for evaluation purposes.
To create separate views or windows for popups on desktop, set the compose.layers.type
system property. Supported values:
WINDOW
createsPopup
andDialog
components as separate undecorated windows.COMPONENT
createsPopup
orDialog
as a separate Swing component in the same window. Note that the setting requires enabled off-screen rendering (see the Experimental off-screen rendering section), and off-screen rendering only works forComposePanel
components, not full window applications.
Note that popups and dialogs are still unable to draw anything outside their own bounds (for example, the shadow of the topmost container).
Here is an example of the code that uses the COMPONENT
property:
@OptIn(ExperimentalComposeUiApi::class) fun main()
{...}
Use Swing in a Compose Multiplatform application
SwingPanel
allows you to create a UI with Swing within a Compose Multiplatform application. Use the factory
parameter of SwingPanel
to create a Swing JPanel
:
factory = { JPanel().apply { layout = BoxLayout(this, BoxLayout.Y_AXIS)
{...}

Update Swing components when Compose state changes
To keep a Swing component up to date, provide an update: (T) -> Unit
callback, which is invoked whenever the composable state changes or the layout is inflated. The following code sample demonstrates how to update a Swing component within a SwingPanel
whenever the composable state changes:
factory = { JPanel().apply { add(swingLabel, BorderLayout.CENTER)} }, update = {
{...}

Experimental interop blending
By default, the interop view implemented using the SwingPanel
wrapper is rectangular and in the foreground, on top of any Compose Multiplatform components. To make popup elements easier to use, we introduced experimental support for interop blending.
warning
Interop blending is Experimental, and you should use it only for evaluation purposes.
To enable this experimental feature, set the compose.interop.blending
system property to true
. The property must be enabled before executing any Compose code in your application, so set it via the -Dcompose.interop.blending=true
command-line JVM argument or use System.setProperty()
at the entry point:
fun main() {
System.setProperty("compose.interop.blending", "true")
...
}
With interop blending enabled, you can rely on Swing in the following use cases:
Clipping. You're no longer limited by a rectangular shape: the
clip
andshadow
modifiers work correctly withSwingPanel
.Overlapping. It is possible to draw any Compose Multiplatform content on top of a
SwingPanel
and interact with it as usual.
For details and known limitations, see the description on GitHub.
Layout with nested Swing and Compose Multiplatform components
With interoperability, you can combine Swing and Compose Multiplatform in both ways: adding Swing components to a Compose Multiplatform application and adding Compose Multiplatform components to a Swing application. If you want to nest several components and freely combine approaches, this scenario is also supported.
The following code sample demonstrates how to add a SwingPanel
to a ComposePanel
, which is already inside another SwingPanel
, creating a Swing-Compose Multiplatform-Swing structure:
fun SwingComponent() : JPanel { return JPanel().apply {
{...}

What's next?
Explore the tutorials about other desktop-specific components.
Thanks for your feedback!