Accessing nodes with less code
croissant676 opened this issue · comments
This issue isn't an actual issue, it's just a question I have about tornadofx
.
When coding something like
hbox {
vbox {
textfield("Things")
}
button ("Print value") {
action {
println("Something") // Wants to print textfield text
}
}
}
Is there an easy way to access the textfield? (Or nodes in general?)
Typically, I do something like this:
hbox {
var textfield: TextField by Delegates.notNull()
vbox {
textfield = textfield("Some more things")
}
button ("Print value") {
action {
println(textfield.text)
}
}
}
This feels more complex than it needs to be.
Is there a solution like this
hbox {
vbox {
textfield("Even more things") {
link = 0
}
}
button ("Print value") {
action {
println((nodes[0] as TextField).text)
println(nodes<TextField>(0).text) // Or this
}
}
}
inside of tornadofx
already?
And is there already an easier way to access nodes that I don't know about? (Which is very likely, since I'm not that experienced with kotlin
or tornadofx
)
This is for all nodes in general.
Thanks in advance!
You can if you absolutely need to assign the ui elements to a var like you do above, but almost every time I see someone do this, what they really want access to is the data. If you just use data binding you have no need to access the UI element directly, you'd just listen to changes to your model or access the model property directly. You can also fire events to get around the tight coupling to ui elements, which is an anti pattern you should avoid. Perhaps if you can show what you're trying to do, we can show you the correct solution.
My code looks something like this:
var daysSpinner: Spinner<Int> by Delegates.notNull()
// UI Section
borderpane {
center {
vbox {
hbox {
// Other UI Elements
daysSpinner = spinner(1, 100, 5, 1, false)
}
// Other UI Elements
}
}
bottom {
hbox {
// Other UI Elements
button("Next > ") {
action {
days = daysSpinner.value
nextView()
}
}
paddingBottom = 30.0
alignment = Pos.CENTER
spacing = 30.0
}
}
}
This is exactly the situation I was talking about :) Here is a version of your code which binds the spinner to a Property and accesses the property value in the action, without having a tight coupling to the UI element:
val dayProperty = SimpleIntegerProperty(42)
override val root = borderpane {
center {
vbox {
hbox {
spinner(1, 100, 5, 1, false, dayProperty)
}
}
}
bottom {
hbox {
button("Next > ") {
action {
println("You have access to ${dayProperty.value} here")
}
}
}
}
}
It worked for me :) Thanks!