LoginSignup
13
7

More than 3 years have passed since last update.

Compose for Desktopのウィジェットを思いつくだけ実装してみる

Last updated at Posted at 2020-12-05

Compose for Desktopとは

Android Jetpack ComposeをデスクトップOS向けに移植したライブラリ。
公式はCompose for Desktop UI Framework | JetBrains: Developer Tools for Professionals and Teams
AWTとSwingなどとの相互互換性を持ち、Skiaのグラフィックライブラリを使ってクロスプラットフォームを実現している。
実行ファイルにはJRE(JDKかな?)が同梱されるため、ファイルサイズは大きくなるが単体で実行可能。

この記事は?

とりあえず思いつく限りのコンポーネントを表示して、そのコードを示す。
殆どはAndroid JetPack Composeと同じ。一部使えないinfixとかあるけど。

今回のコード全体

compose-desktop-sample/all_widgets at main · iwahara/compose-desktop-sample

試したバージョン

kotlin: 1.4.20
compose for desktop : 0.2.0-build131

ベースウィンドウ

スクリーンショット 2020-11-28 1.20.56.png

各ボタンをクリックすると、それぞれのコンポーネントを使ったウィンドウが新規表示される。

Text

文字列を表示するコンポーネント。

スクリーンショット 2020-11-28 1.26.18.png


@Composable
fun TextSample() {
    val windowState = remember { mutableStateOf(false) }

    Button(onClick = {
        windowState.value = true
    }) {
        Text("Textのサンプル")
    }
    if (windowState.value) {
        Window(title = "Textのサンプル", size = IntSize(600, 600), location = IntOffset(100, 100), centered = false,
                onDismissRequest = {
                    windowState.value = false
                }) {
            Column {
                Text("テキスト")
                Divider() //区切り線
                Text(AnnotatedString(
                        text = "複数のスタイルを割り当てる",
                        spanStyles = listOf(
                                AnnotatedString.Range(SpanStyle(fontStyle = FontStyle.Italic), 0, 5)
                        ),
                        paragraphStyles = listOf(
                                AnnotatedString.Range(ParagraphStyle(textAlign = TextAlign.Center), 0, 6),
                        )
                ))
            }
        }
    }
}

Card

カード型のコンポーネント。
スクリーンショット 2020-11-28 1.32.03.png


@Composable
fun CardSample() {
    val windowState = remember { mutableStateOf(false) }

    Button(onClick = {
        windowState.value = true
    }) {
        Text("Cardのサンプル")
    }
    if (windowState.value) {
        Window(title = "Cardのサンプル", size = IntSize(600, 600), location = IntOffset(100, 100), centered = false,
                onDismissRequest = {
                    windowState.value = false
                }) {
            Column {
                Card(Modifier.fillMaxWidth().padding(8.dp), elevation = 8.dp) {
                    Text("カードだよ")
                }
            }
        }

    }
}

TextField

文字入力するためのコンポーネント。
TextField.gif


@Composable
fun TextFieldSample() {
    val windowState = remember { mutableStateOf(false) }
    val textField = remember { mutableStateOf("") }
    Button(onClick = {
        windowState.value = true
    }) {
        Text("TextFieldのサンプル")
    }
    if (windowState.value) {
        Window(title = "TextFieldのサンプル", size = IntSize(600, 600), location = IntOffset(100, 100),
                centered = false,
                onDismissRequest = {
                    windowState.value = false
                }) {

            Column {
                TextField(value = textField.value, onValueChange = {
                    textField.value = it
                }, label = {
                    Text("ラベル")
                }, placeholder = {
                    Text("プレースホルダー")
                })
                Text(textField.value)
            }
        }
    }

}

CheckBox

チェックボックスのコンポーネント。
スクリーンショット 2020-11-29 21.16.22.png
スクリーンショット 2020-11-29 21.16.27.png


@Composable
fun CheckBoxSample() {
    val windowState = remember { mutableStateOf(false) }
    val checked = remember { mutableStateOf(true) }
    Button(onClick = {
        windowState.value = true
    }) {
        Text("CheckBoxのサンプル")
    }
    if (windowState.value) {
        Window(title = "CheckBoxのサンプル", size = IntSize(600, 600), location = IntOffset(100, 100), centered = false,
                onDismissRequest = {
                    windowState.value = false
                }) {
            Column {
                Checkbox(checked = checked.value,
                        onCheckedChange = {
                            checked.value = it
                        })
                Text(if (checked.value) "チェック済み!" else "チェックなし!")
            }
        }

    }
}

RadioButton

ラジオボタンのコンポーネント
スクリーンショット 2020-11-30 21.05.17.png

スクリーンショット 2020-11-30 21.05.20.png


