groostav
12/24/2016, 10:43 PM<!-- whateverView.fxml -->
<GridPane fx:id="mainView" fx:controller="com.whatever.WhateverController">
<Button fx:id="helloButton" onAction="#onHelloClicked" text="${controller.helloButtonText}/>
</GridPane>
would generate the code:
interface WhateverView {
val mainView: GridPane
val helloButton: Button
}
which you could then implement to "use"
class WhateverController(viewImpl: WhateverView): WhateverView by viewImpl {
val helloButtonText = "hello bindings!"
fun doDomainThing(domainObject: DomainModel){
helloButton.state = compute(domainObject);
}
fun onHelloClicked(event: ActionEvent){
//regular FXML handler handling
}
}
and which would require some kind of factory likely involving dynamic proxies to leverage:
val controller = uiFrameworkFacotry.create<WhateverController>()
this has the design wins that:
- you dont need to use the field name matches FXID scheme, which, of course, are bound and runtime meaning that spelling mistakes can only be found relatively late
- you dont need to mention the type yourself, which probably makes your code a little more refactor safe. Consider mainView is changed to a VBox instead of GridPane, theres a good chance that if you made that change in the view code, you wouldnt need any changes in the kotlin controller class.
- This also makes explicit the fxml resolution strategy. I don't know how other FXML users do it but I almost immediately implemented some reflection to find the view by a naming convention. Here that problem is taken away from us.