Browse Source

Merge pull request #213 from JetBrains/updTutorials

Updated Window control API and Swing interoperability tutorials.
pull/215/head
Roman Sedaikin 4 years ago committed by GitHub
parent
commit
6aaf291136
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 113
      tutorials/Swing_Integration/README.md
  2. BIN
      tutorials/Swing_Integration/swing_panel.gif
  3. 83
      tutorials/Window_API/README.md
  4. BIN
      tutorials/Window_API/window_state.gif

113
tutorials/Swing_Integration/README.md

@ -2,7 +2,7 @@
## What is covered
In this tutorial, we will show you how to use ComposePanel in your Swing application.
In this tutorial, we will show you how to use ComposePanel and SwingPanel in your application.
## Using ComposePanel
@ -146,4 +146,113 @@ fun Counter(text: String, counter: MutableState<Int>) {
![IntegrationWithSwing](screenshot.png)
### Note. Adding a Swing component to CFD composition is not currently supported.
## Adding a Swing component to CFD composition using SwingPanel.
SwingPanel lets you create a UI using Swing components in a Compose-based UI. To achieve this you need to create Swing component and pass it as a parameter to SwingPanel.
```kotlin
import androidx.compose.desktop.SwingPanel
import androidx.compose.desktop.Window
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.padding
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import java.awt.Component
import java.awt.Dimension
import java.awt.event.ActionEvent
import java.awt.event.ActionListener
import javax.swing.BoxLayout
import javax.swing.JButton
import javax.swing.JPanel
fun main() {
Window {
val counter = remember { mutableStateOf(0) }
val inc: () -> Unit = { counter.value++ }
val dec: () -> Unit = { counter.value-- }
Box(
modifier = Modifier.fillMaxWidth().height(60.dp).padding(top = 20.dp),
contentAlignment = Alignment.Center
) {
Text("Counter: ${counter.value}")
}
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Column(
modifier = Modifier.padding(top = 80.dp, bottom = 20.dp)
) {
Button("1. Compose Button: increment", inc)
Spacer(modifier = Modifier.height(20.dp))
Box(
modifier = Modifier.size(270.dp, 90.dp)
) {
SwingPanel(
component = swingBox(dec),
background = Color.White
)
}
Spacer(modifier = Modifier.height(20.dp))
Button("2. Compose Button: increment", inc)
}
}
}
}
@Composable
fun Button(text: String = "", action: (() -> Unit)? = null) {
Button(
modifier = Modifier.size(270.dp, 30.dp),
onClick = { action?.invoke() }
) {
Text(text)
}
}
fun swingBox(action: (() -> Unit)? = null): Component {
val box = JPanel()
box.setLayout(BoxLayout(box, BoxLayout.Y_AXIS))
box.add(actionButton("1. Swing Button: decrement", action))
box.add(actionButton("2. Swing Button: decrement", action))
box.add(actionButton("3. Swing Button: decrement", action))
return box
}
fun actionButton(
text: String,
action: (() -> Unit)? = null
): JButton {
val button = JButton(text)
button.setAlignmentX(Component.CENTER_ALIGNMENT)
button.addActionListener(object : ActionListener {
public override fun actionPerformed(e: ActionEvent) {
action?.invoke()
}
})
return button
}
```
![IntegrationWithSwing](swing_panel.gif)

BIN
tutorials/Swing_Integration/swing_panel.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 MiB

83
tutorials/Window_API/README.md

@ -66,7 +66,7 @@ fun main() {
## Window attributes
Each window has 9 parameters, all of them could be omitted and have default values:
Each window has following parameters, all of them could be omitted and have default values:
1. title – window title
2. size – initial window size
@ -75,8 +75,9 @@ Each window has 9 parameters, all of them could be omitted and have default valu
5. icon – window icon
6. menuBar – window context menu
7. undecorated – disable native border and title bar of the window
8. events – window events
9. onDismissEvent – event when removing the window content from a composition
8. resizable – makes the window resizable or unresizable
9. events – window events
10. onDismissEvent – event when removing the window content from a composition
An example of using window parameters in the creation step:
@ -177,8 +178,9 @@ AppWindow parameters correspond to the following properties:
3. height – window height
4. x – position of the left top corner of the window along the X axis
5. y – position of the left top corner of the window along the Y axis
6. icon – window icon image
7. events – window events
6. resizable - returns `true` if the window resizable, `false` otherwise
7. icon – window icon image
8. events – window events
To get the properties of a window, it is enough to have a link to the current or specific window. There are two ways to get the current focused window:
@ -276,6 +278,7 @@ Using the following methods, you can change the properties of the AppWindow:
3. setLocation(x: Int, y: Int) – window position
4. setWindowCentered() – set the window to the center of the display
5. setIcon(image: BufferedImage?) – window icon
6. setMenuBar(menuBar: MenuBar) - window menu bar
```kotlin
import androidx.compose.desktop.AppWindowAmbient
@ -300,6 +303,76 @@ fun main() {
![Window properties](center_the_window.gif)
## Methods
Using the following methods, you can change the state of the AppWindow:
1. show(parentComposition: CompositionReference? = null, content: @Composable () -> Unit) – shows a window with the given Compose content,
`parentComposition` is the parent of this window's composition.
2. close() - closes the window.
3. minimize() - minimizes the window to the taskbar. If the window is in fullscreen mode this method is ignored.
4. maximize() - maximizes the window to fill all available screen space. If the window is in fullscreen mode this method is ignored.
5. makeFullscreen() - switches the window to fullscreen mode if the window is resizable. If the window is in fullscreen mode `minimize()` and `maximize()` methods are ignored.
6. restore() - restores the normal state and size of the window after maximizing/minimizing/fullscreen mode.
You can know about window state via properties below:
1. isMinimized - returns true if the window is minimized, false otherwise.
2. isMaximized - returns true if the window is maximized, false otherwise.
3. isFullscreen - returns true if the window is in fullscreen state, false otherwise.
```kotlin
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.Spacer
import androidx.compose.desktop.AppManager
import androidx.compose.desktop.AppWindow
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import javax.swing.SwingUtilities.invokeLater
fun main() = invokeLater {
AppWindow().show {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Column(
modifier = Modifier.padding(top = 20.dp, bottom = 20.dp)
) {
Button("Minimize", { AppManager.focusedWindow?.minimize() })
Button("Maximize", { AppManager.focusedWindow?.maximize() })
Button("Fullscreen", { AppManager.focusedWindow?.makeFullscreen() })
Button("Restore", { AppManager.focusedWindow?.restore() })
Spacer(modifier = Modifier.height(20.dp))
Button("Close", { AppManager.focusedWindow?.close() })
}
}
}
}
@Composable
fun Button(text: String = "", action: (() -> Unit)? = null) {
Button(
modifier = Modifier.size(150.dp, 30.dp),
onClick = { action?.invoke() }
) {
Text(text)
}
Spacer(modifier = Modifier.height(10.dp))
}
```
![Window state](window_state.gif)
## Window events
Events can be defined using the events parameter in the window creation step or redefine using the events property at runtime.

BIN
tutorials/Window_API/window_state.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 MiB

Loading…
Cancel
Save