宣言的(Declarative)UI

永井 忠一 2025.10.24


フレームワーク

Jetpack Composeを利用。プラグインをインストール。Kotlin Multiplatformの「Desktop」プロジェクトを作成

プログラミング

ウィザードが生成したコードを、編集。以下、App.ktファイル

Kotlin
package org.example.demo

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.RadioButton
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import org.jetbrains.compose.ui.tooling.preview.Preview

@Composable
@Preview
fun App() {
    MaterialTheme {
        var left by remember { mutableStateOf(0L) }
        var right by remember { mutableStateOf(0L) }
        var operator by remember { mutableStateOf("+") }
        var answer: Long? by remember { mutableStateOf(null) }
        var reminder: Long? by remember { mutableStateOf(null) }
        Column(
            modifier = Modifier
                .background(MaterialTheme.colorScheme.primaryContainer)
                .safeContentPadding()
                .fillMaxSize(),
            horizontalAlignment = Alignment.CenterHorizontally,
        ) {
            Row {
                TextField(
                    value = left.toString(),
                    onValueChange = { text ->
                        when {
                            text.isEmpty() -> left = 0L
                            else -> text.toLongOrNull()?.let { left = it }
                        }
                    },
                    textStyle = TextStyle(textAlign = TextAlign.End),
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
                )
                Column {
                    Row {
                        RadioButton(
                            selected = (operator == "+"),
                            onClick = { operator = "+" }
                        )
                        Text("+")
                    }
                    Row {
                        RadioButton(
                            selected = (operator == "-"),
                            onClick = { operator = "-" }
                        )
                        Text("-")
                    }
                    Row {
                        RadioButton(
                            selected = (operator == "*"),
                            onClick = { operator = "*" }
                        )
                        Text("*")
                    }
                    Row {
                        RadioButton(
                            selected = (operator == "/"),
                            onClick = { operator = "/" }
                        )
                        Text("/")
                    }
                }
                TextField(
                    value = right.toString(),
                    onValueChange = { text ->
                        when {
                            text.isEmpty() -> right = 0L
                            else -> text.toLongOrNull()?.let { right = it }
                        }
                    },
                    textStyle = TextStyle(textAlign = TextAlign.End),
                    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
                )
            }
            Row {
                Button(onClick = {
                    when (operator) {
                        "+" -> {
                            answer = left + right
                            reminder = null
                        }
                        "-" -> {
                            answer = left - right
                            reminder = null
                        }
                        "*" -> {
                            answer = left*right
                            reminder = null
                        }
                        "/" -> {
                            if (right == 0L) {
                                answer = null
                                reminder = null
                            } else {
                                answer = left/right
                                reminder = left%right
                            }
                        }
                        else -> assert(false)
                    }
                }) {
                    Text("=")
                }
                Column {
                    if (answer != null) {
                        TextField(
                            value = answer.toString(),
                            onValueChange = { },
                            readOnly = true,
                            textStyle = TextStyle(textAlign = TextAlign.End)
                        )
                    }
                    if (reminder != null) {
                        TextField(
                            value = reminder.toString(),
                            onValueChange = { },
                            readOnly = true,
                            textStyle = TextStyle(textAlign = TextAlign.End)
                        )
                    }
                }
                if (answer != null) {
                    Button(onClick = {
                        left = 0L
                        right = 0L
                        answer = null
                        reminder = null
                    }) {
                        Text("clear")
                    }
                }
            }
        }
    }
}

実行の、例

(Gradleタスク「packageReleaseUberJarForCurrentOS」を実行すると、「composeApp/build/compose/jars/」に、実行可能な .jar が生成される)


© 2025 Tadakazu Nagai