Roman Sedaikin
4 years ago
committed by
GitHub
2 changed files with 152 additions and 0 deletions
@ -0,0 +1,152 @@ |
|||||||
|
# Integration Compose for Desktop into Swing-based aplication |
||||||
|
|
||||||
|
## What is covered |
||||||
|
|
||||||
|
In this tutorial, we will show you how to use ComposePanel in your Swing application. |
||||||
|
|
||||||
|
## Using ComposePanel |
||||||
|
|
||||||
|
ComposePanel lets you create a UI using Compose for Desktop in a Swing-based UI. To achieve this you need to create an instance of ComposePanel, add it to your Swing layout, and describe the composition inside `setContent`. You may also need to clear the CFD application events via `AppManager.setEvents`. |
||||||
|
|
||||||
|
```kotlin |
||||||
|
import androidx.compose.desktop.AppManager |
||||||
|
import androidx.compose.desktop.ComposePanel |
||||||
|
import androidx.compose.desktop.setContent |
||||||
|
import androidx.compose.foundation.background |
||||||
|
import androidx.compose.foundation.layout.Box |
||||||
|
import androidx.compose.foundation.layout.Column |
||||||
|
import androidx.compose.foundation.layout.fillMaxSize |
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth |
||||||
|
import androidx.compose.foundation.layout.height |
||||||
|
import androidx.compose.foundation.layout.Row |
||||||
|
import androidx.compose.foundation.layout.size |
||||||
|
import androidx.compose.foundation.layout.Spacer |
||||||
|
import androidx.compose.foundation.layout.width |
||||||
|
import androidx.compose.foundation.Text |
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape |
||||||
|
import androidx.compose.material.Button |
||||||
|
import androidx.compose.material.Surface |
||||||
|
import androidx.compose.runtime.Composable |
||||||
|
import androidx.compose.runtime.MutableState |
||||||
|
import androidx.compose.runtime.mutableStateOf |
||||||
|
import androidx.compose.ui.Alignment |
||||||
|
import androidx.compose.ui.graphics.Color |
||||||
|
import androidx.compose.ui.Modifier |
||||||
|
import androidx.compose.ui.unit.dp |
||||||
|
import java.awt.BorderLayout |
||||||
|
import java.awt.Dimension |
||||||
|
import java.awt.event.ActionEvent |
||||||
|
import java.awt.event.ActionListener |
||||||
|
import javax.swing.JFrame |
||||||
|
import javax.swing.JButton |
||||||
|
import javax.swing.SwingUtilities |
||||||
|
import javax.swing.WindowConstants |
||||||
|
|
||||||
|
val northClicks = mutableStateOf(0) |
||||||
|
val westClicks = mutableStateOf(0) |
||||||
|
val eastClicks = mutableStateOf(0) |
||||||
|
|
||||||
|
fun main() { |
||||||
|
// explicitly clear the application events |
||||||
|
AppManager.setEvents( |
||||||
|
onAppStart = null, |
||||||
|
onAppExit = null, |
||||||
|
onWindowsEmpty = null |
||||||
|
) |
||||||
|
SwingComposeWindow() |
||||||
|
} |
||||||
|
|
||||||
|
fun SwingComposeWindow() { |
||||||
|
val window = JFrame() |
||||||
|
|
||||||
|
// creating ComposePanel |
||||||
|
val composePanel = ComposePanel() |
||||||
|
window.defaultCloseOperation = WindowConstants.EXIT_ON_CLOSE |
||||||
|
window.title = "SwingComposeWindow" |
||||||
|
|
||||||
|
|
||||||
|
window.contentPane.add(actionButton("NORTH", { northClicks.value++ }), BorderLayout.NORTH) |
||||||
|
window.contentPane.add(actionButton("WEST", { westClicks.value++ }), BorderLayout.WEST) |
||||||
|
window.contentPane.add(actionButton("EAST", { eastClicks.value++ }), BorderLayout.EAST) |
||||||
|
window.contentPane.add( |
||||||
|
actionButton( |
||||||
|
text = "SOUTH/REMOVE COMPOSE", |
||||||
|
action = { |
||||||
|
window.contentPane.remove(composePanel) |
||||||
|
} |
||||||
|
), |
||||||
|
BorderLayout.SOUTH |
||||||
|
) |
||||||
|
|
||||||
|
// addind ComposePanel on JFrame |
||||||
|
window.contentPane.add(composePanel, BorderLayout.CENTER) |
||||||
|
|
||||||
|
// setting the content |
||||||
|
composePanel.setContent { |
||||||
|
ComposeContent() |
||||||
|
} |
||||||
|
|
||||||
|
window.setSize(800, 600) |
||||||
|
window.setVisible(true) |
||||||
|
} |
||||||
|
|
||||||
|
fun actionButton(text: String, action: (() -> Unit)? = null): JButton { |
||||||
|
val button = JButton(text) |
||||||
|
button.setToolTipText("Tooltip for $text button.") |
||||||
|
button.setPreferredSize(Dimension(100, 100)) |
||||||
|
button.addActionListener(object : ActionListener { |
||||||
|
public override fun actionPerformed(e: ActionEvent) { |
||||||
|
action?.invoke() |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
return button |
||||||
|
} |
||||||
|
|
||||||
|
@Composable |
||||||
|
fun ComposeContent() { |
||||||
|
Box( |
||||||
|
modifier = Modifier.fillMaxSize(), |
||||||
|
contentAlignment = Alignment.Center |
||||||
|
) { |
||||||
|
Row { |
||||||
|
Counter("West", westClicks) |
||||||
|
Spacer(modifier = Modifier.width(25.dp)) |
||||||
|
Counter("North", northClicks) |
||||||
|
Spacer(modifier = Modifier.width(25.dp)) |
||||||
|
Counter("East", eastClicks) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Composable |
||||||
|
fun Counter(text: String, counter: MutableState<Int>) { |
||||||
|
Surface( |
||||||
|
modifier = Modifier.size(130.dp, 130.dp), |
||||||
|
color = Color(180, 180, 180), |
||||||
|
shape = RoundedCornerShape(4.dp) |
||||||
|
) { |
||||||
|
Column { |
||||||
|
Box( |
||||||
|
modifier = Modifier.height(30.dp).fillMaxWidth(), |
||||||
|
contentAlignment = Alignment.Center |
||||||
|
) { |
||||||
|
Text(text = "${text}Clicks: ${counter.value}") |
||||||
|
} |
||||||
|
Spacer(modifier = Modifier.height(25.dp)) |
||||||
|
Box( |
||||||
|
modifier = Modifier.fillMaxSize(), |
||||||
|
contentAlignment = Alignment.Center |
||||||
|
) { |
||||||
|
Button(onClick = { counter.value++ }) { |
||||||
|
Text(text = text, color = Color.White) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
![IntegrationWithSwing](screenshot.png) |
||||||
|
|
||||||
|
### Note. Adding a Swing component to CFD composition is not currently supported. |
After Width: | Height: | Size: 147 KiB |
Loading…
Reference in new issue