wood burning stoves 2.0*
The moose likes Groovy and the fly likes problem with groovy swt: stuck with bind node processing and ComputedValues Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Languages » Groovy
Bookmark "problem with groovy swt: stuck with bind node processing and ComputedValues" Watch "problem with groovy swt: stuck with bind node processing and ComputedValues" New topic
Author

problem with groovy swt: stuck with bind node processing and ComputedValues

william Woodman
Greenhorn

Joined: Apr 23, 2012
Posts: 12
been trying to look/use improve the groovy-swt/jface builder in groovy and hit some problems i need help to fix .

grooy-swt uses the eclipse data binding framework under the covers - most of the heavy lifting is in the BindFactory.class

whilst trying to use this i've been documenting as a i go and found a bug and i need to fix it and cant figure my way out.

so the problem i'm trying to look at is something in a builder that might look this



basically out of the box this doesnt work - so i have had ago at trying to understand how its working (got a temp fix) but it fails again if i use calc form like

so whats the problem here. in the original code tree the code looks a bit like this



now this fails on a number of fronts - the code return tries to caste a map as ComputedValue - but this doesnt work as the realm doesnt get set when you do it like this. Also despite the fact that the code generates a array of modelObservables[] by iterating through the closure for model references - it then ignoires all that and tries to return the evaluated closure as the ComputedValue.calculation () method.

I fixed the first by using simply returning the first item in the array - this works but only if the closure is a simple {model.prop} form by retuning the first entry


This doesn't work if you try and use a form like {10+ mySlider1.selection}. Why? because that closureBindingTrigger stuff only returns the model.property and ignores the rest. - so the text tracks the slide value starting at 0 not starting at 10 as closure intended

so i tried to go back to the original form and fix the caste issues using the the latest groovy support for inner classes like this to correctly generate a ComputedValue



this kind of works if your closure doesnt contain anything complex so if the closure looks like {'some text'}, this is calculated and your text widget shows the correct string

if you try and do a GString closure like {"some text $someVar"} - the binding fails like this

Status WARNING: org.eclipse.core.databinding code=0 Could not change value of bindingDemo.Model2@564546.targetName java.lang.IllegalArgumentException: argument type mismatch
java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.core.internal.databinding.beans.BeanPropertyHelper.writeProperty(BeanPropertyHelper.java:59)
at org.eclipse.core.internal.databinding.beans.BeanValueProperty.doSetValue(BeanValueProperty.java:51)
at org.eclipse.core.databinding.property.value.ValueProperty.setValue(ValueProperty.java:83)
at org.eclipse.core.internal.databinding.property.value.SimplePropertyObservableValue.doSetValue(SimplePropertyObservableValue.java:104)
at org.eclipse.core.databinding.observable.value.AbstractObservableValue.setValue(AbstractObservableValue.java:55)
at org.eclipse.core.databinding.observable.value.DecoratingObservableValue.setValue(DecoratingObservableValue.java:103)
at org.eclipse.core.internal.databinding.observable.masterdetail.DetailObservableValue.doSetValue(DetailObservableValue.java:134)
at org.eclipse.core.databinding.observable.value.AbstractObservableValue.setValue(AbstractObservableValue.java:55)
at org.eclipse.core.databinding.observable.value.DecoratingObservableValue.setValue(DecoratingObservableValue.java:103)
at org.eclipse.core.databinding.UpdateValueStrategy.doSet(UpdateValueStrategy.java:486)
at org.eclipse.core.databinding.ValueBinding$4.run(ValueBinding.java:197)


so my question is you want generate a ComputedValue object that correctly evaluates a closure with a GString part in it how do you do that ??

back to the original code base again - if i have many model.prop references in the closure {10 + model1.prop1 + model2.prop2} then the loop

builds an array of modelObservables[] with two entries - but i cant generate a dynamically evaluated result that is the entire closure - including any non model+prop parts.

I am beginning to get out of my depth in framework code here for which theres little/zero documentation for

any one who can help i'd really appreciate it and i can then feed this fix and couple others back to the groovy swt leads to get mended

thanks in advance
william Woodman
Greenhorn

Joined: Apr 23, 2012
Posts: 12
updates - so some more playing and siddled closer to understanding

so part one -

in the original code tree



finally figured out what this is - the binding referred to here is the closure bindings when you set up a closure

e.g. if you have {some stuff $var} as closure then the bindings would be 1, and the value essentially the value of the part to substitute when doing a toString on your closure.

so what the code was doing was looking for a binding for the $var in your closure. It then was expecting this to be of form {model.param} and read the model name and the param name from the binding and builds an IObservable from that

this isn't so clever if you express a complex closure like {"hello $var " + model.param} as there are two closure bindings now

so i still only have a partial fix. If the closure is {model.param} i can just create an observable from this with BeanPropterties.value( .... and all works well

if its a complex compound closure such as {"hello $world " + model.param} the best i can do is create a ComputedValue object where the calculate method returns the value of the whole closure such as



however whilst this is ok on first invocation it doesnt seem to observe the changes on the calc value and keeps giving you the cached value. so code in a builder like this



only binds once and as you drag the slider the ComputeValue object doesnt change. Only way i can seem to do that is to hold a ref to that computed value , and force a makeDirty() call on it and it will recalc then

So my question is how do you get a ComputedValue to automatically do the fresh when a value in the closure changes - but you dont change the closure itself?




 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: problem with groovy swt: stuck with bind node processing and ComputedValues