DEV Community

loading...
Cover image for From Swing to Compose Desktop #4

From Swing to Compose Desktop #4

tkuenneth profile image Thomas Kuenneth Updated on ・2 min read

Welcome to the 4. post about my journey of transforming a Java Swing app to Compose for Desktop. Today I will focus on multiple selections in a list. When TKDupeFinder detects, say 10, files with the same MD5 hash their content is very likely the same. Consequently 9 of them are candidates for deletion. The app will provide two buttons, Show and Delete which will, well, show or delete files that have been selected in a list. Let's see how we can

  • create a scrollable list
  • and allow multiple selections

To wet your appetite, here is how things will look:

And here comes the code that does the magic.

@Composable
fun ThirdRow(currentPos: Int, checksums: List<String>,
             selected: SnapshotStateMap<Int, Boolean>) {
    val items = if (checksums.isNotEmpty())
        df.getFiles(checksums[currentPos]) else emptyList()
    LazyColumnForIndexed(items,
            modifier = Modifier.fillMaxSize().padding(8.dp),
            itemContent = { index, item ->
                val current = selected[index] ?: false
                ListItem(secondaryText = { Text(item.parent) },
                        modifier = Modifier.toggleable(onValueChange = {
                            selected[index] = !current
                        },
                                value = current)
                                .background(if (current)
                                    Color.LightGray else Color.Transparent),
                        text = { Text(item.name) })
            })
}
Enter fullscreen mode Exit fullscreen mode

LazyColumnForIndexed() provides the list. The contents to be displayed are already there. currentPos identifies the checksum whose files should be presented. So, with df.getFiles(checksums[currentPos]) I get a list of files, which are passed to LazyColumnForIndexed().

When a new list element needs to be created, itemContent is invoked. It gets an index and the item. I use the index to track if an element is currently selected. This map is passed to my composable (SnapshotStateMap<Int, Boolean>) because it needs to be altered somewhere else, too. Such changes must trigger recompositions, that is why I use a state.

ListItems can be configured to have several lines of text and an icon. Most importantly, you can use its modifier to make it toggleable. If that happens, onValueChange is invoked. As you can see, I just need to flip a Boolean. Depending on the current value, my item has either a transparent or light gray background.

As you can see, with just a handful lines of code you get a nice looking scrollable list with multiple selection. Did you need to implement multiple selection lists in Compose? How did you implement that? Please share your solution in the comments, I would love to hear them.


From Swing to Jetpack Compose Desktop #1
From Swing to Jetpack Compose Desktop #2
From Swing to Compose Desktop #3

Discussion

pic
Editor guide