@Composable
fun RadioButtonSample() {
    val windowState = remember { mutableStateOf(false) }
    val selected = remember { mutableStateOf(true) }
    Button(onClick = {
        windowState.value = true
    }) {
        Text("RadioButtonのサンプル")
    }
    if (windowState.value) {
        Window(title = "RadioButtonのサンプル", size = IntSize(600, 600), location = IntOffset(100, 100), centered = false,
                onDismissRequest = {
                    windowState.value = false
                }) {
            Column {

                RadioButton(selected = selected.value, onClick = {
                    selected.value = !selected.value
                })
                Text(if (selected.value) "選択済み!" else "選択なし!")
            }
        }

    }
}

Switch

スイッチのコンポーネント
スクリーンショット 2020-11-30 21.08.02.png

スクリーンショット 2020-11-30 21.08.05.png


@Composable
fun SwitchSample() {
    val windowState = remember { mutableStateOf(false) }
    val switchChecked = remember { mutableStateOf(false) }
    Button(onClick = {
        windowState.value = true
    }) {
        Text("Switchのサンプル")
    }
    if (windowState.value) {
        Window(title = "Switchのサンプル", size = IntSize(600, 600), location = IntOffset(100, 100), centered = false,
                onDismissRequest = {
                    windowState.value = false
                }) {
            Column {
                Switch(checked = switchChecked.value, onCheckedChange = {
                    switchChecked.value = it
                })
                Text(if (switchChecked.value) "チェック済み!" else "チェックなし!")
            }
        }

    }

}

Slider

スライダーのコンポーネント
slider.gif


@Composable
fun SliderSample() {
    val windowState = remember { mutableStateOf(false) }
    val sliderVal = remember { mutableStateOf(0.5f) }
    Button(onClick = {
        windowState.value = true
    }) {
        Text("Sliderのサンプル")
    }
    if (windowState.value) {
        Window(title = "Sliderのサンプル", size = IntSize(600, 600), location = IntOffset(100, 100), centered = false,
                onDismissRequest = {
                    windowState.value = false
                }) {
            Column {
                Slider(value = sliderVal.value, onValueChange = {
                    sliderVal.value = it
                }, modifier = Modifier.weight(1f))
                Text("Slider ${sliderVal.value}", modifier = Modifier.weight(1f))
            }
        }

    }
}

Progress

円形やバー型の進捗表示のためのコンポーネント
progress.gif


@Composable
fun ProgressSample() {
    val windowState = remember { mutableStateOf(false) }
    val progress = remember { mutableStateOf(0f) }

    Button(onClick = {
        windowState.value = true
    }) {
        Text("Progressのサンプル")
    }
    if (windowState.value) {
        Window(title = "Progressのサンプル", size = IntSize(600, 600), location = IntOffset(100, 100), centered = false,
                onDismissRequest = {
                    windowState.value = false
                }) {
            Column {
                Text("progress ${progress.value}")
                Slider(value = progress.value, onValueChange = {
                    progress.value = it
                })
                LinearProgressIndicator(progress = progress.value)
                CircularProgressIndicator(progress = progress.value)
            }
        }

    }
}

DropDownMenu

選択可能なリストのコンポーネント。
dropdownlist.gif


@Composable
fun DropdownDemo() {

    val windowState = remember { mutableStateOf(false) }

    val items = listOf("A", "B", "C", "D", "E", "F")
    val showMenu = remember { mutableStateOf(false) }
    val selectedIndex = remember { mutableStateOf(0) }
    Button(onClick = {
        windowState.value = true
    }) {
        Text("DropdownMenuのサンプル")
    }
    if (windowState.value) {
        Window(title = "DropdownMenuのサンプル", size = IntSize(600, 600), location = IntOffset(100, 100), centered = false,
                onDismissRequest = {
                    windowState.value = false
                }) {
            Column {
                DropdownMenu(
                        toggle = {
                            Text(items[selectedIndex.value], modifier = Modifier.fillMaxWidth().clickable(onClick = { showMenu.value = true }))
                        },
                        expanded = showMenu.value,
                        onDismissRequest = { showMenu.value = false },
                ) {
                    items.forEachIndexed { index, s ->
                        DropdownMenuItem(
                                onClick = {
                                    selectedIndex.value = index
                                    showMenu.value = false
                                }
                        ) {
                            Text(text = s)
                        }
                    }
                }
            }
        }

    }
}

SnackBar

通知のコンポーネント
snackbar.gif


@ExperimentalMaterialApi
@Composable
fun SnackBarSample(scaffoldState: ScaffoldState) {
    val snackBarVisibleState = remember { mutableStateOf(false) }
    val scope = rememberCoroutineScope()
    Button(onClick = { snackBarVisibleState.value = true }) {
        if (snackBarVisibleState.value) {
            Text("Snackbarが表示されてます")
        } else {
            Text("Snackbarを表示")
        }
    }
    if (snackBarVisibleState.value) {
        scope.launch {
            when (scaffoldState.snackbarHostState.showSnackbar("スナックバーやでー", "ボタンだよ")) {
                SnackbarResult.ActionPerformed -> snackBarVisibleState.value = false
                SnackbarResult.Dismissed -> snackBarVisibleState.value = false
            }
        }
    }
}

参考URL

Overview - Jetpack Compose Playground

13
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
7