Hey everyone, is there some documentation or site ...
# tornadofx
a
Hey everyone, is there some documentation or site where i could lookup how to create something like derived / calculated properties for example a cost value which consist of a multiplication of 3 other properties? Another thing im struggling to find is how i can group together multiple properties and listen when one it changes. I found something like this
Copy code
private val costRecalculationTriggerProperty = SimpleObjectProperty<ObservableList<Property<*>>>(
      FXCollections.observableArrayList { p -> arrayOf<Observable>(p) })
private var costRecalculationTrigger: ObservableList<Property<*>> by costRecalculationTriggerProperty
Is there something else i could use which is kind of more readable?
a
You are looking for Expressions.
Can't find a reference right now
a
Maybe you could post some example code?
a
Here you are: https://github.com/mipt-npm/dataforge-vis/blob/8094f02f067ef3e2ca465ae03d884ea685acdfb7/dataforge-vis-common/src/jvmMain/kotlin/hep/dataforge/vis/fx/editor/FXMeta.kt#L68-L70 use
objectBinding
or any other binding. The arguments and the receiver are dependencies. Inside the block you place the calculation rule. It you have only one dependency, you can use the value inside the lambda. If you have multiple dependencies, then you have to call values of appropriate dependencies, remembering that invalidation is done automatically.
a
Thanks for your help! I finally got it 🙂
g
I found that doing property-math directly created virtually unreadable code, but using the xxxBinding made it all clear and coherent again.
a
Yep. expressions are good only for simple operations like divide by 2.
g
Yes, it gives me a nice naming point on the Model class and it lets me freely intermix non-properties from the domain class.
c
Sorry to revive this thread, but I'm trying to do the same thing, and not having any success, even with the above explanation. I have 4 SimpleIntegerProperties than I want to listen to for changes, such that a 5th SimpleIntegerProperty updates automatically to be the sum of those four. How exactly would I achieve this with say an
integerBinding
? or should I be using something else? My attempts so far have no been at all successful 😞
a
The simplest way is integer binding with 4 arguments in vararg block
c
So I've tried that, and haven seemed to succeed. So for example, I have this:
Copy code
val scoreProperty = integerBinding(baseProperty, bonusProperty, tempProperty, otherProperty) {
    baseProperty.get() +  bonusProperty.get() + tempProperty.get() + otherProperty.get()
  }
Which doesn't seem to work. Am I using that correctly?
a
Should work. I am not near the computer now. Does it generate a error?
c
No, it just doesn't update the field at all.
a
Place a debug marker inside the lambda and check if it is triggered. But it looks strange. How do you change properties values?
c
So the setup it that I have the input field for each of those 4 properties bound to an ItemViewModel with those fields. User changes those fields by inputting different values. I think my issue might be that I need to integer bind the itemviewmodel, rather than the underlying fields. Right now that the code snippet above refers to the underlying fields
Yeah, line is never hit in debug
a
Just add listener to a changing field. I think it won't be triggered as well.
c
Yeah, so the underlying fields listeners aren't triggered until the itemviewmodel is committed. Ok that makes sense to me. But then the question is how do you use integerBinding with an ItemViewModel? I can get a normal binding to work (ie. property.bind(...)) but how do I pass it an integerBinding?
Alright, so this was a bit confusing to me, but it seems to be working now. In the ItemViewModel you create your field as an integerbindinf of the 4 items. Then, you directly bind that integer binding to the textfield for input. I suppose if its calculated, there really is no need for the underlying field to exist outside of the itemviewmodel