Issue
i am using kotlin to create some small application with it, and tornadofx, however i am unfamiliar with how some of the javafx things translate to kotlin.
I am trying to itterate through a list of buttons, and add button to page, but i managed only to add one button per page, and i want to have X items per page, and i want page count to be dynamic
override val root = tabpane{
setPrefSize(800.0,600.0)
tabs.removeAll()
tabClosingPolicy = TabPane.TabClosingPolicy.ALL_TABS
val buttonList = arrayOf(
Button("Btn1"),
Button("Btn2"),
Button("Btn3"),
Button("Btn4")
)
tab("My Tab 1") {
hbox {
button("Click Me!") {
setOnAction {
replaceWith<TestView>()
}
}
button("Add Tab 2") {
setOnAction {
tab("tab2 ")
{
select()
button("Close") { setOnAction { close() } }
pagination(buttonList.size) { setPageFactory { pageIndex -> (buttonList[pageIndex]) } }
style {
arrowsVisible = false
pageInformationVisible = false
}
}
}
}
}
}
}
i tryed to implement a for loop that would add certain amount of items per page (lets say 2 buttons per page) and then proceed to create page. but i had no luck. If anyone could help me find a proper solution for kotlin based pagination i would be thankful
pagination(buttonList.size)
with this line i can controll amount of pages, so that is at least something, but i dont see how to control amount items per page.
pageIndex -> (buttonList[pageIndex])
i realize issue is here, but i had no luck implementing proper logic.
lets say i want 4 items per page, i could get amount of pages required by dividing my list with number 4 (items per page). but not sure how to add more then 1 item per page.
Solution
class SomeView : View() {
private val buttonList = arrayOf(
Button("Btn1"),
Button("Btn2"),
Button("Btn3"),
Button("Btn4"),
Button("Btn5")
)
private var pageSize = 3 //Decide this however you want
override val root = tabpane {
setPrefSize(800.0, 600.0)
tabs.removeAll()
tabClosingPolicy = TabPane.TabClosingPolicy.ALL_TABS
tab("My Tab 1") {
hbox {
button("Click Me!") {
setOnAction {
replaceWith<TestView>()
}
}
button("Add Tab 2") {
setOnAction {
tab("tab2 ")
{
select()
button("Close") { setOnAction { close() } }
//The ceiling calc is for rounding up for the size
pagination(ceil(buttonList.size.toDouble() / pageSize).toInt())
{ setPageFactory { pageIndex -> createPage(pageIndex * pageSize, pageSize) } }
style {
arrowsVisible = false
pageInformationVisible = false
}
}
}
}
}
}
}
private fun createPage(startingIndex: Int, pageSize: Int = 1) : Pane {
val pagePane = VBox() //Create and design whatever pane you want
val endingIndex = minOf(startingIndex + pageSize, buttonList.size) //Don't go out of bounds
for(i in startingIndex until endingIndex) { //Assuming starting index is in bounds
pagePane.add(buttonList[i])
}
return pagePane
}
}
Here is a solution for dynamic pages for pagination. Your main problem was that tab panes only hold one child pane/component. The answer is to nest your buttons in a pane. I haven't tested this hard for edge cases or anything, so this is more proof-of-concept. You'll have to account for those if they come up.
Side Notes: As explained above, this is also why your "Close" button isn't appearing. Also, when I was testing your code I noticed the style wasn't implemented unless I clicked a button in the pane. Maybe it would work if you used a stylesheet, created a cssclass, and added that class to your tabpane (Don't forget to import your stylesheet if you choose to do this).
Answered By - JCamacho