Search code examples
kotlindesktop-applicationandroid-jetpack-composedesktopcompose-desktop

Problem with Kotlin compose for desktop Window


I'm trying to make a chess engine desktop app with an ui component to it.

The game() method that I mention is a simple while loop that allows me to ask for moves in algebraic notation and make the moves if they are valid ones.

I have the following main and my problem is that if I uncomment and run the game() method inside the classe it wont start the App window, and if I instead try to uncomment the same method but from outside the Window it still wont start the desktop App. On the other hand if i run it has it is, it will start the UI window.

fun main() = application {
    resetBoard()
    printBoardSmall()
    Window(onCloseRequest = ::exitApplication, icon = painterResource("black_knight.png"), title = "Chess") {
        ui()
        //game()
    }
    //game()
}
@Composable
fun ui() {
    var squarePair = false
    Row {
        Column {
            for (n in 8 downTo 1) {
                Row {
                    Text(
                        "" + n,
                        textAlign = TextAlign.Center,
                        modifier = Modifier.width(SIZE_TILE),
                        fontSize = FONT_SIZE_BOARD,
                        fontWeight = FontWeight.Bold
                    )
                    squarePair = boardLines(n, squarePair)
                }
            }
            Row {
                Text(" ", textAlign = TextAlign.Center, modifier = Modifier.width(SIZE_TILE))
                for (n in 0..7) {
                    Text(
                        "" + ('A' + n),
                        textAlign = TextAlign.Center,
                        modifier = Modifier.width(SIZE_TILE),
                        fontSize = FONT_SIZE_BOARD,
                        fontWeight = FontWeight.Bold
                    )
                }
            }
        }
        Column {
            Text("   Play", textAlign = TextAlign.Center, fontSize = 30.sp)
            var move = ""
            //var move by remember { mutableStateOf("") }
            TextField(
                value = move,
                onValueChange = { move = it },
                label = { Text("Move") },
                maxLines = 1,
                textStyle = TextStyle(color = Color.Black, fontWeight = FontWeight.Bold),
                modifier = Modifier.padding(20.dp)
            )
            print(move)
        }
    }
}

@Composable
fun board(n: Int, i: Int){
    var team = ""
    if(utils.isWhite(BOARD[n-1][i-1])) team = TEAM[0]
    if(utils.isBlack(BOARD[n-1][i-1])) team = TEAM[1]

    for(k in LOWER_CASE_LETTERS.indices) {
        if (BOARD[n-1][i-1] == LOWER_CASE_LETTERS[k] || BOARD[n-1][i-1] == UPPER_CASE_LETTERS[k]) {
            Image(painter = painterResource(team + "_" + PIECES[k] + ".png"), contentDescription = PIECES[k])
        }
    }
}

Im new to compose and I can't figure out whats the problem, expecially since im trying to run the method outside the Window


Solution

  • I'm no expert, but I'll try my best to help.

    • It doesn't work, when you call it in the Window, 'cause that's what it uses to init it's layout. So the Window won't show, 'till the game() stops.
    • I don't know, why it doesn't work, when you put it after the Window. Looking at fun main() = application { ... } I suspect, that initiating the application is similar to initiating the Window, so it also won't start, untill the game() is over.

    You should try putting game() in a seperate thread. Something like this should work:

    fun() main = application {
        resetBoard()
        printBoardSmall()
    
        Window( ... ){
            ui()
        }
    
        Thread {
           game()
        }.start()
    }
    

    P.S. I'm also very new to compose. And kinda new to programming. And really, really sorry for all the gross oversimplifications I made.

    P.P.S. You could add a TextField to your app and use Button's onClick parameter to call a move checking function. Wouldn't need to play with Threads and coroutines then. And you could also use Buttons for the board squares, cause you can assign them a background and an image. If you would need help with any of that - HMU.