rxkotlinfx-tornadofx-demo
rxkotlinfx-tornadofx-demo copied to clipboard
how to use paging and filter data
I try to make an project that get data from databse but my data rather big >10k rows so i want to paging it but don't know how to convert to rxkotlin and improve loading. I try to get data with runAsync for tableview hope you can show me how to do that Here is my code:
private val danhMucController: DanhMucDVKTController by inject()
private val eventController = EventController()
private var lstDanhMucModel = FXCollections.observableArrayList<DanhMucDVKTModel>()
private var filteredList: FilteredList<DanhMucDVKTModel> by singleAssign()
private var comboboxData = FXCollections.observableArrayList(10, 100, 500)
private val selectedData = SimpleIntegerProperty(10)
private val searchData = SimpleStringProperty()
private var btnXemDanhMuc: Button by singleAssign()
private var btnCapNhatDanhMuc: Button by singleAssign()
private var btnChonFile: Button by singleAssign()
private var table: TableView<DanhMucDVKTModel> by singleAssign()
private var paging: Pagination by singleAssign()
override val root = borderpane {
center {
tableview(lstDanhMucModel){
isEditable = true
column("STT", DanhMucDVKTModel::STT)
column("Mã DVKT", DanhMucDVKTModel::maDVKT).makeEditable()
column("Mã ánh xạ", DanhMucDVKTModel::maAX).makeEditable()
columnResizePolicy = SmartResize.POLICY
enableCellEditing()
regainFocusAfterEdit()
tableFilter.executeFilter()
table = this
onEditCommit {
//update data
danhMucController.update(it).subscribe()
}
//broadcast selections
selectionModel.selectedItems.onChangedObservable()
.map { it.filterNotNull().toSet() }
.subscribe(eventController.selectedDanhMucDVKT)
eventController.refreshDanhMucDVKT.startWith(Unit)
.flatMapSingle {
danhMucController.loadAll.toList()
}.subscribeBy(
onNext = {
lstDanhMucModel.clear()
table.items.clear()
lstDanhMucModel.addAll(it)
},
onError = {
alert(Alert.AlertType.ERROR, "Lỗi lấy dữ liệu", it.message ?: "").show()
}
)
filteredList = FilteredList(lstDanhMucModel)
table.items = filteredList
}
}
bottom {
hbox {
combobox(selectedData, comboboxData) {
hboxConstraints {
alignment = Pos.CENTER_LEFT
}
selectionModel.selectFirst()
}
paging = pagination {
hboxConstraints {
alignment = Pos.CENTER
}
pageCount = lstDanhMucModel.size / selectedData.value + 1
currentPageIndex = 0
currentPageIndexProperty().addListener { _, _, newValue ->
changeTableView(newValue.toInt(), selectedData.value)
}
}
}
}
top {
toolbar {
addClass(fontSize16px, fontFamily)
paddingAll = 5.0
//reload data from database
btnXemDanhMuc = button("", refreshGlyph) {
useMaxWidth = true
tooltip(toolTipReload)
actionEvents().map { Unit }.subscribe(eventController.refreshDanhMucDVKT)
}
//get data from excel
btnChonFile = button("", uploadGlyph) {
useMaxWidth = true
tooltip(toolTipUpload)
actionEvents().map {
danhMucController.loadFromExcel().map { danhMucDVKT ->
DanhMucDVKTModel().apply {
item = danhMucDVKT
}
}.observable()
}.subscribe {
if (it.size != 0) {
lstDanhMucModel.clear()
table.items.clear()
lstDanhMucModel.addAll(it)
table.selectionModel.clearSelection()
table.requestFocus()
}
}
}
//save data into database
btnCapNhatDanhMuc = button("", saveGlyph) {
useMaxWidth = true
tooltip(toolTipSaveAs)
actionEvents().map { Unit }.subscribe(eventController.saveDanhMucDVKT)
}
//remove an row
button("", removeGlyph) {
useMaxWidth = true
tooltip(toolTipDelete)
val keyEvents = table.events(KeyEvent.KEY_PRESSED).filter { it.code == KeyCode.DELETE }
val buttonEvents = actionEvents()
Observable.merge(keyEvents, buttonEvents).flatMapSingle {
table.selectionModel.selectedItems.toObservable()
.map { it.STT.value.toInt() }
.toSet()
}.subscribe(eventController.deleteDanhMucDVKT)
}
textfield(searchData)
}
}
lstDanhMucModel.onChange {
changeTableView(paging.currentPageIndex, selectedData.value)
}
selectedData.onChange {
changeTableView(paging.currentPageIndex, it)
}
searchData.onChange { searchValue ->
filteredList.setPredicate { data ->
data.tenDVKT.value.toLowerCase().contains(searchValue!!)
}
changeTableView(paging.currentPageIndex, selectedData.value)
}
searchData.onChange {
JavaFxObservable.changesOf(searchData).map {
lstDanhMucModel.filter { data ->
data.tenDVKT.value.toLowerCase().contains(it.newVal)
}
}.subscribe {
filteredList = FilteredList(it.observable())
}
}
//handler save data into database
val saveData = eventController.saveDanhMucDVKT
.map { lstDanhMucModel }
.flatMapSingle { lstDMDVKT ->
Alert(Alert.AlertType.CONFIRMATION, "Lựa chọn hình thức lưu dữ liệu",
ButtonType("Thêm", ButtonBar.ButtonData.YES),
ButtonType("Lưu và xóa", ButtonBar.ButtonData.NO),
ButtonType("Bỏ qua", ButtonBar.ButtonData.CANCEL_CLOSE))
.toMaybe().toObservable()
.flatMap {
when {
it.buttonData == ButtonBar.ButtonData.YES -> danhMucController.createList(lstDMDVKT).toObservable()
it.buttonData == ButtonBar.ButtonData.NO -> {
danhMucController.delete().subscribe()
danhMucController.createList(lstDMDVKT).toObservable()
}
else -> Observable.empty()
}
}.toSet()
}.publish() //publish() to prevent multiple subscriptions triggering alert multiple times
saveData.subscribe(eventController.savedDanhMucDVKT)
//add data into database
eventController.savedDanhMucDVKT
.map { Unit }
.subscribe(eventController.refreshDanhMucDVKT)
saveData.connect()
}
//pagingation when change view private fun changeTableView(index: Int, limit: Int) { val fromIndex = index * limit val toIndex = min(fromIndex + limit, lstDanhMucModel.size)
val minIndex = min(toIndex, filteredList.size)
val sortedData = SortedList<DanhMucDVKTModel>(
FXCollections.observableArrayList(filteredList.subList(min(fromIndex, minIndex), minIndex)))
sortedData.comparatorProperty().bind(table.comparatorProperty())
table.items = sortedData
paging.pageCount = filteredList.size / selectedData.value + 1
}
init {
//action to delete rows from database
eventController.deleteDanhMucDVKT.flatMapSingle {
table.currentSelections.toList().flatMap { deleteItems ->
when {
deleteItems.size == 0 -> {
Alert(Alert.AlertType.ERROR, "Bạn chưa chọn DVKT cần xóa", ButtonType.OK)
.toMaybe().map { 0 }.toObservable().toSet()
}
else -> {
Alert(Alert.AlertType.WARNING, "Bạn có chắc là muốn xóa ${deleteItems.size} DVKT không?",
ButtonType("Có", ButtonBar.ButtonData.YES),
ButtonType("Không", ButtonBar.ButtonData.NO)).toMaybe()
.filter { it.buttonData == ButtonBar.ButtonData.YES }
.flatMapObservable { deleteItems.toObservable() }
.flatMapSingle {
danhMucController.deleteWhere(it.STT.value.toInt())
}.map { deleteItems.first().STT.value.toInt() }
.toSet()
}
}
}
}.subscribe { deletedIds ->
if (deletedIds.hashCode().absoluteValue != 0) {
//thực hiện việc xóa dòng dữ liệu trong tableview
lstDanhMucModel.deleteWhere { it.STT.value.toInt() in deletedIds }
Alert(Alert.AlertType.INFORMATION, "Xóa dịch vụ kĩ thuật thành công", ButtonType.OK).show()
}
}
}