Search code examples
tornadofx

Tornadofx: Trying to reload/refresh MainView


I've only really just started on Tornadofx and was having a bit of trouble trying to figure out how to reload a view so the controls in that view are refreshed.

Below is a simplified version of the code I'm working with. I've got a loop to generate radio-button controls based on strings in a list.

class MainView: View("MainView") {
    override val root = vbox {
        for(x in radioText) {
            radiobutton(x, radioGroup) {
                action {
                    radioSelected = this@radiobutton.text
                }
            }
        }

        button("Next") {
            action {
                // Reload View to update radiobuttons with new values
            }
        }
    }
}

In the program I need to go through several sets of these radio buttons, and so the idea was that each time the user presses the "Next" button, the items in the radioText list would be updated to match the next set of radio-buttons. Then I was looking for a way to get the view to update with these new values.

I tried using openWindow() to open a new instance of the view, but then when I used close() to get rid of the previous instance and ended up closing both windows.

button("Next") {
    action {
        MainView().openWindow()
        close()
    }
}

Any help with this would be much appreciated,

Thanks.


Solution

  • If I understood correctly, you are trying to have a list of string and generate radiobuttons with it. So, by adding the variables to your example, would be something like this:

    class MainView: View("MainView") {
        val radioText = ArrayList<String>()
        var radioGroup : ToggleGroup by singleAssign()
        lateinit var radioSelected : String
        override val root = vbox {
            radioText.addAll(arrayListOf("One","Two","Three","Four"))
    
            radioGroup = togglegroup(){}
            for(x in radioText) {
                radiobutton(x,radioGroup) {
                    action {
                        radioSelected = text //You don't need this@radiobutton.text
                    }
                }
            }
    
            button("Next") {
                action {
                    // Reload View to update radiobuttons with new values
                }
            }
        }
    }
    

    I thing is a better idea having your radiobutton created by a listview, wich would be updated by a observable list of string, like I do bellow:

    class MainView2: View("MainView") {
    //    this is a list of observable string, so when the items on his list change
    //    the listview is updated
        val radioText = FXCollections.observableArrayList<String>()
    
        var radioGroup : ToggleGroup by singleAssign()
        lateinit var radioSelected : String
    
        override val root = vbox() {
            prefWidth = 200.0
            prefHeight = 300.0
    
            radioText.setAll("One","Two","Three","Four")
    
            radioGroup = togglegroup(){}
            listview<String>(radioText){
    //      Setting listview height dinamically
                fixedCellSize = 25.0
                prefHeightProperty().bind(radioText.sizeProperty.multiply(fixedCellSizeProperty().add(2)))
    
    //       Generating the radiobutton acording to strings on radioText
                cellFormat {
                    graphic = cache(it){
                        radiobutton(it,radioGroup){
                            action {
                                radioSelected = text
                            }
                        }
                    }
                }
            }
    
            button("Next") {
                action {
                    radioText.clear()
                    radioText.setAll("Five","Six","Seven","Eight","Nine","Ten")
                }
            }
        }
    }
    

    Please let me know if there is something you don't understand on my aproach.