TableState

@Stable
class TableState @RememberInComposition constructor(initialSelectedRowIndices: Set<Int> = emptySet())

A hoistable state holder for what a Table has selected, carrying the gesture that brings one of its rows into view.

Each row is named by its index into the table's rows - the model's own row space, never the position the row is drawn at - so a sort order and a row filter move where a row is shown and leave the index that names it alone.

selectedRowIndices is two-way: assigning it selects those rows, and the user selecting other ones - by click, drag or keyboard - writes them back here. It is snapshot-observable, so reading it inside a composable (or a snapshotFlow collector) subscribes to the user's later selecting as well.

The rows this state names are the composition's own and are re-applied on every pass, so a table driven by a state never stands on a selection the state does not hold, and a row the table's rows do not reach is left out of the selection while it goes on being named here - rows that reach it again show it selected.

revealRow brings one row into view when the application decides to - a row just added, a search hit:

val state = rememberTableState()

Button("Add", onClick = { people = people + Person() })
LaunchedEffect(people) { state.revealRow(people.lastIndex) }
ScrollPane {
Table(rows = people, state = state, modifier = SwingModifier.viewport()) {
column("Name") { it.name }
}
}

rowCount and shownSelectedRowIndices answer for the table instead of for what this state holds. Each reads the bound table where it is called, so what it reports is what the table stands on - which is not always what was declared, since a selection mode narrower than the declaration keeps only part of it and a row filter takes the rows it hides out of the selection. They are not snapshot state, so reading one subscribes to nothing; a composable that has to follow the user reads selectedRowIndices. An unbound state has no table to answer for and reports no rows and nothing selected.

A state drives at most one table: passing it to a second one moves it there and leaves the first unbound.

The order and the widths of the columns are not this state's: Table declares them through its own columnLayout.

Parameters

initialSelectedRowIndices

the rows selected until the caller or the user moves the selection.

See also

Constructors

Link copied to clipboard
@RememberInComposition
constructor(initialSelectedRowIndices: Set<Int> = emptySet())

Properties

Link copied to clipboard

How many rows the table shows: the rows of its model, less the ones a row filter hides. 0 while no table is bound.

Link copied to clipboard

The selected rows as indices into the table's rows, expressed as the general multi-select shape so one state covers every one of org.jetbrains.compose.swing.constants.SelectionMode's modes.

Link copied to clipboard

The rows the table has selected, as indices into its rows. Empty while no table is bound.

Functions

Link copied to clipboard
fun revealRow(rowIndex: Int): Boolean

Brings the row rowIndex names into view, and returns whether it was reached.