LoginSignup
6

More than 1 year has passed since last update.

posted at

updated at

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

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

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
What you can do with signing up
6