Geertjan is a DZone Zone Leader and has posted 468 posts at DZone. You can read more from them at their website. View Full User Profile

Rediscovering the Caricature Demo for Beans Binding

02.21.2008
| 8022 views |
  • submit to reddit
I came across Scott Violet's caricature demo sometime ago and also found the sources somewhere, probably in his blog. The demo is used to demonstrate, in a humorous way, what the Beans Binding Framework is all about. It shows a caricature, as the application object, with Swing controls that bind to its properties. However, the sample didn't work anymore with the current version of the APIs. On top of which, the Timing API and Animations API have also undergone change in the meantime. So, I had a bit of work to do...

However, today I figured it out! Or, at least, everything except the animation part. The code that I needed to work on, because it had changed since Scott wrote the demo, is the following part, which shows exactly the part that is relevant to the Beans Binding Framework:

public BindingCaricatureController() {
bindingGroup = new BindingGroup();
Binding eyeBinding = Bindings.createAutoBinding(AutoBinding.UpdateStrategy.READ_WRITE,
caricature, BeanProperty.create("eyeStyle"), eyesSlider, BeanProperty.create("value"));
Binding faceBinding = Bindings.createAutoBinding(AutoBinding.UpdateStrategy.READ_WRITE,
caricature, BeanProperty.create("faceStyle"), faceSlider, BeanProperty.create("value"));
Binding mouthBinding = Bindings.createAutoBinding(AutoBinding.UpdateStrategy.READ_WRITE,
caricature, BeanProperty.create("mouthStyle"), mouthSlider, BeanProperty.create("value"));
Binding hairBinding = Bindings.createAutoBinding(AutoBinding.UpdateStrategy.READ_WRITE,
caricature, BeanProperty.create("hairStyle"), hairSlider, BeanProperty.create("value"));
Binding noseBinding = Bindings.createAutoBinding(AutoBinding.UpdateStrategy.READ_WRITE,
caricature, BeanProperty.create("noseStyle"), noseSlider, BeanProperty.create("value"));
Binding rotationBinding = Bindings.createAutoBinding(AutoBinding.UpdateStrategy.READ_WRITE,
caricature, BeanProperty.create("rotation"), rotationSlider, BeanProperty.create("value"));
bindingGroup.addBinding(eyeBinding);
bindingGroup.addBinding(faceBinding);
bindingGroup.addBinding(mouthBinding);
bindingGroup.addBinding(hairBinding);
bindingGroup.addBinding(noseBinding);
bindingGroup.addBinding(rotationBinding);
bindingGroup.bind();
}

When I ran the application, I could use the Swing controls to change the application object's properties:

On top of that, I found that I could take Scott's cool application object and add it to the palette in NetBeans IDE. From there, I can drag it onto Swing containers. The Properties window displays all the properties that I can bind to my Swing controls:

And, while in design mode, I can also use the Properties window to try out the properties defined in the application object:

This is going make one cool demo for Beans Binding Framework presentations, also because it shows how snugly application objects integrate with NetBeans IDE!

Published at DZone with permission of its author, Geertjan Wielenga.

Comments

Artur Biesiadowski replied on Fri, 2008/02/22 - 8:36am

It took me considerable amount of time to understand that 'caricature' was about the face, not about how the code looks like.

I think that something wrong is happening with java. Or me. I'm getting bit tired of useless verbosity. Good verbosity is great, self documenting code is great, copy/paste galore obscuring important bits (like in code given above) is bad. I don't know the correct solution, but I certainly don't like what I see here.

Geertjan Wielenga replied on Fri, 2008/02/22 - 10:25am

What exactly is it that you don't like?

Richard Lowe replied on Fri, 2008/02/22 - 11:20am

I would rename bindingGroup to head or headGroup. It would also be cool if you could show grouping of groups like head to neck to body etc... Other than that this is very cool.

Artur Biesiadowski replied on Fri, 2008/02/22 - 1:28pm in response to: Geertjan Wielenga

I don't like ratio of noise to information. Real information in this code is (using non-existing groovscaluby syntax)

eyeSlider.bindTo(caricature.eyeStyle);
faceSlider.bindTo(caricature.faceStyle);
mouthSlider.bindTo(caricature.mouthStyle);
hairSlider.bindTo(caricature.hairStyle);
noseSlider.bindTo(caricature.noseStyle);
rotationSlider.bindTo(caricature.rotation);
// might be also foobarSlider.value.bindTo(caricature.foobarStyle) if somebody prefers

or even

with caricature bind
eyeStyle to eyeSlider,
faceStyle to faceSlider,
mouthStyle to mouthSlider,
hairStyle to hairSlider,
rotation to rotationSlider

Everything more than that is a noise. I'm generally not against verbose, self documenting code, but there have to be benefits of it. Using old style connectors (changelisteners+setters), code would be 4 times longer, but there is a benefit of seeing exactly what is happening on method call level, plus have full strong typing/refactoring. On the other edge, would be some kind of groovy-like builder (something similar to a pseudocode above), which hides the details, but allows you to see the real information used - and only it.

What I can see with caricature example is a middle ground - binding through non-typed, non-refactorable strings and what is worse, a lot of superflous code, not helping in understand what is happening, being there just because java requires it.

In my opinion, this middle ground is probably worst place to be - too far and not far enough at the same time.

Opponents of various extensions of java language (closures, properties, field/method references, etc) are claiming such features would pollute java. At the same time, we are getting libraries which are proposing programming in this way, just with elaborate syntax and string-based, refactoring-unfriendly references.

I understand the reasons behind the BeanBindings and I know that they can be used in some places in gui IDE to allow drag-and-drop programming, serialization of component graphs, etc. I'm just unhappy that there is no way to express in better way in current java code.

(edit)

I have just realized that this post was done through neatbeans zone. I have seen it on java zone, so my comments are purely java-language/library oriented - I'm in no way referring to netbeans support of that library (and it seems to be very good). 

Richard Bair replied on Fri, 2008/02/22 - 4:34pm

Hey Artur

I agree with you. Here are some reasons why you shouldn't be too worried about the current verbosity in Beans Binding

  • I agree that in it's current state it is too verbose for everyday use. Sure, the IDE helps, but I'd like the code to be simple too. However, I also think Shannon has done a great job in capturing the many details associated with binding, so I don't mind all the verbosity at this level. But there has to be a higher level API for doing simple binding in my opinion, particularly with swing components. Expect this to be smoother as we continue to work forward
  • If properties and reflection literals make it into the language, we'll be saved from having to use Strings. Even if they don't, if you use something like the bean-properties project for your properties, you can create a "Property" adapter in BeansBinding and use that instead of having to use the strings

Walter Laan replied on Sat, 2008/02/23 - 7:40am

I've found some source (without animation) at the groovy repository (someone just checked that in ^^).

The binding in Groovy is like this:

slider(id:'noseSlider', minimum:0, maximum:4,
value:bind(target:caricature, targetProperty:'noseStyle', value:2))

Using bean-properties, JCaricature loses about 50 lines of boiler plate and binding is like this:

SwingBind.get().bind(caricature.noseStyle, noseSlider);    

plus the JSlider min/max config code. If BeanBindings SwingBindings supported JSlider it think it would look like this (using static import):

group.add(SwingBindings.createJSliderBinding(READ_WRITE,
caricature, BeanProperty.create("noseStyle"), noseSlider);

Things that I miss:

  • The minimum and maximum values should really be defined by the property and auto configure the slider on binding.
  • Bean properties can't bind the float scale property directly, I made a wrapper property for that. Not sure how that was done Netbeans example. Groovy Swingbuilder allows you to add a (one-way?) converter.
Caricature Bean properties demo webstart or jar with source.

Talden replied on Sun, 2008/02/24 - 7:20pm

Note: I don't us bean binding and don't know the API or the planned API but I just thought it worth expressing what might be possible if the right combination of java 7 features arrive.

I could see each binding becoming something similar to the following:

    // Add a binding for the eyes of the caricature.
bindingGroup.addBinding(READ_WRITE.create(caricature, Caricature#eyeStyle, eyesSlider, Slider#value));

Where the properties are type-safe reflections using FCM property references (or change them to Type#getX if properties aren't supported).

A create method on the AutoBinding.UpdateStrategy would be needed to make it this concise and possibly isn't appropriate. I've also assumed the use of static import as others have mentioned.

If a new set of reflection classes could be provided (EG ReferencedProperty that adds to Property) then the call could become:

    BindingGroup.addBinding(READ_WRITE.create(caricature#eyeStyle, eyesSlider#value));

as "ref#property" could be syntactic sugar for:

    ReferencedProperty.create(DeclaredClassOfRef#property, ref)

Likewise similar Referenced forms of Method and Field would allow binding a reference and a method/field/property type together.

Mateo Gomez replied on Wed, 2012/07/04 - 5:53am

I am learning so much here from you guys..keep sharing! corn salsa recipe

 

Matt Coleman replied on Tue, 2012/07/31 - 1:43am

great caricature,.very helpful and useful

web designer buffalo

Cata Nic replied on Tue, 2013/09/03 - 3:23am

 What is happen with the clients if they will see this post? :) I think they will be amused too. :)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.