I have a TableView that the user can sort by any of its columns. Depending on other events in the app, I want to add data to the TableView. However, when I add the data, the new row always appears on the bottom of the TableView, even though it should appear somewhere else according to the sort order.
My question is, therefore, how I can add data to the TableView such that the TableView is still sorted correctly according to the column that was selected by the user.
Here's the relevant code controlling the TableView:
@FXML
private lateinit var tableColumnMeasurementLogBib: TableColumn<LogEntry, Int>
@FXML
private lateinit var tableColumnMeasurementLogResult: TableColumn<LogEntry, Double>
@FXML
private lateinit var tableColumnMeasurementLogTimestamp: TableColumn<LogEntry, LocalDateTime>
@FXML
private lateinit var tableViewMeasurementLog: TableView<LogEntry>
private val logEntries = FXCollections.observableArrayList<LogEntry>()
private fun setupMeasurementLog() {
tableViewMeasurementLog.items = logEntries
tableColumnMeasurementLogTimestamp.cellValueFactory = PropertyValueFactory(LogEntry::timestamp.name)
tableColumnMeasurementLogResult.cellValueFactory = PropertyValueFactory(LogEntry::result.name)
tableColumnMeasurementLogBib.cellValueFactory = PropertyValueFactory(LogEntry::athleteId.name)
tableColumnMeasurementLogTimestamp.setCellFactory {
object : TableCell<LogEntry, LocalDateTime>() {
override fun updateItem(item: LocalDateTime?, empty: Boolean) {
super.updateItem(item, empty)
if (empty || item == null) {
text = ""
return
}
text = measurementLogDateTimeFormatter.format(item)
}
}
}
}
private fun addDataToLog(athleteId: Int, result: Double, timestamp: LocalDateTime) {
logEntries.add(LogEntry(athleteId, result, timestamp))
}
data class LogEntry(val athleteId: Int, val result: Double, val timestamp: LocalDateTime)
Steps to reproduce:
- Call
addDataToLogwith some values. - In the UI, click on any of the column headers to sort the table by that column.
- Call
addDataToLogagain. - The new data row will always appear at the bottom, no matter where it should actually appear (according to the sorted column).
Turns out reading the JavaDocs would have been of great help here. Simply wrapping the list in a
SortedListlike so does the job: