The Source for Java Technology Collaboration

Home » java.net Forums » Java Desktop Technologies » SwingLabs

Thread: Experiments with beansbinding

Welcome, Guest Help
Login Login
Guest Settings Guest Settings
Reply to this Thread Reply to this Thread Search Forum Search Forum Back to Thread List Back to Thread List

Permlink Replies: 27 - Last Post: Apr 28, 2007 8:50 PM by: Shai Almog
kleopatra

Posts: 1,677
Experiments with beansbinding
Posted: Apr 18, 2007 3:28 AM
  Click to reply to this thread Reply

to keep you posted (and hopefully get some feedback :)

my incubator has a raw implementation of Fowler's AlbumManager (from his organizing presentation series), based on appframework and beansbinding. Plus I described the experiment on the beansbinding mailinglist - which currently is a bit dead, as everybody's on j1 preparation.

Cheers
Jeanette

Shai Almog
Re: Experiments with beansbinding
Posted: Apr 23, 2007 8:12 AM   in response to: kleopatra
  Click to reply to this thread Reply

Hi Jeanette,
I apologize for the much delayed response but I too am remarkably busy due
to J1 (although I'm not going).

I'm very curious about 295 and how it compares to my bean properties (
https://bean-properties.dev.java.net/ ) so I decided to try and port your
code to bean properties and see what I can learn. I learned quite allot and
I think it will be useful if I can publish this in the bean properties site
with the proper credits (if you don't mind).
I'd like to send you the code in person so we can discuss this if you have
the time/patience, some things worked rather well and mapped easily others I
didn't quite understand. The vetoable-selection thing I completely removed
(bean properties don't support veto, but I added it as an RFE so I will fix
it soon).
Some of your additions to the demo such as loading and the meta checkbox I
removed because the whole "model" classes were really hard for me to
understand.

Anyway, since bean properties don't need models I was able to cut the number
of classes from 13 to 6 (admittedly with slightly less functionality) and
reduce the code size within these classes by an additional ~30% (although I
didn't measure). Obviously all the compiler checks provided by bean
properties really helped.

I would be very interested to know what you think drop me a line and I will
send you the sources.

Thanks.

--
Shai Almog
vPrise
http://www.vprise.com/
[att1.html]


Kleopatra
Re: Experiments with beansbinding
Posted: Apr 24, 2007 2:29 AM   in response to: Shai Almog
  Click to reply to this thread Reply

Hi Shai,

> I apologize for the much delayed response but I too am remarkably busy
> due to J1 (although I'm not going).
>

no problem .. I feel the ripples from j1 as well (without attending :-)

> I'm very curious about 295 and how it compares to my bean properties (
> https://bean-properties.dev.java.net/ ) so I decided to try and port
> your code to bean properties and see what I can learn. I learned quite
> allot and I think it will be useful if I can publish this in the bean
> properties site with the proper credits (if you don't mind).

cool - go ahead and add your version the your project! The original
isn't mine anyway, it's described by Martin Fowler in his presentation
series (don't have the concrete link handy, his home is
martinfowler.com, I think) and Karsten adapted it for goodies binding.
Which I adapted to versions using appframework plus goodies and another
using appframework plus beansbinding. Quite happy to see others :-)

The only thing to keep in mind - the focus is on organizing the
presentation layer, not on the technicalities of binding frameworks
(which may help or hinder to reach the goal, though :-). So ...

>
> Anyway, since bean properties don't need models I was able to cut the
> number of classes from 13 to 6

.. is slightly off target - the model layer is not a side-effect of
beansbinding short-comings, but by design <g>

Looking forward to seeing your code in the bean-properties project (it's
easiest to keep current from there). As always, I prefer to keep any
discussions public, this way we all learn most from the effort.

Cheers
Jeanette

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


Shai Almog
Re: Experiments with beansbinding
Posted: Apr 24, 2007 4:56 AM   in response to: Kleopatra
  Click to reply to this thread Reply

> > Anyway, since bean properties don't need models I was able to cut the
> > number of classes from 13 to 6
>
> .. is slightly off target - the model layer is not a side-effect of
> beansbinding short-comings, but by design <g>


I saw Karsten's version but your seems to be so radically different that I
wanted to start off from there.
The models I saw within the application seem to be more of adapters than
models, I saw lots of what seemed to be replicated code/logic which might be
a valid design approach but I just didn't understand it. I'll post my
modified version in the workspace and we can discuss it then.

Looking forward to seeing your code in the bean-properties project (it's
> easiest to keep current from there). As always, I prefer to keep any
> discussions public, this way we all learn most from the effort.


Cool, I'll post everything to CVS and write a comparison to this forum so we
can discuss some of the major differences.


--
Shai Almog
vPrise
http://www.vprise.com/
[att1.html]


Kleopatra
Re: Experiments with beansbinding
Posted: Apr 24, 2007 5:54 AM   in response to: Shai Almog
  Click to reply to this thread Reply

Shai Almog schrieb:
>
> I saw Karsten's version but your seems to be so radically different that
> I wanted to start off from there.
> The models I saw within the application seem to be more of adapters than
> models, I saw lots of what seemed to be replicated code/logic which
> might be a valid design approach but I just didn't understand it.

kind of unexpected - I think it's very near to the goodies version,
except that I had to do the model layer entirely myself because
beansbinding doesn't have the notion of model (at least none I could
detect, may be blind ;-)

So I'm curious: Where do you see replication? The Album/-Manager stand
for the domain, the corresponding xxModel are the presentation
data/logic and the views are near-to as dumb as possible (it's an
example, so not entirely there).

Cheers
Jeanette



---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


Shai Almog
Re: Experiments with beansbinding
Posted: Apr 24, 2007 6:15 AM   in response to: Kleopatra
  Click to reply to this thread Reply

> So I'm curious: Where do you see replication? The Album/-Manager stand
> for the domain, the corresponding xxModel are the presentation
> data/logic and the views are near-to as dumb as possible (it's an
> example, so not entirely there).
>

I hope its not offensive, its probably me who misunderstood the code since
it seems like some code just isn't called or maybe I missed something
because of all the indirection.

The navigation is a huge portion I might just not have gotten, there is a
whole object dedicated for navigation and I still don't understand why you
would need both Navigation.java and BAlbumManagerNavigationView?
Also this seems to be allot of code for just next/previous functionality?
Even if you don't allow selecting some albums (veto functionality).

There are 4 different classes that contain the album list JXList are they
all the same thing?


--
Shai Almog
vPrise
http://www.vprise.com/
[att1.html]


Shai Almog
Re: Experiments with beansbinding
Posted: Apr 24, 2007 6:57 AM   in response to: Shai Almog
  Click to reply to this thread Reply

OK,
I checked in an initial version at:
https://bean-properties.dev.java.net/source/browse/bean-properties/Album/

Libraries of reference for comparison are here:
https://jdnc-incubator.dev.java.net/source/browse/jdnc-incubator/src/kleopatra/java/org/jdesktop/appframework/beansbinding/album/#dirlist

And here:
https://bean-properties.dev.java.net/source/browse/bean-properties/Album/src/org/jdesktop/appframework/beansbinding/album/

Major points of difference:
1. Album.java is much smaller and doesn't include getters/setters or any
observability method (add/remove/fire etc.).

2. No model objects, while the functionality (such as buffering) can be
replicated in the bean properties using either inheritance/delegation or
virtual properties I thought it doesn't illustrate much in the comparison
(and the port was taking me way too long anyway).

3. All relations are static and verified by the compiler! E.g. check out the
binding to the table in bean properties:

context.bindContent(albumManager.managedAlbums,
new PropertyContext[] {
a.artist.getContext(),
a.title.getContext(),
a.classical.getContext(),
a.composer.getContext()
}, albumTable);
context.bindSelectionIndex(albumManager.selection, albumTable);

Vs. the exact same code in the bean binding JSR:

context.addBinding(albumManagerModel.getNavigation(),
"${selectedElement}", albumTable, "selectedElement");
Binding tableBinding = context.addBinding(
albumManagerModel.getManagedAlbums(), null,
albumTable, "elements");
int column = 0;
tableBinding.addBinding("${artist}", null,
SwingBindingSupport.TableColumnParameter, column++);
tableBinding.addBinding("${title }", null,
SwingBindingSupport.TableColumnParameter, column++);
tableBinding.addBinding("${classical}", null,
SwingBindingSupport.TableColumnParameter, column++,
SwingBindingSupport.TableColumnClassParameter, Boolean.class);
tableBinding.addBinding("${composer}", null,
SwingBindingSupport.TableColumnParameter, column++);


The main problem I have with the JSR code isn't the longer syntax, that can
be fixed. The problem is all the strings used to bind into properties that
might be renamed, while porting I actually made such a mistake and renamed a
property only to get broken functionality and unrelated exceptions (from
within the application framework since the property was bound to
disable/enable an action).

4. What you don't see in the previous example is that bean properties
supports fully internationalizing the table column headers without knowing a
thing about the table (this is done by localizing a property context). This
can't be done in 295 and has to be achieved using a special API every time
you create a table.

5. The application framework makes heavy use of bound properties for things
such as disabling/enabling an action e.g.:
@Action(enabledProperty = "name")

This kind of sucks because of loose coupling which means that if I change a
property name this will just stop working... However, it can still work with
bean properties. This is from the 295 example:

public boolean isAlbumSelected() {
return navigation.getSelectedElement() != null;
}

public void setAlbumSelected(boolean selected) {
boolean sel = isAlbumSelected();
firePropertyChange("albumSelected", !sel, sel);
}

And this is from the bean properties example:

public final Property<Boolean> albumSelected = new
ObservableProperty<Boolean>(false);

public boolean isAlbumSelected() {
return albumSelected.get();
}

Notice that neither one of us defines fire/add/remove property etc.. This is
because both samples derive from a generic bean implementation that contains
basic features. If that weren't the case the samples would still be roughly
equivalent.


--
Shai Almog
vPrise
http://www.vprise.com/
[att1.html]


Kleopatra
Re: Experiments with beansbinding
Posted: Apr 24, 2007 7:24 AM   in response to: Shai Almog
  Click to reply to this thread Reply


cool - will have a look at it soon. Expect it to be fun <g>

Cheers
Jeanette

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


Kleopatra
Re: Experiments with beansbinding
Posted: Apr 24, 2007 9:04 AM   in response to: Shai Almog
  Click to reply to this thread Reply

Shai Almog schrieb:
>
> Major points of difference:
> 1. Album.java is much smaller and doesn't include getters/setters or any
> observability method (add/remove/fire etc.).
>

if that's your best argument, you better hide <g> no, no, just teasing!

I prefer less code to more, but only if I can get the same functionality
with less lines. So I'll start with a (random) list of functional
differences between our versions - some of them are probably trivial to
add to yours, I just list them anyway (no intention to dig into your
code and do it myself :-) And some might be related to the fact that you
have folded everything into two layers (bean and view), while mine has
three (domain, presentation model, view - where the Album/Manager are
meant to simulate the pure domain).

- Album: setClassical(false) should clear the composer property

- (missing) AlbumModel has presentation only property composerEnabled
which is synched to classical. This allows the view to bind the enabled
property of composerField/Label to that property.

- newAlbum on the combined view opens a dialog with a new album (created
by the domain layer) for editing. The new album is added only if the
user commits the dialog, otherwise it's thrown away.

- the apply/discard is enabled when changes to the details view are detected

- (you already mentioned it, just to repeat): the selection change is
not vetoable

- discard keeps the selection, thus showing the old unedited values. Not
sure why your version clears the selection and sets the details to a new
instance of Album? Which is directly instantiated instead of going
through the manager factory ... hmm. Wild guess - but could it be that
you have a similar "null" object binding issue as beansbinding?


> 2. No model objects, while the functionality (such as buffering) can be
> replicated in the bean properties using either inheritance/delegation or
> virtual properties I thought it doesn't illustrate much in the
> comparison (and the port was taking me way too long anyway).
>

not sure if that's true - buffering a bunch of related properties (not
necessarily on the same bean) is one of the trickier parts of binding,
especially if it comes to sharing data in multiple views. Had been
through that more than once <g>. Fowler formulated some interesting
general concepts about it. Can't live without that additional layer ever
since I read those.

> 3. All relations are static and verified by the compiler! E.g. check out
> the binding to the table in bean properties:
>

yeah, that a point a definitely like about your properties. Strings are
so error-prone, strings in EL even more so (did I ever mention I don't
like EL <g>).

>
> Vs. the exact same code in the bean binding JSR:
>
> context.addBinding(albumManagerModel.getNavigation(),
> "${selectedElement}", albumTable, "selectedElement");
>

nitpicking - but not "exact same": the navigation is vetoable :-) Though
that aspect is not yet complete and unrelated to JSR itself.

>
> 4. What you don't see in the previous example is that bean properties
> supports fully internationalizing the table column headers without
> knowing a thing about the table (this is done by localizing a property
> context). This can't be done in 295 and has to be achieved using a
> special API every time you create a table.
>

My guess is that in the end it will, at least in combination with
appframework.

> 5. The application framework makes heavy use of bound properties for
> things such as disabling/enabling an action e.g.:
> @Action(enabledProperty = "name")
>
> This kind of sucks because of loose coupling which means that if I
> change a property name this will just stop working...

agreed.

> However, it can
> still work with bean properties.

hmm... how? Tried a rename refactoring in Eclipse two ways and both
throw up:

- renamed the Property albumSelected to albumSelectedX with all bells
and whistles on: it caught the enabledProperty, but not the getter.

- renamed the getter which caught nothing else

maybe it's an Eclipse shortcoming?


My main quibble with your version is that there is no clear separation
between domain and presentation on the one side nor a further separation
between presentation logic and view on the other side. The reason seems
to be, that there _is no_ model support just similar as in beansbinding.
This leads to inconsistent separation of logic, f.i. you moved the
discard/apply plus it's enablement into the managerView - which violates
the "view must be dumb" rule of thumb. On the other hand you moved the
newAlbum/editAlbum/deleteAlbum actions plus enablement into the domain
(or your mixture of domain and presentation, don't know exactly how to
categorize it), which is kind of polluted by accessing a view (when
creating the edit dialog, f.i., which concededly is a problem in the
managerModel as well, only one layer nearer to the view ;).

Okay, that's for starters, getting hungry. Nice discussion, keep it coming!

Jeanette





---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


Shai Almog
Re: Experiments with beansbinding
Posted: Apr 24, 2007 11:25 AM   in response to: Kleopatra
  Click to reply to this thread Reply

> I prefer less code to more, but only if I can get the same functionality
> with less lines. So I'll start with a (random) list of functional


I think you get more functionality with less lines in my case ;-)
You get full fledged property objects that can be passed around and
internationalized, they can be statically checked and dynamically added.


differences between our versions - some of them are probably trivial to
> add to yours, I just list them anyway (no intention to dig into your
> code and do it myself :-) And some might be related to the fact that you
> have folded everything into two layers (bean and view), while mine has
> three (domain, presentation model, view - where the Album/Manager are
> meant to simulate the pure domain).


Very possible, the complexity of the additional tier didn't seem necessary
in this case. After all the bean tier can't be mapped to the database via an
API like JTA... JTA doesn't allow observability or any similar feature and
thus the additional abstraction seems to me like an interesting exercise but
of little practical value.

- Album: setClassical(false) should clear the composer property


This can be done with a virtual property (without changing the code) or
subclassing with a delegate property.
I intended to remove the UI since I removed the code.

- (missing) AlbumModel has presentation only property composerEnabled
> which is synched to classical. This allows the view to bind the enabled
> property of composerField/Label to that property.


I had that initially and removed it when I removed the AlbumModel, I
couldn't understand all the relationships with all the different classes and
everything started to break ;-

- the apply/discard is enabled when changes to the details view are detected


Easy to do, adding a listener to the bean which is installed to enable these
functions.

- (you already mentioned it, just to repeat): the selection change is
> not vetoable


I just added veto support to bean properties (haven't committed it though)
so it would be interesting to know what its supposed to do because I just
didn't understand the code.

- discard keeps the selection, thus showing the old unedited values. Not
> sure why your version clears the selection and sets the details to a new
> instance of Album? Which is directly instantiated instead of going
> through the manager factory ... hmm. Wild guess - but could it be that
> you have a similar "null" object binding issue as beansbinding?


If a property is null it can be bound to a text field, no problem... A
Boolean object can't be null when binding to a checkbox. However, if I want
to clear all the fields of an album I'd rather invoke bind(new Album())
(notice some properties of Album are null) than have to invoke every single
field and indicate I would want them to return to the default values.
I could revert values on discard I had not realized that was the original
functionality... It is actually easier.

> 2. No model objects, while the functionality (such as buffering) can be
> > replicated in the bean properties using either inheritance/delegation or
> > virtual properties I thought it doesn't illustrate much in the
> > comparison (and the port was taking me way too long anyway).
> >
>
> not sure if that's true - buffering a bunch of related properties (not
> necessarily on the same bean) is one of the trickier parts of binding,
> especially if it comes to sharing data in multiple views. Had been
> through that more than once <g>. Fowler formulated some interesting
> general concepts about it. Can't live without that additional layer ever
> since I read those.


Whats a model layer?
The beans themselves are a model layer, adding yet another model layer in
between seems to me like baggage not an advantage.
The views would all rely on the underlying bean layer which would propagate
changes to all views just the same.
Can you point out an exact use case or a specific example.


nitpicking - but not "exact same": the navigation is vetoable :-) Though
> that aspect is not yet complete and unrelated to JSR itself.


Sorry, I didn't realize this was related to vetoable selection. I assume the
code would be pretty similar since the vetoable selection doesn't seem
related to binding (or did I misunderstand that).

>
> > 4. What you don't see in the previous example is that bean properties
> > supports fully internationalizing the table column headers without
> > knowing a thing about the table (this is done by localizing a property
> > context). This can't be done in 295 and has to be achieved using a
> > special API every time you create a table.
> >
>
> My guess is that in the end it will, at least in combination with
> appframework.


I highly doubt it will be able to do this properly... Let me explain. If you
want to localize a new bean all you have to do is:
@Bean(localize=true, bundle="bundleName")
class MyBean {
public final Property<Integer> prop =....
}

then it will look in the resource bundle for a string matching
MyBean.prop.displayName etc... and localize the bean.
When you add the bean to the table its column names would match perfectly!
You can even customize that programmatically and you can use a different
strategy for localization overriding default property names!

Since table stores column names in the model it is impossible for the app
framework to do much in this regard.
The bean binding would have to provide some form of API where you would have
to invoke the table model and indicate to it what your column names should
be e.g.:
bindingInstance.setTableColumn("prop", "localizedValue");

Right now even this isn't supported.

> However, it can
> > still work with bean properties.
>
> hmm... how? Tried a rename refactoring in Eclipse two ways and both
> throw up:


Sorry I wasn't clear. It would screw up the rename once you use Strings, I
was talking about the general problem of old properties being string based.
I obviously can't fix this.
What I meant to say is that despite the fact that the bean is a new bean it
can still support a legacy property that plugs seamlessly into the
application framework. You would obviously be giving up type safety in order
to do so.

My main quibble with your version is that there is no clear separation
> between domain and presentation on the one side nor a further separation
> between presentation logic and view on the other side. The reason seems
> to be, that there _is no_ model support just similar as in beansbinding.
> This leads to inconsistent separation of logic, f.i. you moved the
> discard/apply plus it's enablement into the managerView - which violates
> the "view must be dumb" rule of thumb. On the other hand you moved the


I mixed view and model for these particular cases to match the code more
closely, also don't forget that I didn't quite understand the code :-(
Had I designed this from scratch I would not have put these methods there.
The problem was that some of the original classes in which these methods
existed made no sense in the newer architecture.
Obviously since these methods are completely separate I think you can see
that the mixing of view is very minor and unrelated to the bean properties
or binding.

About the model not having a clear separation, I would debate that... I
think it has all the separation realistically needed.



--
Shai Almog
vPrise
http://www.vprise.com/
[att1.html]


Kleopatra
Re: Experiments with beansbinding
Posted: Apr 24, 2007 1:06 PM   in response to: Shai Almog
  Click to reply to this thread Reply

Weeelll, it's late and maybe I got your intention wrong - but I think we
have a basic goal mismatch:

>
> Whats a model layer?
> The beans themselves are a model layer, adding yet another model layer
> in between seems to me like baggage not an advantage.

To repeat myself: the model layer I mean is the presentation model. The
ease with which a presentation model layer can be inserted is one of my
the major issues with binding frameworks (goodies has it for free,
beansbinding and bean-properties not at all). If you don't buy (not
necessarily from me, but f.i. from Fowler) that it's very helpful for
most non-trivial use-cases than we can't agree ;-) You are free to
choose whatever architecture you deem appropriate, I won't argue that -
but it's not what I'm after.

Cheers
Jeanette

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


Shai Almog
Re: Experiments with beansbinding
Posted: Apr 24, 2007 1:15 PM   in response to: Kleopatra
  Click to reply to this thread Reply

> To repeat myself: the model layer I mean is the presentation model. The
> ease with which a presentation model layer can be inserted is one of my
> the major issues with binding frameworks (goodies has it for free,
> beansbinding and bean-properties not at all). If you don't buy (not
> necessarily from me, but f.i. from Fowler) that it's very helpful for
> most non-trivial use-cases than we can't agree ;-) You are free to
> choose whatever architecture you deem appropriate, I won't argue that -
> but it's not what I'm after.
>

I'd have to disagree that bean properties doesn't allow such a model layer
to exist...
Its just not immediately obvious and I personally didn't include it in the
example.

I would really appreciate a practical use case to which I can respond since
this is a little vague, I have read Fowler extensively and I don't see
myself violating anything I can recall from his writings. I think our
definition of what a model is and whether a mediator layer needs to be user
visible differ.
I have a mediator layer which is used to implement binding (so does 295),
both Scott and myself chose to hide most of our mediator layer since it
would just confuse most users. JGoodies exposes it to allow greater power to
map to anything (not my goal since it has no use case when using bean
properties).

--
Shai Almog
vPrise
http://www.vprise.com/
[att1.html]


rturnbull

Posts: 460
Re: Experiments with beansbinding
Posted: Apr 26, 2007 9:34 PM   in response to: Shai Almog
  Click to reply to this thread Reply

> 5. The application framework makes heavy use of bound
> properties for things
> such as disabling/enabling an action e.g.:
> @Action(enabledProperty = "name")
>
> This kind of sucks because of loose coupling which
> means that if I change a
> property name this will just stop working... However,
> it can still work with
> bean properties. This is from the 295 example:
>
> public boolean isAlbumSelected() {
> return navigation.getSelectedElement() != null;
> }
>
> public void setAlbumSelected(boolean selected) {
> boolean sel = isAlbumSelected();
> firePropertyChange("albumSelected", !sel, sel);
> }

This works for me:

public final String enableDetail = "enableDetailButtons";
protected boolean enableDetailButtons = false;

public void setEnableDetailButtons(boolean state) {
boolean old = detailButtonsEnabled;
detailButtonsEnabled = state;
pcs.firePropertyChange(enableDetail, old, detailButtonsEnabled);
}

@Action(enabledProperty = enableDetail)
public void detailOK() {
cleanup();
}

which is a bit better. But the literal still has to have the same name as the property.
So if you want to change the property name, you have to change the is/get and set method names and the string literal.
<remove>
I'm not sure why Application wants to call the get/set methods for something that isn't defined with @Property.
</remove>

Please ignore the last sentence.
Not sure where it came from.
With all this new stuff (plus new to me stuff) I'm getting
a little confused.


Message was edited by: rturnbull

Joshua Marinacci
Re: Experiments with beansbinding
Posted: Apr 27, 2007 7:02 AM   in response to: rturnbull
  Click to reply to this thread Reply

> which is a bit better. But the literal still has to have the same
> name as the property.
> So if you want to change the property name, you have to change the
> is/get and set method names and the string literal.
> I'm not sure why Application wants to call the get/set methods for
> something that isn't defined with @Property.

Yes. The string literal problem is one of the reasons we are
considering adding properties into the language in Java 7. :)

- j


> [Message sent by forum member 'rturnbull' (rturnbull)]
>
> http://forums.java.net/jive/thread.jspa?messageID=214570
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
> For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

- Blasting forth in three part harmony!


[att1.html]


Shai Almog
Re: Experiments with beansbinding
Posted: Apr 27, 2007 7:43 AM   in response to: Joshua Marinacci
  Click to reply to this thread Reply

> Yes. The string literal problem is one of the reasons we are considering
> adding properties into the language in Java 7. :)
>

The problem with the language change is that it doesn't "really" solve the
problem, it only partially hides it behind compiler "magic" that will work
for common cases but won't be nearly as powerful as true object based
properties. But rather than talk in slogans let me explain:

When doing something like:
addPropertyChangeListener("prop", l);

You could now replace it with:
addPropertyChangeListener(bean.prop, l);

(this is possible in Java 5 with bean properties using addListener(bean.prop,
l) and I will get to that later).

In Java 7 you can do one of two things both of which suck...
1. Compile the above code to a string internally so the line
addPropertyChangeListener("prop", l);

Would just compile to:

addPropertyChangeListener(bean.prop, l);

2. Create a strict object on the fly since the property keyword maintains
compatibility you won't be able to store this object so every listener
binding would compile to:
addPropertyChangeListener(new PropertyWrapper(bean, "prop"), l);


I think people would understand the problem of the second approach and the
first approach would be verified by the compiler only when you do a proper
rebuild of all the code including libraries... Furthermore, you will still
pay for string lookups and still won't be able to treat properties as full
objects such as:

public final Property<Color> background = new PropertyImpl<Color>();
public final Property<Color> foreground = new PropertyImpl<Color>();

// you can't invoke this method externally since Color is immutable so you
would have to
// know about setBackground/setForeground without "real" property objects
adjustSaturation(background);
adjustSaturation(foreground);


These are just some of the reasons why the Java 7 change is fundamentally a
patch on something that is broken. For further details check out these:
https://bean-properties.dev.java.net/10things.html
https://bean-properties.dev.java.net/faq.html

--
Shai Almog
vPrise
http://www.vprise.com/
[att1.html]


Kleopatra
Re: Experiments with beansbinding
Posted: Apr 24, 2007 7:04 AM   in response to: Shai Almog
  Click to reply to this thread Reply

Shai Almog schrieb:
>
> I hope its not offensive,

not at all :-)

> The navigation is a huge portion I might just not have gotten, there is
> a whole object dedicated for navigation and I still don't understand why
> you would need both Navigation.java and BAlbumManagerNavigationView?
> Also this seems to be allot of code for just next/previous
> functionality? Even if you don't allow selecting some albums (veto
> functionality).
>
> There are 4 different classes that contain the album list JXList are
> they all the same thing?
>

dooohhh ... the reason for the confusion is entirely my fault, sorry,
should have cleaned up a bit: everything with navigation or WriteThrough
as part of its name is a left-over from experimenting (just moved the
unused out of the way). Which leaves (some with a B before, yet another
inconsistency ...)

BAlbumBrower - the application class, with tabs for 2 variants of
showing/editing an album
Album/BAlbumManager - domain data
AlbumModel/BAlbumManagerModel - presentation logic
BAlbumEditorView - the editor for a single album, used both in the
dialog and in the combined view
BAlbumManagerView - the list/details view
BTabularAlbumManagerView - the not-editable xtable showing the details,
editing in a modal dialog

The Navigation (ignore the prev/next for now) basically is the selection
container on the model side, a very raw effort to abstract the selection
control, which feels like a deja-vue from SelectionInList in goodies ;-)

Thanks for your patience!
Jeanette


---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


Shai Almog
Re: Experiments with beansbinding
Posted: Apr 24, 2007 7:10 AM   in response to: Kleopatra
  Click to reply to this thread Reply

> dooohhh ... the reason for the confusion is entirely my fault, sorry,
> should have cleaned up a bit: everything with navigation or WriteThrough
> as part of its name is a left-over from experimenting (just moved the
> unused out of the way). Which leaves (some with a B before, yet another
> inconsistency ...)


Thats why it was so confusing ;-)
I tried to follow the flow but just couldn't reach anywhere...

BAlbumBrower - the application class, with tabs for 2 variants of
> showing/editing an album
> Album/BAlbumManager - domain data
> AlbumModel/BAlbumManagerModel - presentation logic
> BAlbumEditorView - the editor for a single album, used both in the
> dialog and in the combined view
> BAlbumManagerView - the list/details view
> BTabularAlbumManagerView - the not-editable xtable showing the details,
> editing in a modal dialog
>
> The Navigation (ignore the prev/next for now) basically is the selection
> container on the model side, a very raw effort to abstract the selection
> control, which feels like a deja-vue from SelectionInList in goodies ;-)


I'm really not sure if I replicated the exact same functionality, I tried to
do something that "looked" similar but I don't know if its the same.
BTW why is the table not editable?



--
Shai Almog
vPrise
http://www.vprise.com/
[att1.html]


Kleopatra
Re: Experiments with beansbinding
Posted: Apr 24, 2007 7:31 AM   in response to: Shai Almog
  Click to reply to this thread Reply

Shai Almog schrieb:


> BTW why is the table not editable?

the simple, though evasive answer: because here the objective was a
separate editor, implemented in a modal dialog.

the truth: could not yet find a way to do a "buffered" in-place edit in
the table row as table edits are cell-based, not row-based. Don't know
if the beansbinding has some support for it, it's a bit complicated to
follow its inner workings ...

Jeanette

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


Shai Almog
Re: Experiments with beansbinding
Posted: Apr 24, 2007 7:37 AM   in response to: Kleopatra
  Click to reply to this thread Reply

> the truth: could not yet find a way to do a "buffered" in-place edit in
> the table row as table edits are cell-based, not row-based. Don't know
> if the beansbinding has some support for it, it's a bit complicated to
> follow its inner workings ...


Why would you need to "buffer" changes to the table? Why not update the
property right on the cell edit commit?
I think I just didn't get the buffering feature in your code ;-)


--
Shai Almog
vPrise
http://www.vprise.com/
[att1.html]


osbald

Posts: 853
Re: Experiments with beansbinding
Posted: Apr 24, 2007 7:59 AM   in response to: Kleopatra
  Click to reply to this thread Reply

> could not yet find a way to do a "buffered" in-place
> edit in the table row as table edits are cell-based, not
> row-based. Don't know if the beansbinding has some
> support for it

I don't think you're missing anything. I explicitly asked Scott about buffering and model helpers and he told me neither were covered by the JSR. Which is a shame, esp for the buffering which is a pretty common requirement (left me wondering what Karstens input on the JSR expert board was). For the model he seemed to assume it'd be a swingx.AsbtractBean, appframework.AsbtractBean or simply a home grown bound bean.

- Richard

Oh Just remembering something else re buffering.. he said make a copy of the model.. so you might want clonable and deep copy (copy constructors!!) thrown into your model object too.

Message was edited by: osbald

Shai Almog
Re: Experiments with beansbinding
Posted: Apr 24, 2007 8:12 AM   in response to: osbald
  Click to reply to this thread Reply

> I don't think you're missing anything. I explicitly asked Scott about
> buffering and model helpers and he told me neither were covered by the JSR.
> Which is a shame, esp for the buffering which is a pretty common requirement
> (left me wondering what Karstens input on the JSR expert board was). For the
> model he seemed to assume it'd be a swingx.AsbtractBean,
> appframework.AsbtractBean or simply a home grown bound bean.
>

Hmm... I meant in the term of the demo from Jeanette where she has some
fields in that respect ;-)

What sort of buffering support would you expect?
I toyed allot with the thought of adding some complex features to the
bindings some of which already exist in 295, but I decided they have no
actual use case but do complicate things quite a bit. E.g. in Jeanette's
example she used a logic of binding which allows the binding result to be
applied only when the "apply" button is pressed.
I OTOH don't have such a feature a binding is always immediate. The solution
however is trivial... Clone the object and then return it to the
modification.


--
Shai Almog
vPrise
http://www.vprise.com/
[att1.html]


Patrick Wright
Re: Experiments with beansbinding
Posted: Apr 24, 2007 8:38 AM   in response to: Shai Almog
  Click to reply to this thread Reply

> What sort of buffering support would you expect?

I think the goal is simply to be able to enter a bunch of changes and
still hit "cancel" if you want to back out.

Cloning is one solution, albeit possibly a little expensive; if you
have the buffering support you have some overhead for the data
structures but you only keep a copy of what is modified, not of all
fields. I haven't had time to look at these packages yet, but some
buffering support seems a "natural" part of the domain; I always
wanted to add more explicit buffering the the DataBuffer API, never
got around to it.

Regards
Patrick

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


Shai Almog
Re: Experiments with beansbinding
Posted: Apr 24, 2007 10:54 AM   in response to: Patrick Wright
  Click to reply to this thread Reply

>
> I think the goal is simply to be able to enter a bunch of changes and
> still hit "cancel" if you want to back out.
>
>
Since the bean properties implement a simple and fast generic clone method
it seems to me like the best approach. It is supported by default when
deriving from BaseBean but is generally a single line: BeanContainer.get
().clone(myBean);
This doesn't require any serialization or any expensive work, I don't see an
advantage in only holding what has specifically changed the difference in
memory would seem negligible for this use case.


--
Shai Almog
vPrise
http://www.vprise.com/
[att1.html]


i30817

Posts: 386
Re: Experiments with beansbinding
Posted: Apr 24, 2007 2:27 PM   in response to: Shai Almog
  Click to reply to this thread Reply

Sometimes the model you're altering is not amenable to cloning. Case in point the "awefull" Document family.

Shai Almog
Re: Experiments with beansbinding
Posted: Apr 24, 2007 2:31 PM   in response to: i30817
  Click to reply to this thread Reply

> Sometimes the model you're altering is not amenable to cloning. Case in
> point the "awefull" Document family.
>

I wasn't talking about cloning the document, I was talking about cloning the
bean which is always clonable in the caseof the bean properties API without
writing a single line of code. E.g.:
tempBean = BeanContainer.get().clone(beanIWantToEdit);
editBean(tempBean);
...
if(!canceled) {
// replace existing bean with tempBean
}

--
Shai Almog
vPrise
http://www.vprise.com/
[att1.html]


Kleopatra
Re: Experiments with beansbinding
Posted: Apr 24, 2007 9:12 AM   in response to: Shai Almog
  Click to reply to this thread Reply

Shai Almog schrieb:

> I OTOH don't have such a feature a binding is always immediate. The
> solution however is trivial... Clone the object and then return it to
> the modification.
>

That's only one use case anyway, be sure to read Fowler's series, he
explains the pros and cons much better than I could. And I disagree with
that it's trivial in the general case, having experienced too many
little devils in the details ;-).

Cheers
Jeanette


---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


osbald

Posts: 853
Re: Experiments with beansbinding
Posted: Apr 24, 2007 10:27 AM   in response to: Kleopatra
  Click to reply to this thread Reply

Should really read through Jeanettes latest comments before posting, but I was just in a meeting where everybody created large amounts of work for me and I want to go home.

The buffering is largely to support dialogs, which the user can commit or discard at any point. I suppose hence the name dialog as it covers a single conversation or session. The problem with purely direct binding is that your model may simply be another POJO in the same VM - but it may also be (more usefully) a remote object.. in which case updates incur network overhead, security checks etc.. I know Scott has something in beansbinding to avoid updates on every keypresses (document changes) and can sync on focus loss etc.. This is one level of buffering.

The other level of buffering is knowing what changes have been made. If I copy the model I won't know what operations have been performed on it when the user hits apply. You might just be binding to an model with a couple of strings.. in which case to could compare the two and work out what needs to be changed. However if your dialog has a something like a table with editable cells, the user can add, remove rows, columns and reorder them that comparison isn't feasible anymore. (esp when order is important). The issue here is that while you're free to manipulate your PM in any way.. when you come to commit those changes to a remote server it may fail at any point on validation, security or concurrency etc.. grounds. Sometimes you can just replace the remote object / model with your modified copy safe in the knowledge nothing else could have changed and each of your individual changes were also valid in the remote domain. Other times you really can't cut those corners. As Jeanette says the devils in the details.

Using an ORM like JPA or Hibernate can get you here as the objects they return are often proxies.. adding an item to such a proxied collection will automatically invoke/create JDBC methods on the database. So direct binding might be doing more then you'd like. More often you've got value objects from a remote method using the ORM. In which case your problem is reversed. You then need to make individual changes to the original objects state in order to invoke the correct JDBC operations. You can't replace the remote proxied collections with you're vanilla undecorated ones (and you can't create new proxied ones outside of the same session/context).

Another reason for having that granularity of individual changes might be when you need full Undoable & Redoable support.

Another wrinkle is that UI representation for any given property is likely to be stored & accessed differently from the UI. A single model date property stored as GMT might appear as two separate fields one for date one for time and in each the in clients preferred locale format (i.e. not GMT). Kartsen I think refers to this as indirection. Of course you could use a PresentationModel to iron out these differences and only bind to the PM - which is often preferable. Things like this will bite you if your model object differ from your UIs which of course they should as you shouldn't model your objects on how they might look on the screen.

- Richard

Shai Almog
Re: Experiments with beansbinding
Posted: Apr 24, 2007 11:50 AM   in response to: osbald
  Click to reply to this thread Reply

Very interesting, I think I accept the point of having the ability to track
specific changes made to the object and as I explain in the body its pretty
easy to add such a feature to bean properties. However, since such cases
aren't the norm and do contain overhead (at least in terms of complexity) I
would not make it the default behavior.

The buffering is largely to support dialogs, which the user can commit or
> discard at any point. I suppose hence the name dialog as it covers a single
> conversation or session. The problem with purely direct binding is that your
> model may simply be another POJO in the same VM - but it may also be (more
> usefully) a remote object.. in which case updates incur network overhead,
> security checks etc.. I know Scott has something in beansbinding to avoid
> updates on every keypresses (document changes) and can sync on focus loss
> etc.. This is one level of buffering.


Interesting use case, I think it can also be supported by cloning. I
generally think that since this is a UI, the overhead of cloning the edited
objects wouldn't be great... However, the API as a result is considerably
simpler and its implementation is simpler still.

The other level of buffering is knowing what changes have been made. If I
> copy the model I won't know what operations have been performed on it when
> the user hits apply.


Does buffering know that?
I would be surprised... Anyway thats pretty trivial to add, if someone
actually needs that functionality he should probably pay the penalty of
complexity/overhead rather than the more common use case that doesn't need
that.

You might just be binding to an model with a couple of strings.. in which
> case to could compare the two and work out what needs to be changed. However
> if your dialog has a something like a table with editable cells, the user
> can add, remove rows, columns and reorder them that comparison isn't
> feasible anymore. (esp when order is important).


You mean you would have a bean containing a large list of beans. You would
edit the bean and as a result the beans within it, so you wouldn't want to
clone the whole tree... Usually when I saw such use cases when you edit/move
an entry in the sub bean the change was permanent and unaffected by cancel.
If it is affected by cancel then I doubt a buffering layer would do
something more efficient than just cloning the whole structure. Its just too
complicated, buffering is for simple things like text fields I don't think
it would perform a use case like this more efficiently.
If it would then it might be worthwhile to consider adding something like
this as an optional feature.

The issue here is that while you're free to manipulate your PM in any way..
> when you come to commit those changes to a remote server it may fail at any
> point on validation, security or concurrency etc.. grounds. Sometimes you
> can just replace the remote object / model with your modified copy safe in
> the knowledge nothing else could have changed and each of your individual
> changes were also valid in the remote domain. Other times you really can't
> cut those corners. As Jeanette says the devils in the details.


I do lots of n-tier programming and have grown on the knees of CORBA ;-)
I am quite familiar with those details and yes they do exist but rarely are
they handled manually. I can understand the desire to detect and "merge" the
changes from an object... I think I might add such functionality to a
framework which is just trivial to do (add a listener to a bean, track which
properties have changed and keep them in the list. When called to merge only
update modified properties).

Using an ORM like JPA or Hibernate can get you here as the objects they
> return are often proxies.. adding an item to such a proxied collection will
> automatically invoke/create JDBC methods on the database. So direct binding
> might be doing more then you'd like.


I'm building my own ORM right now, which is a real pain... harder than it
sounds!
Point is that an ORM would often be mapped to an object on its own and not
to a 295 bean since an ORM object shouldn't be observable but a 295 bean
MUST be observable.
So you would essentially have to build a 295 bean and a separate
JPA/Hibernate bean both of which would look very similar but have different
semantics (annotations vs. observability). You would then have to map the
295 bean to the UI and upon commit do a one way bind between the observable
bean to the JPA bean (or map manually if the tiers don't match well).
With bean properties I would use a mirror object into which I would set the
values or just map manually.

I don't see where 295 would allow you to only synchronize changes.


More often you've got value objects from a remote method using the ORM. In
> which case your problem is reversed. You then need to make individual
> changes to the original objects state in order to invoke the correct JDBC
> operations. You can't replace the remote proxied collections with you're
> vanilla undecorated ones (and you can't create new proxied ones outside of
> the same session/context).


Thats true anyway for a remote object whether its a POJO/cloned or not, I
don't get the point?

Another reason for having that granularity of individual changes might be
> when you need full Undoable & Redoable support.


True. But isn't this mostly a view feature?

Another wrinkle is that UI representation for any given property is likely
> to be stored & accessed differently from the UI. A single model date
> property stored as GMT might appear as two separate fields one for date one
> for time and in each the in clients preferred locale format (i.e. not
> GMT). Kartsen I think refers to this as indirection. Of course you could use
> a PresentationModel to iron out these differences and only bind to the PM -
> which is often preferable. Things like this will bite you if your model
> object differ from your UIs which of course they should as you shouldn't
> model your objects on how they might look on the screen.
>

Thats a very interesting point but I don't think I understand to how it
specifically relates in the discussion above?

--
Shai Almog
vPrise
http://www.vprise.com/
[att1.html]





 XML java.net RSS