You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Oliver Rossmueller <ol...@tuxerra.com> on 2005/03/03 02:08:30 UTC

Tree2

Sean,

I finally found some time to dig into your tree implementation, and 
although it's a nice component there are some issues I would like to 
discuss:

- I don't like how you changed the way the data is handed over to the 
tree by forcing the user to provide TreeNode implementors? To use 
TreeModel in swing was a wise decision of the designers at sun as it's 
an interface which can be implemented for any kind of hierarchical data 
in a simple and lightweight manner. That's why I duplicated it in my 
tree impl. In you model I would be forced to wrap all my internal node 
objects with a TreeNode implementor because I'm not able to change the 
internal node objects as  they are provided by a 3rd party library. It 
can be done but in comparison to the TreeModel implementation I have in 
place at the moment it's a more complex and more heavyweight solution. 
And I don't like to have to ask my boss to buy better machines and more 
RAM because instead of one object per node now I have to create two of them.
- tree2 is not able to deal with node selection so anybody would be on 
his own to implement this feature; I think there should be a way to have 
the tree handle node selection
- your scheme of defining how the nodes are rendered is nice and simple, 
but it will not work out for some of the scenarios I have to deal with; 
so we have to find a more powerful way to specify rendering rules

Oliver

-- 
Oliver Rossmueller
Software Engineer and IT-Consultant
Hamburg, Germany
http://www.rossmueller.com


Re: Tree2

Posted by Sean Schofield <se...@gmail.com>.
> None of your components, tree or tree2, is better than the other one.
> Both are excellent components with perhaps different features.

Agreed.  When Oliver and I started this process we agreed that there
was room for improvement in the current tree control.  I think we've
made some of those improvements.

> So, please: Is there any realistic chance to merge these two into one
> super tree component that has every single feature of both worlds?

That has been my goal all along so I am ok with that.  I have been
asking for feedback on the user list asking users to try out the new
tree and let me know what issues there were (including missing
functionality from the current tree.)  So far the big thing that has
come up is that there is a companion tree table control that depends
on the current tree control.  So right now I am working on making a
tree table that is compatible with the new tree control.

> - Consolidate the abstract view (the interfaces users would implement).
> In doubt, let's do it the Swing way. This is what people already might
> know and are familiar with.

Both are already similar (but not identical) to the Swing interface. 
The changes to the new tree interface are small but crucial so there's
not a lot of wiggle room there.  There are a few things I took out
because they are no longer needed and a few things that have been
added because they are now needed.  Ultimately I think the interface
depends on your approach to solving the problem.

> - All interfaces and classes that are at least similar in function in
> both components must have both author tags. Might sound childish, but it
> is not. Everyone of us is proud of the code he has hacked. And that's
> ok. So, please be fair and reference the other author when you had equal
> ideas or where influenced by the other's code.

I think we have this already.  I will double check to make sure all
relevant files have the appropriate author tags.  (Side note: I'm not
sure author tags are allowed for top level Apache projects.  When
Struts changed from Jakarta to Apache we had to remove all of the
author tags.)

> - No fear to change interfaces or behaviour if that makes things simpler
> for everyone. Yes, people might already use the old tree component. And
> they will have to change their code. But nobody will have a problem with
> that, if the gain is a new all-in-one super tree component. On the
> contrary, nobody will be happy in the long run with two nearly-equal but
> competing tree components.

I agree 100% with this.  Also, noody forces the user to upgrade to the
next version of MyFaces.  The end user controls the timing of this. 
Our users also have the opportunity to influence the outcome of the
new control through participation on the mailing list.

> Oliver, please be fair to Sean and tell him every single issue, you
> think is missing or sub-optimal in tree2, in a clearly laid out and
> businesslike manner.

I remain open to criticism.  The more specific the better.  The new
tree has benefited already from the suggestions/criticisim of Oliver
and others.  I promise not to take it personally.

> Sean, please be fair to Oliver and tell him every single issue, you
> think is missing or sub-optimal in tree1, in a clearly laid out and
> businesslike manner.

My biggest issue in the current tree is lack of javascript support. 
Every time you click on a node you have to post to the server.  This
makes the tree very slow.  Oliver has pointed out that sometimes the
size of a tree is too large to render completely on the client and
thus a tree has to support the server expansion method.  I agree with
him on that, so the tree should support both (which I have done in the
new tree.)  Javascript support on the client is a must have.

My second issue in the current tree is the complexity in both its
design and configuration.  I found it to difficult to setup a simple
tree for myself that did what I needed.  I have a use case where I
need to specify different types of icons depending on the nature of
the node that is being rendered.  I think a solution that relies on
facets, commandLinks, value binding expressions and other familiar JSF
concepts is easier to use.

Finally there appears to be limitations on what can go in a tree.  It
would be nice if the tree could accept any kind of JSF component as
the node and for all normal JSF behavior to work for those components.
 ex. You could add an inputText component to nodes of a certain type
and have listeners for ValueChangeEvents, etc.  Basically give the
user complete flexability on how the tree can be rendered and what can
go in the tree.

> Ok, I'm not starry-eyed, so please, both of you, whenever there is an
> issue, where you do not see any chance for an agreement, stay fair and
> please take the effort, describe the problem, so that also non tree
> experts have a clue, and let us vote about it.

Sounds good.

> And always have in mind that written words are subject to
> misinterpretation more than spoken words. We are all no well-trained
> diplomats, so our language might sound rough sometimes, although not
> meant so. Please have this in mind and always assume, that the other
> party meant it businesslike, also if it sounds affective.

I have been trying my best in this area but there is always room for
improvement.  I like to consider myself a team player.
 
> If everybody stays fair, I'm sure we could have a one-for-all kick-ass
> MyFaces tree component.

Yes!
 
> Manfred

sean

Re: Tree2

Posted by Sean Schofield <se...@gmail.com>.
> I don't know what was wrong with my post or with Sean's reply that
> caused you to write this message, but anyway I sign 99% of it's content.
> The 1% I can not follow completely is the point according interface
> changes. From my POV we have to be careful in changing existing
> components. If you are in the middle of a project you care about any
> change in a framework you are using. To say it's up to the user to
> update to a new MyFaces release or not is only half of the truth.
> Consider there is a bug in MyFaces which blocks an important feature of
> your application and which will be fixed in the next release. Where is
> your choice in this situation? As you urgently need the fix you have to
> update. And now consider that by updating to the next release you also
> get a a new tree/tabbed pane/navigation/... component which offers the
> same or better functionality as the old one but by using a different
> interface or programming model so that your existing code will break.
> You don't care about new and better functionality in this situation, you
> just want the fix to finish your project. So what would your opinion be
> in this situation. I suppose you would not be too happy the MyFaces
> developers force you to change a crucial part of your application?

The open source nature of MyFaces gives the user an additional choice.
 They could always build their own version of the jar and mix and
match functionality.  In fact, maybe we could provide a legacy tree
jarfile that would contain the old tree stuff to help users who didn't
want to upgrade right away?
 
> To make it short: there is no problem in changing components and their
> interfaces as long as the changes are small and straightforward and
> require only slight modifications by the user. In any other case we
> should continue to support the old component (by providing a legacy
> package for example).

I would argue that is precisely what is being proposed.  Straight
forward, relatively minor changes.  So you do agree that it ok to
change the interface in some circumstances then?  As long as you are
open to that idea then I think we can work something out that
satisifes everyone.  I will address your specific concerns in your
second email.
 
> Oliver

sean

Re: Tree2

Posted by Oliver Rossmueller <ol...@tuxerra.com>.
Manfred,

I don't know what was wrong with my post or with Sean's reply that 
caused you to write this message, but anyway I sign 99% of it's content. 
The 1% I can not follow completely is the point according interface 
changes. From my POV we have to be careful in changing existing 
components. If you are in the middle of a project you care about any 
change in a framework you are using. To say it's up to the user to 
update to a new MyFaces release or not is only half of the truth. 
Consider there is a bug in MyFaces which blocks an important feature of 
your application and which will be fixed in the next release. Where is 
your choice in this situation? As you urgently need the fix you have to 
update. And now consider that by updating to the next release you also 
get a a new tree/tabbed pane/navigation/... component which offers the 
same or better functionality as the old one but by using a different 
interface or programming model so that your existing code will break. 
You don't care about new and better functionality in this situation, you 
just want the fix to finish your project. So what would your opinion be 
in this situation. I suppose you would not be too happy the MyFaces 
developers force you to change a crucial part of your application?

To make it short: there is no problem in changing components and their 
interfaces as long as the changes are small and straightforward and 
require only slight modifications by the user. In any other case we 
should continue to support the old component (by providing a legacy 
package for example).

Oliver


Manfred Geiler wrote:

> Oliver, Sean,
> I do not understand every single issue in your current discussion, but 
> what I see is some danger in the direction your discussion is heading 
> for at the moment. Please, both, lean back for a few seconds. "My 
> stuff is better" discussions are always counterproductive and often 
> end with one party giving up and saying "goodbye". That is what nobody 
> wants. MyFaces needs both of you!
> None of your components, tree or tree2, is better than the other one. 
> Both are excellent components with perhaps different features.
> So, please: Is there any realistic chance to merge these two into one 
> super tree component that has every single feature of both worlds?
> When I say merge, I mean:
> - Consolidate the abstract view (the interfaces users would 
> implement). In doubt, let's do it the Swing way. This is what people 
> already might know and are familiar with.
> - All interfaces and classes that are at least similar in function in 
> both components must have both author tags. Might sound childish, but 
> it is not. Everyone of us is proud of the code he has hacked. And 
> that's ok. So, please be fair and reference the other author when you 
> had equal ideas or where influenced by the other's code.
> - No fear to change interfaces or behaviour if that makes things 
> simpler for everyone. Yes, people might already use the old tree 
> component. And they will have to change their code. But nobody will 
> have a problem with that, if the gain is a new all-in-one super tree 
> component. On the contrary, nobody will be happy in the long run with 
> two nearly-equal but competing tree components.
>
> Oliver, please be fair to Sean and tell him every single issue, you 
> think is missing or sub-optimal in tree2, in a clearly laid out and 
> businesslike manner.
>
> Sean, please be fair to Oliver and tell him every single issue, you 
> think is missing or sub-optimal in tree1, in a clearly laid out and 
> businesslike manner.
>
> Ok, I'm not starry-eyed, so please, both of you, whenever there is an 
> issue, where you do not see any chance for an agreement, stay fair and 
> please take the effort, describe the problem, so that also non tree 
> experts have a clue, and let us vote about it.
> And always have in mind that written words are subject to 
> misinterpretation more than spoken words. We are all no well-trained 
> diplomats, so our language might sound rough sometimes, although not 
> meant so. Please have this in mind and always assume, that the other 
> party meant it businesslike, also if it sounds affective.
>
> If everybody stays fair, I'm sure we could have a one-for-all kick-ass 
> MyFaces tree component.
>
> Thank you guys,
> Manfred
>
>
>
> Sean Schofield schrieb:
>
>>> - I don't like how you changed the way the data is handed over to the
>>> tree by forcing the user to provide TreeNode implementors? To use
>>> TreeModel in swing was a wise decision of the designers at sun as it's
>>> an interface which can be implemented for any kind of hierarchical data
>>> in a simple and lightweight manner. That's why I duplicated it in my
>>> tree impl. In you model I would be forced to wrap all my internal node
>>> objects with a TreeNode implementor because I'm not able to change the
>>> internal node objects as  they are provided by a 3rd party library. It
>>> can be done but in comparison to the TreeModel implementation I have in
>>> place at the moment it's a more complex and more heavyweight solution.
>>> And I don't like to have to ask my boss to buy better machines and more
>>> RAM because instead of one object per node now I have to create two 
>>> of them.
>>
>>
>>
>> I don't quite understand your objection.  The new approach to the data
>> is similar to the old except simpler.  Yes the data will have to be in
>> TreeNode objects but that's true in the current tree and its true in
>> Swing.  Take a look at your tree.jsp example.  You are putting the
>> data in DefaultMutableTreeNode which extends your TreeNode interface. 
>> In my example you put the data in TreeNodeBase which extends my
>> TreeNode interface.  OK so you have to change your data population
>> code slightly but that doesn't seem to be what you're complaining
>> about.
>>
>> In both versions of the component (and in Sun's JTree) you have to put
>> the data in an object that implements a TreeNode interface.  The new
>> tree is no different.   In fact, the interface is simpler.  I don't
>> understand the third party tool argument.  Do you really have third
>> party tools that are returning objects that implement
>> org.apache.myfaces.custom.tree.TreeNode?  If not, then what do third
>> party objects have to do with anything?
>>
>> I will play Devil's advocate for a moment and say that the best
>> argument against the new tree is that you might have to make slight
>> changes to your code so that your are populating TreeNodeBase (or you
>> own custom TreeNode) instead of whatever your were populating before. 
>> A non trivial change but IMO well worth it to get the new features of
>> the new tree.  You definitely do not have to have two sets of objects
>> or buy more RAM.
>>
>>
>>> - tree2 is not able to deal with node selection so anybody would be on
>>> his own to implement this feature; I think there should be a way to 
>>> have
>>> the tree handle node selection
>>
>>
>>
>> I'm not sure how to respond to that.  Tree2 handles node selection
>> perfectly fine IMO.  What do you mean by this?  What is it not able to
>> do that you need it to be able to do?  The nodes open and close when
>> you click on them.  It works in javascript or through server post.  It
>> remembers which nodes are open.  And you can put pretty much any JSF
>> component in the node (checkbox, image, commandLink, radio buttons,
>> whatever) and it handles the events appropriately.
>>
>>
>>> - your scheme of defining how the nodes are rendered is nice and 
>>> simple,
>>> but it will not work out for some of the scenarios I have to deal with;
>>> so we have to find a more powerful way to specify rendering rules
>>
>>
>>
>> I'd be interested in hearing what kinds of scenarios this scheme
>> couldn't handle.  Perhaps you there are some but if the component can
>> be improved by understanding your scenario then I'd like to know. 
>> Both you and Heath have thrown some intersesting scenarios my way in
>> the past and I think I have adressed them (and the component is better
>> for it.)
>>
>>
>>> Oliver
>>
>>
>>
>> sean
>>
>>


-- 
Oliver Rossmueller
Software Engineer and IT-Consultant
Hamburg, Germany
http://www.rossmueller.com


Re: Tree2

Posted by Manfred Geiler <ma...@apache.org>.
Oliver, Sean,
I do not understand every single issue in your current discussion, but 
what I see is some danger in the direction your discussion is heading 
for at the moment. Please, both, lean back for a few seconds. "My stuff 
is better" discussions are always counterproductive and often end with 
one party giving up and saying "goodbye". That is what nobody wants. 
MyFaces needs both of you!
None of your components, tree or tree2, is better than the other one. 
Both are excellent components with perhaps different features.
So, please: Is there any realistic chance to merge these two into one 
super tree component that has every single feature of both worlds?
When I say merge, I mean:
- Consolidate the abstract view (the interfaces users would implement). 
In doubt, let's do it the Swing way. This is what people already might 
know and are familiar with.
- All interfaces and classes that are at least similar in function in 
both components must have both author tags. Might sound childish, but it 
is not. Everyone of us is proud of the code he has hacked. And that's 
ok. So, please be fair and reference the other author when you had equal 
ideas or where influenced by the other's code.
- No fear to change interfaces or behaviour if that makes things simpler 
for everyone. Yes, people might already use the old tree component. And 
they will have to change their code. But nobody will have a problem with 
that, if the gain is a new all-in-one super tree component. On the 
contrary, nobody will be happy in the long run with two nearly-equal but 
competing tree components.

Oliver, please be fair to Sean and tell him every single issue, you 
think is missing or sub-optimal in tree2, in a clearly laid out and 
businesslike manner.

Sean, please be fair to Oliver and tell him every single issue, you 
think is missing or sub-optimal in tree1, in a clearly laid out and 
businesslike manner.

Ok, I'm not starry-eyed, so please, both of you, whenever there is an 
issue, where you do not see any chance for an agreement, stay fair and 
please take the effort, describe the problem, so that also non tree 
experts have a clue, and let us vote about it.
And always have in mind that written words are subject to 
misinterpretation more than spoken words. We are all no well-trained 
diplomats, so our language might sound rough sometimes, although not 
meant so. Please have this in mind and always assume, that the other 
party meant it businesslike, also if it sounds affective.

If everybody stays fair, I'm sure we could have a one-for-all kick-ass 
MyFaces tree component.

Thank you guys,
Manfred



Sean Schofield schrieb:
>>- I don't like how you changed the way the data is handed over to the
>>tree by forcing the user to provide TreeNode implementors? To use
>>TreeModel in swing was a wise decision of the designers at sun as it's
>>an interface which can be implemented for any kind of hierarchical data
>>in a simple and lightweight manner. That's why I duplicated it in my
>>tree impl. In you model I would be forced to wrap all my internal node
>>objects with a TreeNode implementor because I'm not able to change the
>>internal node objects as  they are provided by a 3rd party library. It
>>can be done but in comparison to the TreeModel implementation I have in
>>place at the moment it's a more complex and more heavyweight solution.
>>And I don't like to have to ask my boss to buy better machines and more
>>RAM because instead of one object per node now I have to create two of them.
> 
> 
> I don't quite understand your objection.  The new approach to the data
> is similar to the old except simpler.  Yes the data will have to be in
> TreeNode objects but that's true in the current tree and its true in
> Swing.  Take a look at your tree.jsp example.  You are putting the
> data in DefaultMutableTreeNode which extends your TreeNode interface. 
> In my example you put the data in TreeNodeBase which extends my
> TreeNode interface.  OK so you have to change your data population
> code slightly but that doesn't seem to be what you're complaining
> about.
> 
> In both versions of the component (and in Sun's JTree) you have to put
> the data in an object that implements a TreeNode interface.  The new
> tree is no different.   In fact, the interface is simpler.  I don't
> understand the third party tool argument.  Do you really have third
> party tools that are returning objects that implement
> org.apache.myfaces.custom.tree.TreeNode?  If not, then what do third
> party objects have to do with anything?
> 
> I will play Devil's advocate for a moment and say that the best
> argument against the new tree is that you might have to make slight
> changes to your code so that your are populating TreeNodeBase (or you
> own custom TreeNode) instead of whatever your were populating before. 
> A non trivial change but IMO well worth it to get the new features of
> the new tree.  You definitely do not have to have two sets of objects
> or buy more RAM.
> 
> 
>>- tree2 is not able to deal with node selection so anybody would be on
>>his own to implement this feature; I think there should be a way to have
>>the tree handle node selection
> 
> 
> I'm not sure how to respond to that.  Tree2 handles node selection
> perfectly fine IMO.  What do you mean by this?  What is it not able to
> do that you need it to be able to do?  The nodes open and close when
> you click on them.  It works in javascript or through server post.  It
> remembers which nodes are open.  And you can put pretty much any JSF
> component in the node (checkbox, image, commandLink, radio buttons,
> whatever) and it handles the events appropriately.
> 
> 
>>- your scheme of defining how the nodes are rendered is nice and simple,
>>but it will not work out for some of the scenarios I have to deal with;
>>so we have to find a more powerful way to specify rendering rules
> 
> 
> I'd be interested in hearing what kinds of scenarios this scheme
> couldn't handle.  Perhaps you there are some but if the component can
> be improved by understanding your scenario then I'd like to know. 
> Both you and Heath have thrown some intersesting scenarios my way in
> the past and I think I have adressed them (and the component is better
> for it.)
> 
> 
>>Oliver
> 
> 
> sean
> 
> 

Re: Tree2

Posted by Sean Schofield <se...@gmail.com>.
I am sorry if the email I just sent made it to the list.  I initially
meant to reply to the list but changed my mind and decided that I
would just include Manfred and Oliver.  I stand by the contents of the
email but I had not meant to bother the rest of the developers with
this matter.

I am looking forward to more productive discussions in the future.

sean


On Mon, 14 Mar 2005 02:15:23 +0100, Oliver Rossmueller
<ol...@tuxerra.com> wrote:
> Sean,
> 
> you do not accept my argument that the wrapper objects I would need
> following your programming model waste memory. That's fine for me. But
> tell you what: I do not accept your argument that implementing TreeModel
> is a special case nobody else is using. My colleagues and I have
> implemented TreeModel variants for dozens of Swing applications to save
> memory resources. Of course you can do without your own implementation
> by using DefaultTreeModel. But - accept it or not - memory consumption
> matters for some people out there. So don't wipe this argument from the
> table like it's not there.
> 
> I'll tell you how we are going to resolve this: when you came along with
> the idea for an improved tree component I told you we can get all the
> requirements you are looking for by refactoring the existing tree
> component. You choose the revolutionary approach and started your own
> component from scratch. That's just fine for me but now I'm going to try
> the evolutionary approach by refactoring the existing tree and
> incorporating new functionality from tree2. I'm quite sure this can be
> done without breaking existing code. As I have other stuff to work on,
> too, this will not be finished within the next few days. Anyway it
> should be worth the time as we'll end up with one tree component and
> without the need for a legacy package.
> 
> In the meantime if there will be a MyFaces release we should mark tree2
> as experimental and tell anybody that he's using this component at his
> own risk.
> 
> Oliver
> 
> 
> Sean Schofield wrote:
> 
> >Oliver,
> >
> >You are correct that option 3 is missing in the new tree and that its
> >present in JTree and the current tree.  This was not designed to
> >intentionally deprive you of functionality that you need in your
> >application.  It didn't really occur to me that tree should support
> >this kind of functionality.
> >
> >You must admit that your situation is a pretty specialized case.  How
> >many MyFaces users are using third party components that provide tree
> >data via a model?  My guess is that most are pulling the data
> >themselves from LDAP or a database and they are using either options 1
> >or 2 which tree2 can handle.
> >
> >You are basically asking for the ability to plug a third party data
> >model directly into the tree without wrapping the objects with an
> >adapter, etc. to conform to TreeNode interface.  I definitely think
> >that it is acceptable to wrap your data with a very *light* object
> >that can provide this functionality.  I do not accept your argument
> >that this wastes precious memory.  The adapter pattern is a standard
> >practice and is done all the time without crashing servers.  I agree
> >that in your case it would be a hassle to change the code but lets not
> >overstate the ramifications of this solution.
> >
> >Your code sample where you show how you could use tree2 right now
> >seems perfectly fine to me.  I recall that you are using the
> >server-side expansion control now because you have too much data to
> >push to the client at once.  This makes the wrapping of your
> >components even less burdensome.
> >
> >Since there seems to be some concern about losing this functionality,
> >I would propose that we consider keeping the original tree but moving
> >it to a legacy package name and give it a tag like <treeLegacy>.  Also
> >we should deprecate the current tree classes.  Since it looks like a
> >release will be coming soon I think this is the best short-term
> >solution.
> >
> >Then you and I can explore the possibility of providing option 3
> >functionality in a future release.
> >
> >What do you think about that?  I take it you have no other concerns at
> >this point other than option 3 functionality.  Is that correct?
> >
> >sean
> >
> >
> >On Sat, 12 Mar 2005 14:22:55 +0100, Oliver Rossmueller
> ><ol...@tuxerra.com> wrote:
> >
> >
> >>Sean Schofield wrote:
> >>
> >>
> >>
> >>><snip>
> >>>
> >>>Yes you are repeating yourself over and over on this point.  I do not
> >>>see how tree2 has changed the basic requirments of the user.  You keep
> >>>saying that I am against TreeModel and for TreeNode.  That is not the
> >>>case.  Let me try to phrase my argument differently ...
> >>>
> >>>You are correct that JTree operates on a TreeModel instance.  It also
> >>>has TreeNode interface.  Data is first wrapped in TreeNode instance
> >>>before being added to the model.  See this example from Sun's JTree
> >>>example:
> >>>
> >>>rootNode = new DefaultMutableTreeNode("Root Node");
> >>>treeModel = new DefaultTreeModel(rootNode);
> >>>treeModel.addTreeModelListener(new MyTreeModelListener());
> >>>tree = new JTree(treeModel);
> >>>
> >>>You are correct that JTree does not require a TreeNode interface.  I
> >>>agree with you there.  JTree does require a *different* interface,
> >>>however, and that interface is TreeModel.  You cannot just add some
> >>>arbitrary String "Foo" to a JTree.  How would the tree know what to do
> >>>with it?  Is this string a leaf or not?  How can you add children to a
> >>>String?  You have two choices.  First choice is to use
> >>>DefaultMutableTreeNode and DefaultTreeModel (as shown above.)  That
> >>>option *requires* TreeNode.  Second choice is to write your own class
> >>>that implements TreeModel.  Either way, you cannot just add an
> >>>arbitrary String to a JTree.
> >>>
> >>>Again, I urge us not to think in terms of JTree.  Lets leave JTree out
> >>>of this for now.  Lets just talk about the shortcomings of tree2.  If
> >>>we can address those then we can move forward.  IMO discussing JTree
> >>>is not helpful in reaching consensus on this.
> >>>
> >>>
> >>>
> >>>
> >>The point is not JTree but the options the user has in providing data:
> >>
> >>Option 1: Use DefaultTreeModel and wrap your node objects using
> >>DefaultMutableTreeNode
> >>
> >>Option 2: Use DefaultTreeModel and have your node objects implement
> >>interface TreeNode
> >>
> >>Option 3: Implement interface TreeModel on your own
> >>
> >>As the current tree component's design closely follows JTree you have
> >>the same three options:
> >>
> >>Option 1: Use DefaultTreeModel and wrap your node objects using
> >>DefaultMutableTreeNode
> >>
> >>Option 2: Use DefaultTreeModel and have your node objects implement
> >>interface TreeNode
> >>
> >>Option 3: Implement interface TreeModel on your own
> >>
> >>Now you say we do not need option 3 anymore, so tree2 only has
> >>
> >>Option 1: Use TreeNodeBase to wrap your node objects
> >>
> >>Option 2: Have your node objects implement interface tree2.TreeNode
> >>
> >>As you kicked away the TreeModel interface (your TreeModel class is just
> >>an implementation-specific internal helper for HtmlTree as I see it) I
> >>no longer have the option to implement TreeModel on my own. But named
> >>option 3 is a crucial option and it's absence is an absolute show
> >>stopper for me. As words seem not to work out in explaining my argument
> >>I'll try it with an example this time. It follows the scenario using the
> >>3rd party library already mentioned before.
> >>
> >>So at the moment I have an implementation of interface TreeModel which
> >>looks somewhat like the following:
> >>
> >>public class MyTreeModel implements TreeModel
> >>{
> >>
> >>   private ExternalLib externalLib = new ExternalLib();
> >>
> >>   public Object getRoot()
> >>   {
> >>       return externalLib.top();
> >>   }
> >>
> >>   public Object getChild(Object parent, int index)
> >>   {
> >>       ExternalObject[] children = externalLib.subnodes(parent);
> >>       return children[index];
> >>   }
> >>
> >>   public int getChildCount(Object parent)
> >>   {
> >>       return externalLib.countSubnodes(parent);
> >>   }
> >>
> >>   public boolean isLeaf(Object node)
> >>   {
> >>       return externalLib.testLeaf(node);
> >>   }
> >>
> >>   public int getIndexOfChild(Object parent, Object child)
> >>    {
> >>        ExternalObject[] children = externalLib.subnodes(parent);
> >>        for (int i = 0; i < children.length; i++)
> >>        {
> >>            if (children[i].equals(child)) {
> >>                return i;
> >>            };
> >>
> >>        }
> >>        return -1;
> >>     }
> >>
> >>   public void valueForPathChanged(TreePath path, Object newValue)
> >>   {
> >>       ...
> >>   }
> >>
> >>   public Collection getTreeModelListeners()
> >>   {
> >>       ...
> >>   }
> >>}
> >>
> >>Simple enough, isn't it? But you tell me I can't use TreeModel anymore
> >>when using tree2. So any node object has to implement tree2.TreeNode. As
> >>I have no  access to the sorces of ExternalLib and ExternalObject and
> >>therefore can not implement interface tree2.TreeNode in the library I
> >>have to use a wrapper. Unfortunatelly I cannot use option 1 ans
> >>TreeNodeBase just operates on strings. Ok, so I have to implement
> >>tree2.TreeNode on my own:
> >>
> >>public class TreeNodeWrapper implements TreeNode
> >>{
> >>   private String identifier;
> >>   private ExternalObject node;
> >>   ExternalLib externalLib;
> >>
> >>   public TreeNodeWrapper(ExternalObject node, ExternalLib externalLib)
> >>   {
> >>       this.node = node;
> >>       this.externalLib = externalLib;
> >>   }
> >>
> >>   public boolean isLeaf()
> >>   {
> >>       return externalLib.testLeaf(node);
> >>   }
> >>
> >>   public void setLeaf(boolean leaf)
> >>   {
> >>       // don't know why this is in the interface
> >>       throw new UnsupportedOperationException();
> >>   }
> >>
> >>   public List getChildren()
> >>   {
> >>       ExternalObject[] children = externalLib.subnodes(parent);
> >>       ArrayList answer = new ArrayList(children.length);
> >>
> >>       for (int i = 0; i < children.length; i++)
> >>       {
> >>           answer.add(new TreeNodeWrapper(children[i], externalLib));
> >>// <= EXTRA OBJECT HERE ###############
> >>       }
> >>
> >>       return answer;
> >>   }
> >>
> >>   public String getType()
> >>   {
> >>       return node.getTypeName();
> >>   }
> >>
> >>   public void setType(String type)
> >>   {
> >>       // don't know why this is in the interface
> >>       throw new UnsupportedOperationException();
> >>   }
> >>
> >>   public void setDescription(String description)
> >>   {
> >>       // don't know why this is in the interface
> >>       throw new UnsupportedOperationException();
> >>   }
> >>
> >>   public String getDescription()
> >>   {
> >>       return node.getLabel();
> >>   }
> >>
> >>   public void setIdentifier(String identifier)
> >>   {
> >>       this.identifier = identifier;
> >>   }
> >>
> >>   public String getIdentifier()
> >>   {
> >>       return identifier;
> >>   }
> >>
> >>   public int getChildCount()
> >>   {
> >>       return externalLib.countSubnodes(node);
> >>   }
> >>}
> >>
> >>All right, complexity of this implementation is similar to the TreeModel
> >>implementation. But my main argument against your decistion to drop
> >>option 3 is the need for extra wrapper objects to fulfill the conctract
> >>(see method getChildren() above where any ExternalObject has to be put
> >>inside another wrapper object). Maybe you do not care about resource
> >>consumption but I do and I have to because the machines I have at hand
> >>are kind of limited in that aspect. So I don't like to be forced to
> >>waste memory just because you do not like the TreeModel interface and
> >>the programming model behind it. You say it's just an interface but you
> >>have to see the implications on possible implementations this change in
> >>interfaces has. That's what I'm talking about all the time.
> >>
> >>So please give option 3 back to users and change tree2 to take
> >>tree.model.TreeModel instances as it's value instead of tree2.TreeNode.
> >>Or show me a way to fulfill the tree2.TreeNode contract without the need
> >>for extra objects in the example above.
> >>
> >>Oliver
> >>
> >>
> >>
> >>>
> >>>
> >>>
> >>>>Exactly that's my argument: the TreeNodeBase instance is the extra
> >>>>object you force me to create!!! When implementing TreeModel there is no
> >>>>need for this extra object, I'm able to use just the 3rd party data
> >>>>objects, naked and unwrapped as I get the from the external library. I
> >>>>don't have to wrap them with DefaultMutableTreeNode or any other object.
> >>>>
> >>>>
> >>>>
> >>>>
> >>>I guarantee that your third party component is not returing objects
> >>>that implement TreeModel.  That is my point.  I think you are getting
> >>>hung up on the wording of TreeModel vs. TreeNode.  The current tree
> >>>needs to make the raw data compliant with what the component expects
> >>>(TreeModel).  The new tree does the same thing but calls it something
> >>>different (TreeNode.)   The current tree also has a TreeNode interface
> >>>and you say that its not required to use the tree.  That's fine.  I
> >>>won't argue that point.
> >>>
> >>>To summarize, the current tree requires that data be adapted to the
> >>>TreeModel interface.  The new tree requires that data be adapted to
> >>>the TreeNode interface.  The fact that I am calling it TreeNode
> >>>instead of TreeModel does not make it any more difficult for the user
> >>>to implement.  The new tree also has a TreeModel class.  A difference
> >>>in the new implementation is that the model stuff is handled behind
> >>>the scenes.  There is no need for the user to provide their own model.
> >>>We could look at changing that but basically its already possible to
> >>>provide your own models by extending the TreeModel class.
> >>>
> >>>Please take another look at how I am using TreeNode and TreeModel.  If
> >>>you think its important that the user can provide their own models
> >>>then lets explore that!  Maybe this is the nature of your objection.
> >>>If so, I'm happy to work with you on that.
> >>>
> >>>I think some of the confusion is over the changes in implementation.
> >>>This is primarily a difference of opinion between the two of us.  It
> >>>doesn't affect the users.  Most users are going to use
> >>>DefaultMutableTreeNode as you do in your example or TreeNodeBase as I
> >>>do in my example.
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>>Again you seem to ignore my argument. I'm not talking about
> >>>>expanded/collapsed state but about SELECTED nodes. Take the tree example
> >>>>in the examples webapp. When you click the text of the root node it will
> >>>>get bold as the root node is the selected node now. Go on and expand
> >>>>some of the children and click the text of one of the child nodes: again
> >>>>the text will get bold to mark the selected node. At any time it is
> >>>>possible to ask the current tree for the path to the node currently
> >>>>selected. In tree2 the component itself does not care about that so I
> >>>>have to implement that feature on my own. It can be done using some
> >>>>specific command links and actions but I think to keep track of a
> >>>>selected node is a feature so common to tree components that is should
> >>>>be implemented there.
> >>>>
> >>>>
> >>>>
> >>>>
> >>>This is the kind of specific use case that I have been asking you to
> >>>provide.  Until now you just kept telling me that the new tree could
> >>>not handle selection.  Now I see what you mean by selection.  Let me
> >>>see if I can't address it in the new tree.  I will get back to you on
> >>>this one.
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>>Actually that's what I'm doing I suppose: to talk about features that
> >>>>are missing for tree2. But you have to be open for the fact that there
> >>>>are other scenarios and applications than the one you have in mind. I
> >>>>understand that your effort is driven by the requirements of the project
> >>>>you are currently working on. The current tree component has it's origin
> >>>>in a similar effort. To get a general-purpose tree component we have to
> >>>>address the issues I brought on the table. Otherwise we end up with two
> >>>>tree implementations which have something in common but miss some
> >>>>feature the other implementation has and vice versa. This can not be the
> >>>>goal if you ask me.
> >>>>
> >>>>
> >>>>
> >>>>
> >>>I agree we need to address these issues.  In order to do that, I need
> >>>specifics.  I will look into the selection issue as you have asked.  I
> >>>think I can work something out on that one.  As for the interface
> >>>issue, please take another look at my reasoning on that.  If you want
> >>>the ability to provide your own TreeModel then maybe that's something
> >>>we can do (although I don't think its necessary.)
> >>>
> >>>Believe it or not I think we are making progress.  I now know what you
> >>>mean by the selection problem.  So we are 50% there.  Lets see if we
> >>>can't reach an understanding on the inteface issue.
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>>Oliver
> >>>>
> >>>>
> >>>>
> >>>>
> >>>sean
> >>>
> >>>
> >>>
> >>>
> >>--
> >>Oliver Rossmueller
> >>Software Engineer and IT-Consultant
> >>Hamburg, Germany
> >>http://www.rossmueller.com
> >>
> >>
> >>
> >>
> 
> --
> Oliver Rossmueller
> Software Engineer and IT-Consultant
> Hamburg, Germany
> http://www.rossmueller.com
> 
>

[offlist] End of the Road (Was Re: Tree2)

Posted by Sean Schofield <se...@gmail.com>.
Oliver,

You continue to embarass yourself with these ranting email messages. 
Up until this point I have been *more* than patient with your antics. 
I have tried over and over again to be diplomatic with you about this.
 I understand that you put a lot of hard work into the original tree
control and I have tried to be sensitive to that fact.  I approached
you privately off the list to see if your were willing to work
together on this.  If I had known how you would have handled this back
then I would never have bothered.

The fact of the matter is that the current tree control is unworkable
for me.  I tried working within its existing code base but I found
that to be impossible.  I tried soliciting your opinion but after a
few posts you dropped out of the conversation entirely only to emerge
when the component was complete and not to your satisfaction.

You have been extremely dismissive of the new tree control and all of
the hard work that myself and others have put into it.  You continue
to insult me with your posts that imply that I am too much of an idiot
to understand you.  Believe me, I get it.  You are the only one who
knows how to write a tree control.

I learned a long time ago that the key to good software development
was teamwork.  Each programmer brings something to the table and the
best software tends to draw on a synthesis of those ideas.  I took
this approach when developing the new tree control and included some
of your ideas along with those of others.

It is clear to me that you do not have any interest in working
together anymore.  Manfred (and others) have pleaded with us to work
this out.  You refuse to move even an inch.  You refuse to concede
that there is any merit to a new tree control.  You have insulted both
myself and my ideas.

Well I am personally tired of banging my head into a wall on this.  I
have more important things to do with my time.  I think the new tree
control is great.  It has 99% of the original tree functionality with
a ton more features.  And its much easier to configure and uses half
the amount of source code.  If you were willing to work with me on it
you could have had 100% of the current tree functionaltiy.

So my plan is to use this in my own program.  If MyFaces still wants
the new tree then I will be happy to provide the documentation and
support.  I think its kind of silly to have two trees but if everyone
thinks that is a good copromise then I will go along.  I have one
request which is that we resolve this quickly.  I need to know whether
I should stop with my open source efforts on this particular component
or not.

Lets put this tree argument to rest once and for all so we can move
onto more productive matters.  We have a lot of top level project
tasks to be handled and a new release of MyFaces coming.  The tree
control is only a small part of a much larger project.

Since Manfred is our leader on this project I will defer to him as how
we best go forward.  As I mentioned to him a few weeks ago, I am
willing to withdraw my code or to have two tree components.  I am
willing to have an informal or formal vote.

Regards,
sean







On Mon, 14 Mar 2005 02:15:23 +0100, Oliver Rossmueller
<ol...@tuxerra.com> wrote:
> Sean,
> 
> you do not accept my argument that the wrapper objects I would need
> following your programming model waste memory. That's fine for me. But
> tell you what: I do not accept your argument that implementing TreeModel
> is a special case nobody else is using. My colleagues and I have
> implemented TreeModel variants for dozens of Swing applications to save
> memory resources. Of course you can do without your own implementation
> by using DefaultTreeModel. But - accept it or not - memory consumption
> matters for some people out there. So don't wipe this argument from the
> table like it's not there.
> 
> I'll tell you how we are going to resolve this: when you came along with
> the idea for an improved tree component I told you we can get all the
> requirements you are looking for by refactoring the existing tree
> component. You choose the revolutionary approach and started your own
> component from scratch. That's just fine for me but now I'm going to try
> the evolutionary approach by refactoring the existing tree and
> incorporating new functionality from tree2. I'm quite sure this can be
> done without breaking existing code. As I have other stuff to work on,
> too, this will not be finished within the next few days. Anyway it
> should be worth the time as we'll end up with one tree component and
> without the need for a legacy package.
> 
> In the meantime if there will be a MyFaces release we should mark tree2
> as experimental and tell anybody that he's using this component at his
> own risk.
> 
> Oliver
> 
> 
> Sean Schofield wrote:
> 
> >Oliver,
> >
> >You are correct that option 3 is missing in the new tree and that its
> >present in JTree and the current tree.  This was not designed to
> >intentionally deprive you of functionality that you need in your
> >application.  It didn't really occur to me that tree should support
> >this kind of functionality.
> >
> >You must admit that your situation is a pretty specialized case.  How
> >many MyFaces users are using third party components that provide tree
> >data via a model?  My guess is that most are pulling the data
> >themselves from LDAP or a database and they are using either options 1
> >or 2 which tree2 can handle.
> >
> >You are basically asking for the ability to plug a third party data
> >model directly into the tree without wrapping the objects with an
> >adapter, etc. to conform to TreeNode interface.  I definitely think
> >that it is acceptable to wrap your data with a very *light* object
> >that can provide this functionality.  I do not accept your argument
> >that this wastes precious memory.  The adapter pattern is a standard
> >practice and is done all the time without crashing servers.  I agree
> >that in your case it would be a hassle to change the code but lets not
> >overstate the ramifications of this solution.
> >
> >Your code sample where you show how you could use tree2 right now
> >seems perfectly fine to me.  I recall that you are using the
> >server-side expansion control now because you have too much data to
> >push to the client at once.  This makes the wrapping of your
> >components even less burdensome.
> >
> >Since there seems to be some concern about losing this functionality,
> >I would propose that we consider keeping the original tree but moving
> >it to a legacy package name and give it a tag like <treeLegacy>.  Also
> >we should deprecate the current tree classes.  Since it looks like a
> >release will be coming soon I think this is the best short-term
> >solution.
> >
> >Then you and I can explore the possibility of providing option 3
> >functionality in a future release.
> >
> >What do you think about that?  I take it you have no other concerns at
> >this point other than option 3 functionality.  Is that correct?
> >
> >sean
> >
> >
> >On Sat, 12 Mar 2005 14:22:55 +0100, Oliver Rossmueller
> ><ol...@tuxerra.com> wrote:
> >
> >
> >>Sean Schofield wrote:
> >>
> >>
> >>
> >>><snip>
> >>>
> >>>Yes you are repeating yourself over and over on this point.  I do not
> >>>see how tree2 has changed the basic requirments of the user.  You keep
> >>>saying that I am against TreeModel and for TreeNode.  That is not the
> >>>case.  Let me try to phrase my argument differently ...
> >>>
> >>>You are correct that JTree operates on a TreeModel instance.  It also
> >>>has TreeNode interface.  Data is first wrapped in TreeNode instance
> >>>before being added to the model.  See this example from Sun's JTree
> >>>example:
> >>>
> >>>rootNode = new DefaultMutableTreeNode("Root Node");
> >>>treeModel = new DefaultTreeModel(rootNode);
> >>>treeModel.addTreeModelListener(new MyTreeModelListener());
> >>>tree = new JTree(treeModel);
> >>>
> >>>You are correct that JTree does not require a TreeNode interface.  I
> >>>agree with you there.  JTree does require a *different* interface,
> >>>however, and that interface is TreeModel.  You cannot just add some
> >>>arbitrary String "Foo" to a JTree.  How would the tree know what to do
> >>>with it?  Is this string a leaf or not?  How can you add children to a
> >>>String?  You have two choices.  First choice is to use
> >>>DefaultMutableTreeNode and DefaultTreeModel (as shown above.)  That
> >>>option *requires* TreeNode.  Second choice is to write your own class
> >>>that implements TreeModel.  Either way, you cannot just add an
> >>>arbitrary String to a JTree.
> >>>
> >>>Again, I urge us not to think in terms of JTree.  Lets leave JTree out
> >>>of this for now.  Lets just talk about the shortcomings of tree2.  If
> >>>we can address those then we can move forward.  IMO discussing JTree
> >>>is not helpful in reaching consensus on this.
> >>>
> >>>
> >>>
> >>>
> >>The point is not JTree but the options the user has in providing data:
> >>
> >>Option 1: Use DefaultTreeModel and wrap your node objects using
> >>DefaultMutableTreeNode
> >>
> >>Option 2: Use DefaultTreeModel and have your node objects implement
> >>interface TreeNode
> >>
> >>Option 3: Implement interface TreeModel on your own
> >>
> >>As the current tree component's design closely follows JTree you have
> >>the same three options:
> >>
> >>Option 1: Use DefaultTreeModel and wrap your node objects using
> >>DefaultMutableTreeNode
> >>
> >>Option 2: Use DefaultTreeModel and have your node objects implement
> >>interface TreeNode
> >>
> >>Option 3: Implement interface TreeModel on your own
> >>
> >>Now you say we do not need option 3 anymore, so tree2 only has
> >>
> >>Option 1: Use TreeNodeBase to wrap your node objects
> >>
> >>Option 2: Have your node objects implement interface tree2.TreeNode
> >>
> >>As you kicked away the TreeModel interface (your TreeModel class is just
> >>an implementation-specific internal helper for HtmlTree as I see it) I
> >>no longer have the option to implement TreeModel on my own. But named
> >>option 3 is a crucial option and it's absence is an absolute show
> >>stopper for me. As words seem not to work out in explaining my argument
> >>I'll try it with an example this time. It follows the scenario using the
> >>3rd party library already mentioned before.
> >>
> >>So at the moment I have an implementation of interface TreeModel which
> >>looks somewhat like the following:
> >>
> >>public class MyTreeModel implements TreeModel
> >>{
> >>
> >>   private ExternalLib externalLib = new ExternalLib();
> >>
> >>   public Object getRoot()
> >>   {
> >>       return externalLib.top();
> >>   }
> >>
> >>   public Object getChild(Object parent, int index)
> >>   {
> >>       ExternalObject[] children = externalLib.subnodes(parent);
> >>       return children[index];
> >>   }
> >>
> >>   public int getChildCount(Object parent)
> >>   {
> >>       return externalLib.countSubnodes(parent);
> >>   }
> >>
> >>   public boolean isLeaf(Object node)
> >>   {
> >>       return externalLib.testLeaf(node);
> >>   }
> >>
> >>   public int getIndexOfChild(Object parent, Object child)
> >>    {
> >>        ExternalObject[] children = externalLib.subnodes(parent);
> >>        for (int i = 0; i < children.length; i++)
> >>        {
> >>            if (children[i].equals(child)) {
> >>                return i;
> >>            };
> >>
> >>        }
> >>        return -1;
> >>     }
> >>
> >>   public void valueForPathChanged(TreePath path, Object newValue)
> >>   {
> >>       ...
> >>   }
> >>
> >>   public Collection getTreeModelListeners()
> >>   {
> >>       ...
> >>   }
> >>}
> >>
> >>Simple enough, isn't it? But you tell me I can't use TreeModel anymore
> >>when using tree2. So any node object has to implement tree2.TreeNode. As
> >>I have no  access to the sorces of ExternalLib and ExternalObject and
> >>therefore can not implement interface tree2.TreeNode in the library I
> >>have to use a wrapper. Unfortunatelly I cannot use option 1 ans
> >>TreeNodeBase just operates on strings. Ok, so I have to implement
> >>tree2.TreeNode on my own:
> >>
> >>public class TreeNodeWrapper implements TreeNode
> >>{
> >>   private String identifier;
> >>   private ExternalObject node;
> >>   ExternalLib externalLib;
> >>
> >>   public TreeNodeWrapper(ExternalObject node, ExternalLib externalLib)
> >>   {
> >>       this.node = node;
> >>       this.externalLib = externalLib;
> >>   }
> >>
> >>   public boolean isLeaf()
> >>   {
> >>       return externalLib.testLeaf(node);
> >>   }
> >>
> >>   public void setLeaf(boolean leaf)
> >>   {
> >>       // don't know why this is in the interface
> >>       throw new UnsupportedOperationException();
> >>   }
> >>
> >>   public List getChildren()
> >>   {
> >>       ExternalObject[] children = externalLib.subnodes(parent);
> >>       ArrayList answer = new ArrayList(children.length);
> >>
> >>       for (int i = 0; i < children.length; i++)
> >>       {
> >>           answer.add(new TreeNodeWrapper(children[i], externalLib));
> >>// <= EXTRA OBJECT HERE ###############
> >>       }
> >>
> >>       return answer;
> >>   }
> >>
> >>   public String getType()
> >>   {
> >>       return node.getTypeName();
> >>   }
> >>
> >>   public void setType(String type)
> >>   {
> >>       // don't know why this is in the interface
> >>       throw new UnsupportedOperationException();
> >>   }
> >>
> >>   public void setDescription(String description)
> >>   {
> >>       // don't know why this is in the interface
> >>       throw new UnsupportedOperationException();
> >>   }
> >>
> >>   public String getDescription()
> >>   {
> >>       return node.getLabel();
> >>   }
> >>
> >>   public void setIdentifier(String identifier)
> >>   {
> >>       this.identifier = identifier;
> >>   }
> >>
> >>   public String getIdentifier()
> >>   {
> >>       return identifier;
> >>   }
> >>
> >>   public int getChildCount()
> >>   {
> >>       return externalLib.countSubnodes(node);
> >>   }
> >>}
> >>
> >>All right, complexity of this implementation is similar to the TreeModel
> >>implementation. But my main argument against your decistion to drop
> >>option 3 is the need for extra wrapper objects to fulfill the conctract
> >>(see method getChildren() above where any ExternalObject has to be put
> >>inside another wrapper object). Maybe you do not care about resource
> >>consumption but I do and I have to because the machines I have at hand
> >>are kind of limited in that aspect. So I don't like to be forced to
> >>waste memory just because you do not like the TreeModel interface and
> >>the programming model behind it. You say it's just an interface but you
> >>have to see the implications on possible implementations this change in
> >>interfaces has. That's what I'm talking about all the time.
> >>
> >>So please give option 3 back to users and change tree2 to take
> >>tree.model.TreeModel instances as it's value instead of tree2.TreeNode.
> >>Or show me a way to fulfill the tree2.TreeNode contract without the need
> >>for extra objects in the example above.
> >>
> >>Oliver
> >>
> >>
> >>
> >>>
> >>>
> >>>
> >>>>Exactly that's my argument: the TreeNodeBase instance is the extra
> >>>>object you force me to create!!! When implementing TreeModel there is no
> >>>>need for this extra object, I'm able to use just the 3rd party data
> >>>>objects, naked and unwrapped as I get the from the external library. I
> >>>>don't have to wrap them with DefaultMutableTreeNode or any other object.
> >>>>
> >>>>
> >>>>
> >>>>
> >>>I guarantee that your third party component is not returing objects
> >>>that implement TreeModel.  That is my point.  I think you are getting
> >>>hung up on the wording of TreeModel vs. TreeNode.  The current tree
> >>>needs to make the raw data compliant with what the component expects
> >>>(TreeModel).  The new tree does the same thing but calls it something
> >>>different (TreeNode.)   The current tree also has a TreeNode interface
> >>>and you say that its not required to use the tree.  That's fine.  I
> >>>won't argue that point.
> >>>
> >>>To summarize, the current tree requires that data be adapted to the
> >>>TreeModel interface.  The new tree requires that data be adapted to
> >>>the TreeNode interface.  The fact that I am calling it TreeNode
> >>>instead of TreeModel does not make it any more difficult for the user
> >>>to implement.  The new tree also has a TreeModel class.  A difference
> >>>in the new implementation is that the model stuff is handled behind
> >>>the scenes.  There is no need for the user to provide their own model.
> >>>We could look at changing that but basically its already possible to
> >>>provide your own models by extending the TreeModel class.
> >>>
> >>>Please take another look at how I am using TreeNode and TreeModel.  If
> >>>you think its important that the user can provide their own models
> >>>then lets explore that!  Maybe this is the nature of your objection.
> >>>If so, I'm happy to work with you on that.
> >>>
> >>>I think some of the confusion is over the changes in implementation.
> >>>This is primarily a difference of opinion between the two of us.  It
> >>>doesn't affect the users.  Most users are going to use
> >>>DefaultMutableTreeNode as you do in your example or TreeNodeBase as I
> >>>do in my example.
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>>Again you seem to ignore my argument. I'm not talking about
> >>>>expanded/collapsed state but about SELECTED nodes. Take the tree example
> >>>>in the examples webapp. When you click the text of the root node it will
> >>>>get bold as the root node is the selected node now. Go on and expand
> >>>>some of the children and click the text of one of the child nodes: again
> >>>>the text will get bold to mark the selected node. At any time it is
> >>>>possible to ask the current tree for the path to the node currently
> >>>>selected. In tree2 the component itself does not care about that so I
> >>>>have to implement that feature on my own. It can be done using some
> >>>>specific command links and actions but I think to keep track of a
> >>>>selected node is a feature so common to tree components that is should
> >>>>be implemented there.
> >>>>
> >>>>
> >>>>
> >>>>
> >>>This is the kind of specific use case that I have been asking you to
> >>>provide.  Until now you just kept telling me that the new tree could
> >>>not handle selection.  Now I see what you mean by selection.  Let me
> >>>see if I can't address it in the new tree.  I will get back to you on
> >>>this one.
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>>Actually that's what I'm doing I suppose: to talk about features that
> >>>>are missing for tree2. But you have to be open for the fact that there
> >>>>are other scenarios and applications than the one you have in mind. I
> >>>>understand that your effort is driven by the requirements of the project
> >>>>you are currently working on. The current tree component has it's origin
> >>>>in a similar effort. To get a general-purpose tree component we have to
> >>>>address the issues I brought on the table. Otherwise we end up with two
> >>>>tree implementations which have something in common but miss some
> >>>>feature the other implementation has and vice versa. This can not be the
> >>>>goal if you ask me.
> >>>>
> >>>>
> >>>>
> >>>>
> >>>I agree we need to address these issues.  In order to do that, I need
> >>>specifics.  I will look into the selection issue as you have asked.  I
> >>>think I can work something out on that one.  As for the interface
> >>>issue, please take another look at my reasoning on that.  If you want
> >>>the ability to provide your own TreeModel then maybe that's something
> >>>we can do (although I don't think its necessary.)
> >>>
> >>>Believe it or not I think we are making progress.  I now know what you
> >>>mean by the selection problem.  So we are 50% there.  Lets see if we
> >>>can't reach an understanding on the inteface issue.
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>>Oliver
> >>>>
> >>>>
> >>>>
> >>>>
> >>>sean
> >>>
> >>>
> >>>
> >>>
> >>--
> >>Oliver Rossmueller
> >>Software Engineer and IT-Consultant
> >>Hamburg, Germany
> >>http://www.rossmueller.com
> >>
> >>
> >>
> >>
> 
> --
> Oliver Rossmueller
> Software Engineer and IT-Consultant
> Hamburg, Germany
> http://www.rossmueller.com
> 
>

Re: Tree2

Posted by Oliver Rossmueller <ol...@tuxerra.com>.
Sean,

you do not accept my argument that the wrapper objects I would need 
following your programming model waste memory. That's fine for me. But 
tell you what: I do not accept your argument that implementing TreeModel 
is a special case nobody else is using. My colleagues and I have 
implemented TreeModel variants for dozens of Swing applications to save 
memory resources. Of course you can do without your own implementation 
by using DefaultTreeModel. But - accept it or not - memory consumption 
matters for some people out there. So don't wipe this argument from the 
table like it's not there.

I'll tell you how we are going to resolve this: when you came along with 
the idea for an improved tree component I told you we can get all the 
requirements you are looking for by refactoring the existing tree 
component. You choose the revolutionary approach and started your own 
component from scratch. That's just fine for me but now I'm going to try 
the evolutionary approach by refactoring the existing tree and 
incorporating new functionality from tree2. I'm quite sure this can be 
done without breaking existing code. As I have other stuff to work on, 
too, this will not be finished within the next few days. Anyway it 
should be worth the time as we'll end up with one tree component and 
without the need for a legacy package.

In the meantime if there will be a MyFaces release we should mark tree2 
as experimental and tell anybody that he's using this component at his 
own risk.

Oliver


Sean Schofield wrote:

>Oliver,
>
>You are correct that option 3 is missing in the new tree and that its
>present in JTree and the current tree.  This was not designed to
>intentionally deprive you of functionality that you need in your
>application.  It didn't really occur to me that tree should support
>this kind of functionality.
>
>You must admit that your situation is a pretty specialized case.  How
>many MyFaces users are using third party components that provide tree
>data via a model?  My guess is that most are pulling the data
>themselves from LDAP or a database and they are using either options 1
>or 2 which tree2 can handle.
>
>You are basically asking for the ability to plug a third party data
>model directly into the tree without wrapping the objects with an
>adapter, etc. to conform to TreeNode interface.  I definitely think
>that it is acceptable to wrap your data with a very *light* object
>that can provide this functionality.  I do not accept your argument
>that this wastes precious memory.  The adapter pattern is a standard
>practice and is done all the time without crashing servers.  I agree
>that in your case it would be a hassle to change the code but lets not
>overstate the ramifications of this solution.
>
>Your code sample where you show how you could use tree2 right now
>seems perfectly fine to me.  I recall that you are using the
>server-side expansion control now because you have too much data to
>push to the client at once.  This makes the wrapping of your
>components even less burdensome.
>
>Since there seems to be some concern about losing this functionality,
>I would propose that we consider keeping the original tree but moving
>it to a legacy package name and give it a tag like <treeLegacy>.  Also
>we should deprecate the current tree classes.  Since it looks like a
>release will be coming soon I think this is the best short-term
>solution.
>
>Then you and I can explore the possibility of providing option 3
>functionality in a future release.
>
>What do you think about that?  I take it you have no other concerns at
>this point other than option 3 functionality.  Is that correct?
>
>sean
>
>
>On Sat, 12 Mar 2005 14:22:55 +0100, Oliver Rossmueller
><ol...@tuxerra.com> wrote:
>  
>
>>Sean Schofield wrote:
>>
>>    
>>
>>><snip>
>>>
>>>Yes you are repeating yourself over and over on this point.  I do not
>>>see how tree2 has changed the basic requirments of the user.  You keep
>>>saying that I am against TreeModel and for TreeNode.  That is not the
>>>case.  Let me try to phrase my argument differently ...
>>>
>>>You are correct that JTree operates on a TreeModel instance.  It also
>>>has TreeNode interface.  Data is first wrapped in TreeNode instance
>>>before being added to the model.  See this example from Sun's JTree
>>>example:
>>>
>>>rootNode = new DefaultMutableTreeNode("Root Node");
>>>treeModel = new DefaultTreeModel(rootNode);
>>>treeModel.addTreeModelListener(new MyTreeModelListener());
>>>tree = new JTree(treeModel);
>>>
>>>You are correct that JTree does not require a TreeNode interface.  I
>>>agree with you there.  JTree does require a *different* interface,
>>>however, and that interface is TreeModel.  You cannot just add some
>>>arbitrary String "Foo" to a JTree.  How would the tree know what to do
>>>with it?  Is this string a leaf or not?  How can you add children to a
>>>String?  You have two choices.  First choice is to use
>>>DefaultMutableTreeNode and DefaultTreeModel (as shown above.)  That
>>>option *requires* TreeNode.  Second choice is to write your own class
>>>that implements TreeModel.  Either way, you cannot just add an
>>>arbitrary String to a JTree.
>>>
>>>Again, I urge us not to think in terms of JTree.  Lets leave JTree out
>>>of this for now.  Lets just talk about the shortcomings of tree2.  If
>>>we can address those then we can move forward.  IMO discussing JTree
>>>is not helpful in reaching consensus on this.
>>>
>>>
>>>      
>>>
>>The point is not JTree but the options the user has in providing data:
>>
>>Option 1: Use DefaultTreeModel and wrap your node objects using
>>DefaultMutableTreeNode
>>
>>Option 2: Use DefaultTreeModel and have your node objects implement
>>interface TreeNode
>>
>>Option 3: Implement interface TreeModel on your own
>>
>>As the current tree component's design closely follows JTree you have
>>the same three options:
>>
>>Option 1: Use DefaultTreeModel and wrap your node objects using
>>DefaultMutableTreeNode
>>
>>Option 2: Use DefaultTreeModel and have your node objects implement
>>interface TreeNode
>>
>>Option 3: Implement interface TreeModel on your own
>>
>>Now you say we do not need option 3 anymore, so tree2 only has
>>
>>Option 1: Use TreeNodeBase to wrap your node objects
>>
>>Option 2: Have your node objects implement interface tree2.TreeNode
>>
>>As you kicked away the TreeModel interface (your TreeModel class is just
>>an implementation-specific internal helper for HtmlTree as I see it) I
>>no longer have the option to implement TreeModel on my own. But named
>>option 3 is a crucial option and it's absence is an absolute show
>>stopper for me. As words seem not to work out in explaining my argument
>>I'll try it with an example this time. It follows the scenario using the
>>3rd party library already mentioned before.
>>
>>So at the moment I have an implementation of interface TreeModel which
>>looks somewhat like the following:
>>
>>public class MyTreeModel implements TreeModel
>>{
>>
>>   private ExternalLib externalLib = new ExternalLib();
>>
>>   public Object getRoot()
>>   {
>>       return externalLib.top();
>>   }
>>
>>   public Object getChild(Object parent, int index)
>>   {
>>       ExternalObject[] children = externalLib.subnodes(parent);
>>       return children[index];
>>   }
>>
>>   public int getChildCount(Object parent)
>>   {
>>       return externalLib.countSubnodes(parent);
>>   }
>>
>>   public boolean isLeaf(Object node)
>>   {
>>       return externalLib.testLeaf(node);
>>   }
>>
>>   public int getIndexOfChild(Object parent, Object child)
>>    {
>>        ExternalObject[] children = externalLib.subnodes(parent);
>>        for (int i = 0; i < children.length; i++)
>>        {
>>            if (children[i].equals(child)) {
>>                return i;
>>            };
>>
>>        }
>>        return -1;
>>     }
>>
>>   public void valueForPathChanged(TreePath path, Object newValue)
>>   {
>>       ...
>>   }
>>
>>   public Collection getTreeModelListeners()
>>   {
>>       ...
>>   }
>>}
>>
>>Simple enough, isn't it? But you tell me I can't use TreeModel anymore
>>when using tree2. So any node object has to implement tree2.TreeNode. As
>>I have no  access to the sorces of ExternalLib and ExternalObject and
>>therefore can not implement interface tree2.TreeNode in the library I
>>have to use a wrapper. Unfortunatelly I cannot use option 1 ans
>>TreeNodeBase just operates on strings. Ok, so I have to implement
>>tree2.TreeNode on my own:
>>
>>public class TreeNodeWrapper implements TreeNode
>>{
>>   private String identifier;
>>   private ExternalObject node;
>>   ExternalLib externalLib;
>>
>>   public TreeNodeWrapper(ExternalObject node, ExternalLib externalLib)
>>   {
>>       this.node = node;
>>       this.externalLib = externalLib;
>>   }
>>
>>   public boolean isLeaf()
>>   {
>>       return externalLib.testLeaf(node);
>>   }
>>
>>   public void setLeaf(boolean leaf)
>>   {
>>       // don't know why this is in the interface
>>       throw new UnsupportedOperationException();
>>   }
>>
>>   public List getChildren()
>>   {
>>       ExternalObject[] children = externalLib.subnodes(parent);
>>       ArrayList answer = new ArrayList(children.length);
>>
>>       for (int i = 0; i < children.length; i++)
>>       {
>>           answer.add(new TreeNodeWrapper(children[i], externalLib));
>>// <= EXTRA OBJECT HERE ###############
>>       }
>>
>>       return answer;
>>   }
>>
>>   public String getType()
>>   {
>>       return node.getTypeName();
>>   }
>>
>>   public void setType(String type)
>>   {
>>       // don't know why this is in the interface
>>       throw new UnsupportedOperationException();
>>   }
>>
>>   public void setDescription(String description)
>>   {
>>       // don't know why this is in the interface
>>       throw new UnsupportedOperationException();
>>   }
>>
>>   public String getDescription()
>>   {
>>       return node.getLabel();
>>   }
>>
>>   public void setIdentifier(String identifier)
>>   {
>>       this.identifier = identifier;
>>   }
>>
>>   public String getIdentifier()
>>   {
>>       return identifier;
>>   }
>>
>>   public int getChildCount()
>>   {
>>       return externalLib.countSubnodes(node);
>>   }
>>}
>>
>>All right, complexity of this implementation is similar to the TreeModel
>>implementation. But my main argument against your decistion to drop
>>option 3 is the need for extra wrapper objects to fulfill the conctract
>>(see method getChildren() above where any ExternalObject has to be put
>>inside another wrapper object). Maybe you do not care about resource
>>consumption but I do and I have to because the machines I have at hand
>>are kind of limited in that aspect. So I don't like to be forced to
>>waste memory just because you do not like the TreeModel interface and
>>the programming model behind it. You say it's just an interface but you
>>have to see the implications on possible implementations this change in
>>interfaces has. That's what I'm talking about all the time.
>>
>>So please give option 3 back to users and change tree2 to take
>>tree.model.TreeModel instances as it's value instead of tree2.TreeNode.
>>Or show me a way to fulfill the tree2.TreeNode contract without the need
>>for extra objects in the example above.
>>
>>Oliver
>>
>>    
>>
>>>
>>>      
>>>
>>>>Exactly that's my argument: the TreeNodeBase instance is the extra
>>>>object you force me to create!!! When implementing TreeModel there is no
>>>>need for this extra object, I'm able to use just the 3rd party data
>>>>objects, naked and unwrapped as I get the from the external library. I
>>>>don't have to wrap them with DefaultMutableTreeNode or any other object.
>>>>
>>>>
>>>>        
>>>>
>>>I guarantee that your third party component is not returing objects
>>>that implement TreeModel.  That is my point.  I think you are getting
>>>hung up on the wording of TreeModel vs. TreeNode.  The current tree
>>>needs to make the raw data compliant with what the component expects
>>>(TreeModel).  The new tree does the same thing but calls it something
>>>different (TreeNode.)   The current tree also has a TreeNode interface
>>>and you say that its not required to use the tree.  That's fine.  I
>>>won't argue that point.
>>>
>>>To summarize, the current tree requires that data be adapted to the
>>>TreeModel interface.  The new tree requires that data be adapted to
>>>the TreeNode interface.  The fact that I am calling it TreeNode
>>>instead of TreeModel does not make it any more difficult for the user
>>>to implement.  The new tree also has a TreeModel class.  A difference
>>>in the new implementation is that the model stuff is handled behind
>>>the scenes.  There is no need for the user to provide their own model.
>>>We could look at changing that but basically its already possible to
>>>provide your own models by extending the TreeModel class.
>>>
>>>Please take another look at how I am using TreeNode and TreeModel.  If
>>>you think its important that the user can provide their own models
>>>then lets explore that!  Maybe this is the nature of your objection.
>>>If so, I'm happy to work with you on that.
>>>
>>>I think some of the confusion is over the changes in implementation.
>>>This is primarily a difference of opinion between the two of us.  It
>>>doesn't affect the users.  Most users are going to use
>>>DefaultMutableTreeNode as you do in your example or TreeNodeBase as I
>>>do in my example.
>>>
>>>
>>>
>>>      
>>>
>>>>Again you seem to ignore my argument. I'm not talking about
>>>>expanded/collapsed state but about SELECTED nodes. Take the tree example
>>>>in the examples webapp. When you click the text of the root node it will
>>>>get bold as the root node is the selected node now. Go on and expand
>>>>some of the children and click the text of one of the child nodes: again
>>>>the text will get bold to mark the selected node. At any time it is
>>>>possible to ask the current tree for the path to the node currently
>>>>selected. In tree2 the component itself does not care about that so I
>>>>have to implement that feature on my own. It can be done using some
>>>>specific command links and actions but I think to keep track of a
>>>>selected node is a feature so common to tree components that is should
>>>>be implemented there.
>>>>
>>>>
>>>>        
>>>>
>>>This is the kind of specific use case that I have been asking you to
>>>provide.  Until now you just kept telling me that the new tree could
>>>not handle selection.  Now I see what you mean by selection.  Let me
>>>see if I can't address it in the new tree.  I will get back to you on
>>>this one.
>>>
>>>
>>>
>>>      
>>>
>>>>Actually that's what I'm doing I suppose: to talk about features that
>>>>are missing for tree2. But you have to be open for the fact that there
>>>>are other scenarios and applications than the one you have in mind. I
>>>>understand that your effort is driven by the requirements of the project
>>>>you are currently working on. The current tree component has it's origin
>>>>in a similar effort. To get a general-purpose tree component we have to
>>>>address the issues I brought on the table. Otherwise we end up with two
>>>>tree implementations which have something in common but miss some
>>>>feature the other implementation has and vice versa. This can not be the
>>>>goal if you ask me.
>>>>
>>>>
>>>>        
>>>>
>>>I agree we need to address these issues.  In order to do that, I need
>>>specifics.  I will look into the selection issue as you have asked.  I
>>>think I can work something out on that one.  As for the interface
>>>issue, please take another look at my reasoning on that.  If you want
>>>the ability to provide your own TreeModel then maybe that's something
>>>we can do (although I don't think its necessary.)
>>>
>>>Believe it or not I think we are making progress.  I now know what you
>>>mean by the selection problem.  So we are 50% there.  Lets see if we
>>>can't reach an understanding on the inteface issue.
>>>
>>>
>>>
>>>      
>>>
>>>>Oliver
>>>>
>>>>
>>>>        
>>>>
>>>sean
>>>
>>>
>>>      
>>>
>>--
>>Oliver Rossmueller
>>Software Engineer and IT-Consultant
>>Hamburg, Germany
>>http://www.rossmueller.com
>>
>>
>>    
>>


-- 
Oliver Rossmueller
Software Engineer and IT-Consultant
Hamburg, Germany
http://www.rossmueller.com


Re: Tree2

Posted by Sean Schofield <se...@gmail.com>.
Oliver,

You are correct that option 3 is missing in the new tree and that its
present in JTree and the current tree.  This was not designed to
intentionally deprive you of functionality that you need in your
application.  It didn't really occur to me that tree should support
this kind of functionality.

You must admit that your situation is a pretty specialized case.  How
many MyFaces users are using third party components that provide tree
data via a model?  My guess is that most are pulling the data
themselves from LDAP or a database and they are using either options 1
or 2 which tree2 can handle.

You are basically asking for the ability to plug a third party data
model directly into the tree without wrapping the objects with an
adapter, etc. to conform to TreeNode interface.  I definitely think
that it is acceptable to wrap your data with a very *light* object
that can provide this functionality.  I do not accept your argument
that this wastes precious memory.  The adapter pattern is a standard
practice and is done all the time without crashing servers.  I agree
that in your case it would be a hassle to change the code but lets not
overstate the ramifications of this solution.

Your code sample where you show how you could use tree2 right now
seems perfectly fine to me.  I recall that you are using the
server-side expansion control now because you have too much data to
push to the client at once.  This makes the wrapping of your
components even less burdensome.

Since there seems to be some concern about losing this functionality,
I would propose that we consider keeping the original tree but moving
it to a legacy package name and give it a tag like <treeLegacy>.  Also
we should deprecate the current tree classes.  Since it looks like a
release will be coming soon I think this is the best short-term
solution.

Then you and I can explore the possibility of providing option 3
functionality in a future release.

What do you think about that?  I take it you have no other concerns at
this point other than option 3 functionality.  Is that correct?

sean


On Sat, 12 Mar 2005 14:22:55 +0100, Oliver Rossmueller
<ol...@tuxerra.com> wrote:
> Sean Schofield wrote:
> 
> > <snip>
> >
> >Yes you are repeating yourself over and over on this point.  I do not
> >see how tree2 has changed the basic requirments of the user.  You keep
> >saying that I am against TreeModel and for TreeNode.  That is not the
> >case.  Let me try to phrase my argument differently ...
> >
> >You are correct that JTree operates on a TreeModel instance.  It also
> >has TreeNode interface.  Data is first wrapped in TreeNode instance
> >before being added to the model.  See this example from Sun's JTree
> >example:
> >
> >rootNode = new DefaultMutableTreeNode("Root Node");
> >treeModel = new DefaultTreeModel(rootNode);
> >treeModel.addTreeModelListener(new MyTreeModelListener());
> >tree = new JTree(treeModel);
> >
> >You are correct that JTree does not require a TreeNode interface.  I
> >agree with you there.  JTree does require a *different* interface,
> >however, and that interface is TreeModel.  You cannot just add some
> >arbitrary String "Foo" to a JTree.  How would the tree know what to do
> >with it?  Is this string a leaf or not?  How can you add children to a
> >String?  You have two choices.  First choice is to use
> >DefaultMutableTreeNode and DefaultTreeModel (as shown above.)  That
> >option *requires* TreeNode.  Second choice is to write your own class
> >that implements TreeModel.  Either way, you cannot just add an
> >arbitrary String to a JTree.
> >
> >Again, I urge us not to think in terms of JTree.  Lets leave JTree out
> >of this for now.  Lets just talk about the shortcomings of tree2.  If
> >we can address those then we can move forward.  IMO discussing JTree
> >is not helpful in reaching consensus on this.
> >
> >
> The point is not JTree but the options the user has in providing data:
> 
> Option 1: Use DefaultTreeModel and wrap your node objects using
> DefaultMutableTreeNode
> 
> Option 2: Use DefaultTreeModel and have your node objects implement
> interface TreeNode
> 
> Option 3: Implement interface TreeModel on your own
> 
> As the current tree component's design closely follows JTree you have
> the same three options:
> 
> Option 1: Use DefaultTreeModel and wrap your node objects using
> DefaultMutableTreeNode
> 
> Option 2: Use DefaultTreeModel and have your node objects implement
> interface TreeNode
> 
> Option 3: Implement interface TreeModel on your own
> 
> Now you say we do not need option 3 anymore, so tree2 only has
> 
> Option 1: Use TreeNodeBase to wrap your node objects
> 
> Option 2: Have your node objects implement interface tree2.TreeNode
> 
> As you kicked away the TreeModel interface (your TreeModel class is just
> an implementation-specific internal helper for HtmlTree as I see it) I
> no longer have the option to implement TreeModel on my own. But named
> option 3 is a crucial option and it's absence is an absolute show
> stopper for me. As words seem not to work out in explaining my argument
> I'll try it with an example this time. It follows the scenario using the
> 3rd party library already mentioned before.
> 
> So at the moment I have an implementation of interface TreeModel which
> looks somewhat like the following:
> 
> public class MyTreeModel implements TreeModel
> {
> 
>    private ExternalLib externalLib = new ExternalLib();
> 
>    public Object getRoot()
>    {
>        return externalLib.top();
>    }
> 
>    public Object getChild(Object parent, int index)
>    {
>        ExternalObject[] children = externalLib.subnodes(parent);
>        return children[index];
>    }
> 
>    public int getChildCount(Object parent)
>    {
>        return externalLib.countSubnodes(parent);
>    }
> 
>    public boolean isLeaf(Object node)
>    {
>        return externalLib.testLeaf(node);
>    }
> 
>    public int getIndexOfChild(Object parent, Object child)
>     {
>         ExternalObject[] children = externalLib.subnodes(parent);
>         for (int i = 0; i < children.length; i++)
>         {
>             if (children[i].equals(child)) {
>                 return i;
>             };
> 
>         }
>         return -1;
>      }
> 
>    public void valueForPathChanged(TreePath path, Object newValue)
>    {
>        ...
>    }
> 
>    public Collection getTreeModelListeners()
>    {
>        ...
>    }
> }
> 
> Simple enough, isn't it? But you tell me I can't use TreeModel anymore
> when using tree2. So any node object has to implement tree2.TreeNode. As
> I have no  access to the sorces of ExternalLib and ExternalObject and
> therefore can not implement interface tree2.TreeNode in the library I
> have to use a wrapper. Unfortunatelly I cannot use option 1 ans
> TreeNodeBase just operates on strings. Ok, so I have to implement
> tree2.TreeNode on my own:
> 
> public class TreeNodeWrapper implements TreeNode
> {
>    private String identifier;
>    private ExternalObject node;
>    ExternalLib externalLib;
> 
>    public TreeNodeWrapper(ExternalObject node, ExternalLib externalLib)
>    {
>        this.node = node;
>        this.externalLib = externalLib;
>    }
> 
>    public boolean isLeaf()
>    {
>        return externalLib.testLeaf(node);
>    }
> 
>    public void setLeaf(boolean leaf)
>    {
>        // don't know why this is in the interface
>        throw new UnsupportedOperationException();
>    }
> 
>    public List getChildren()
>    {
>        ExternalObject[] children = externalLib.subnodes(parent);
>        ArrayList answer = new ArrayList(children.length);
> 
>        for (int i = 0; i < children.length; i++)
>        {
>            answer.add(new TreeNodeWrapper(children[i], externalLib));
> // <= EXTRA OBJECT HERE ###############
>        }
> 
>        return answer;
>    }
> 
>    public String getType()
>    {
>        return node.getTypeName();
>    }
> 
>    public void setType(String type)
>    {
>        // don't know why this is in the interface
>        throw new UnsupportedOperationException();
>    }
> 
>    public void setDescription(String description)
>    {
>        // don't know why this is in the interface
>        throw new UnsupportedOperationException();
>    }
> 
>    public String getDescription()
>    {
>        return node.getLabel();
>    }
> 
>    public void setIdentifier(String identifier)
>    {
>        this.identifier = identifier;
>    }
> 
>    public String getIdentifier()
>    {
>        return identifier;
>    }
> 
>    public int getChildCount()
>    {
>        return externalLib.countSubnodes(node);
>    }
> }
> 
> All right, complexity of this implementation is similar to the TreeModel
> implementation. But my main argument against your decistion to drop
> option 3 is the need for extra wrapper objects to fulfill the conctract
> (see method getChildren() above where any ExternalObject has to be put
> inside another wrapper object). Maybe you do not care about resource
> consumption but I do and I have to because the machines I have at hand
> are kind of limited in that aspect. So I don't like to be forced to
> waste memory just because you do not like the TreeModel interface and
> the programming model behind it. You say it's just an interface but you
> have to see the implications on possible implementations this change in
> interfaces has. That's what I'm talking about all the time.
> 
> So please give option 3 back to users and change tree2 to take
> tree.model.TreeModel instances as it's value instead of tree2.TreeNode.
> Or show me a way to fulfill the tree2.TreeNode contract without the need
> for extra objects in the example above.
> 
> Oliver
> 
> >
> >
> >
> >>Exactly that's my argument: the TreeNodeBase instance is the extra
> >>object you force me to create!!! When implementing TreeModel there is no
> >>need for this extra object, I'm able to use just the 3rd party data
> >>objects, naked and unwrapped as I get the from the external library. I
> >>don't have to wrap them with DefaultMutableTreeNode or any other object.
> >>
> >>
> >
> >I guarantee that your third party component is not returing objects
> >that implement TreeModel.  That is my point.  I think you are getting
> >hung up on the wording of TreeModel vs. TreeNode.  The current tree
> >needs to make the raw data compliant with what the component expects
> >(TreeModel).  The new tree does the same thing but calls it something
> >different (TreeNode.)   The current tree also has a TreeNode interface
> >and you say that its not required to use the tree.  That's fine.  I
> >won't argue that point.
> >
> >To summarize, the current tree requires that data be adapted to the
> >TreeModel interface.  The new tree requires that data be adapted to
> >the TreeNode interface.  The fact that I am calling it TreeNode
> >instead of TreeModel does not make it any more difficult for the user
> >to implement.  The new tree also has a TreeModel class.  A difference
> >in the new implementation is that the model stuff is handled behind
> >the scenes.  There is no need for the user to provide their own model.
> > We could look at changing that but basically its already possible to
> >provide your own models by extending the TreeModel class.
> >
> >Please take another look at how I am using TreeNode and TreeModel.  If
> >you think its important that the user can provide their own models
> >then lets explore that!  Maybe this is the nature of your objection.
> >If so, I'm happy to work with you on that.
> >
> >I think some of the confusion is over the changes in implementation.
> >This is primarily a difference of opinion between the two of us.  It
> >doesn't affect the users.  Most users are going to use
> >DefaultMutableTreeNode as you do in your example or TreeNodeBase as I
> >do in my example.
> >
> >
> >
> >>Again you seem to ignore my argument. I'm not talking about
> >>expanded/collapsed state but about SELECTED nodes. Take the tree example
> >>in the examples webapp. When you click the text of the root node it will
> >>get bold as the root node is the selected node now. Go on and expand
> >>some of the children and click the text of one of the child nodes: again
> >>the text will get bold to mark the selected node. At any time it is
> >>possible to ask the current tree for the path to the node currently
> >>selected. In tree2 the component itself does not care about that so I
> >>have to implement that feature on my own. It can be done using some
> >>specific command links and actions but I think to keep track of a
> >>selected node is a feature so common to tree components that is should
> >>be implemented there.
> >>
> >>
> >
> >This is the kind of specific use case that I have been asking you to
> >provide.  Until now you just kept telling me that the new tree could
> >not handle selection.  Now I see what you mean by selection.  Let me
> >see if I can't address it in the new tree.  I will get back to you on
> >this one.
> >
> >
> >
> >>Actually that's what I'm doing I suppose: to talk about features that
> >>are missing for tree2. But you have to be open for the fact that there
> >>are other scenarios and applications than the one you have in mind. I
> >>understand that your effort is driven by the requirements of the project
> >>you are currently working on. The current tree component has it's origin
> >>in a similar effort. To get a general-purpose tree component we have to
> >>address the issues I brought on the table. Otherwise we end up with two
> >>tree implementations which have something in common but miss some
> >>feature the other implementation has and vice versa. This can not be the
> >>goal if you ask me.
> >>
> >>
> >
> >I agree we need to address these issues.  In order to do that, I need
> >specifics.  I will look into the selection issue as you have asked.  I
> >think I can work something out on that one.  As for the interface
> >issue, please take another look at my reasoning on that.  If you want
> >the ability to provide your own TreeModel then maybe that's something
> >we can do (although I don't think its necessary.)
> >
> >Believe it or not I think we are making progress.  I now know what you
> >mean by the selection problem.  So we are 50% there.  Lets see if we
> >can't reach an understanding on the inteface issue.
> >
> >
> >
> >>Oliver
> >>
> >>
> >
> >sean
> >
> >
> 
> --
> Oliver Rossmueller
> Software Engineer and IT-Consultant
> Hamburg, Germany
> http://www.rossmueller.com
> 
>

Re: Tree2

Posted by Oliver Rossmueller <ol...@tuxerra.com>.
Sean Schofield wrote:

> <snip>
>
>Yes you are repeating yourself over and over on this point.  I do not
>see how tree2 has changed the basic requirments of the user.  You keep
>saying that I am against TreeModel and for TreeNode.  That is not the
>case.  Let me try to phrase my argument differently ...
>
>You are correct that JTree operates on a TreeModel instance.  It also
>has TreeNode interface.  Data is first wrapped in TreeNode instance
>before being added to the model.  See this example from Sun's JTree
>example:
>
>rootNode = new DefaultMutableTreeNode("Root Node");
>treeModel = new DefaultTreeModel(rootNode);
>treeModel.addTreeModelListener(new MyTreeModelListener());
>tree = new JTree(treeModel);
>
>You are correct that JTree does not require a TreeNode interface.  I
>agree with you there.  JTree does require a *different* interface,
>however, and that interface is TreeModel.  You cannot just add some
>arbitrary String "Foo" to a JTree.  How would the tree know what to do
>with it?  Is this string a leaf or not?  How can you add children to a
>String?  You have two choices.  First choice is to use
>DefaultMutableTreeNode and DefaultTreeModel (as shown above.)  That
>option *requires* TreeNode.  Second choice is to write your own class
>that implements TreeModel.  Either way, you cannot just add an
>arbitrary String to a JTree.
>
>Again, I urge us not to think in terms of JTree.  Lets leave JTree out
>of this for now.  Lets just talk about the shortcomings of tree2.  If
>we can address those then we can move forward.  IMO discussing JTree
>is not helpful in reaching consensus on this.
>  
>
The point is not JTree but the options the user has in providing data:

Option 1: Use DefaultTreeModel and wrap your node objects using 
DefaultMutableTreeNode

Option 2: Use DefaultTreeModel and have your node objects implement 
interface TreeNode

Option 3: Implement interface TreeModel on your own


As the current tree component's design closely follows JTree you have 
the same three options:

Option 1: Use DefaultTreeModel and wrap your node objects using 
DefaultMutableTreeNode

Option 2: Use DefaultTreeModel and have your node objects implement 
interface TreeNode

Option 3: Implement interface TreeModel on your own


Now you say we do not need option 3 anymore, so tree2 only has

Option 1: Use TreeNodeBase to wrap your node objects

Option 2: Have your node objects implement interface tree2.TreeNode

As you kicked away the TreeModel interface (your TreeModel class is just 
an implementation-specific internal helper for HtmlTree as I see it) I 
no longer have the option to implement TreeModel on my own. But named 
option 3 is a crucial option and it's absence is an absolute show 
stopper for me. As words seem not to work out in explaining my argument 
I'll try it with an example this time. It follows the scenario using the 
3rd party library already mentioned before.

So at the moment I have an implementation of interface TreeModel which 
looks somewhat like the following:

public class MyTreeModel implements TreeModel
{

    private ExternalLib externalLib = new ExternalLib();


    public Object getRoot()
    {
        return externalLib.top();
    }


    public Object getChild(Object parent, int index)
    {
        ExternalObject[] children = externalLib.subnodes(parent);
        return children[index];
    }


    public int getChildCount(Object parent)
    {
        return externalLib.countSubnodes(parent);
    }


    public boolean isLeaf(Object node)
    {
        return externalLib.testLeaf(node);
    }

    public int getIndexOfChild(Object parent, Object child)
     {
         ExternalObject[] children = externalLib.subnodes(parent);
         for (int i = 0; i < children.length; i++)
         {
             if (children[i].equals(child)) {
                 return i;
             };

         }
         return -1;
      }


    public void valueForPathChanged(TreePath path, Object newValue)
    {
        ...
    }


    public Collection getTreeModelListeners()
    {
        ...
    }
}


Simple enough, isn't it? But you tell me I can't use TreeModel anymore 
when using tree2. So any node object has to implement tree2.TreeNode. As 
I have no  access to the sorces of ExternalLib and ExternalObject and 
therefore can not implement interface tree2.TreeNode in the library I 
have to use a wrapper. Unfortunatelly I cannot use option 1 ans 
TreeNodeBase just operates on strings. Ok, so I have to implement 
tree2.TreeNode on my own:

public class TreeNodeWrapper implements TreeNode
{
    private String identifier;
    private ExternalObject node;
    ExternalLib externalLib;
   
   
    public TreeNodeWrapper(ExternalObject node, ExternalLib externalLib)
    {
        this.node = node;
        this.externalLib = externalLib;
    }
   
    public boolean isLeaf()
    {
        return externalLib.testLeaf(node);
    }
   
    public void setLeaf(boolean leaf)
    {
        // don't know why this is in the interface
        throw new UnsupportedOperationException();
    }

    public List getChildren()
    {
        ExternalObject[] children = externalLib.subnodes(parent);
        ArrayList answer = new ArrayList(children.length);
       
        for (int i = 0; i < children.length; i++)
        {
            answer.add(new TreeNodeWrapper(children[i], externalLib));  
// <= EXTRA OBJECT HERE ###############
        }
       
        return answer;
    }

    public String getType()
    {
        return node.getTypeName();
    }

    public void setType(String type)
    {
        // don't know why this is in the interface
        throw new UnsupportedOperationException();
    }   
   
   
    public void setDescription(String description)
    {
        // don't know why this is in the interface
        throw new UnsupportedOperationException();
    }
   
    public String getDescription()
    {
        return node.getLabel();
    }
   
    public void setIdentifier(String identifier)
    {
        this.identifier = identifier;
    }
   
    public String getIdentifier()
    {
        return identifier;
    }
   
    public int getChildCount()
    {
        return externalLib.countSubnodes(node);
    }
}


All right, complexity of this implementation is similar to the TreeModel 
implementation. But my main argument against your decistion to drop 
option 3 is the need for extra wrapper objects to fulfill the conctract 
(see method getChildren() above where any ExternalObject has to be put 
inside another wrapper object). Maybe you do not care about resource 
consumption but I do and I have to because the machines I have at hand 
are kind of limited in that aspect. So I don't like to be forced to 
waste memory just because you do not like the TreeModel interface and 
the programming model behind it. You say it's just an interface but you 
have to see the implications on possible implementations this change in 
interfaces has. That's what I'm talking about all the time.

So please give option 3 back to users and change tree2 to take 
tree.model.TreeModel instances as it's value instead of tree2.TreeNode. 
Or show me a way to fulfill the tree2.TreeNode contract without the need 
for extra objects in the example above.

Oliver

> 
>  
>
>>Exactly that's my argument: the TreeNodeBase instance is the extra
>>object you force me to create!!! When implementing TreeModel there is no
>>need for this extra object, I'm able to use just the 3rd party data
>>objects, naked and unwrapped as I get the from the external library. I
>>don't have to wrap them with DefaultMutableTreeNode or any other object.
>>    
>>
>
>I guarantee that your third party component is not returing objects
>that implement TreeModel.  That is my point.  I think you are getting
>hung up on the wording of TreeModel vs. TreeNode.  The current tree
>needs to make the raw data compliant with what the component expects
>(TreeModel).  The new tree does the same thing but calls it something
>different (TreeNode.)   The current tree also has a TreeNode interface
>and you say that its not required to use the tree.  That's fine.  I
>won't argue that point.
>
>To summarize, the current tree requires that data be adapted to the
>TreeModel interface.  The new tree requires that data be adapted to
>the TreeNode interface.  The fact that I am calling it TreeNode
>instead of TreeModel does not make it any more difficult for the user
>to implement.  The new tree also has a TreeModel class.  A difference
>in the new implementation is that the model stuff is handled behind
>the scenes.  There is no need for the user to provide their own model.
> We could look at changing that but basically its already possible to
>provide your own models by extending the TreeModel class.
>
>Please take another look at how I am using TreeNode and TreeModel.  If
>you think its important that the user can provide their own models
>then lets explore that!  Maybe this is the nature of your objection. 
>If so, I'm happy to work with you on that.
>
>I think some of the confusion is over the changes in implementation. 
>This is primarily a difference of opinion between the two of us.  It
>doesn't affect the users.  Most users are going to use
>DefaultMutableTreeNode as you do in your example or TreeNodeBase as I
>do in my example.
> 
>  
>
>>Again you seem to ignore my argument. I'm not talking about
>>expanded/collapsed state but about SELECTED nodes. Take the tree example
>>in the examples webapp. When you click the text of the root node it will
>>get bold as the root node is the selected node now. Go on and expand
>>some of the children and click the text of one of the child nodes: again
>>the text will get bold to mark the selected node. At any time it is
>>possible to ask the current tree for the path to the node currently
>>selected. In tree2 the component itself does not care about that so I
>>have to implement that feature on my own. It can be done using some
>>specific command links and actions but I think to keep track of a
>>selected node is a feature so common to tree components that is should
>>be implemented there.
>>    
>>
>
>This is the kind of specific use case that I have been asking you to
>provide.  Until now you just kept telling me that the new tree could
>not handle selection.  Now I see what you mean by selection.  Let me
>see if I can't address it in the new tree.  I will get back to you on
>this one.
>
>  
>
>>Actually that's what I'm doing I suppose: to talk about features that
>>are missing for tree2. But you have to be open for the fact that there
>>are other scenarios and applications than the one you have in mind. I
>>understand that your effort is driven by the requirements of the project
>>you are currently working on. The current tree component has it's origin
>>in a similar effort. To get a general-purpose tree component we have to
>>address the issues I brought on the table. Otherwise we end up with two
>>tree implementations which have something in common but miss some
>>feature the other implementation has and vice versa. This can not be the
>>goal if you ask me.
>>    
>>
>
>I agree we need to address these issues.  In order to do that, I need
>specifics.  I will look into the selection issue as you have asked.  I
>think I can work something out on that one.  As for the interface
>issue, please take another look at my reasoning on that.  If you want
>the ability to provide your own TreeModel then maybe that's something
>we can do (although I don't think its necessary.)
> 
>Believe it or not I think we are making progress.  I now know what you
>mean by the selection problem.  So we are 50% there.  Lets see if we
>can't reach an understanding on the inteface issue.
>
>  
>
>>Oliver
>>    
>>
>
>sean
>  
>


-- 
Oliver Rossmueller
Software Engineer and IT-Consultant
Hamburg, Germany
http://www.rossmueller.com


Re: Tree2

Posted by Sean Schofield <se...@gmail.com>.
Oliver,

> I'm sorry but I feel somewhat like talking to stones at the moment :-(
> I'm repeating myself over and over again but you just seem to ignore my
> argument that TreeNode is nothing more than a helper interface to
> support the Swing JTree component. Please have a look at the sources if
> you don't beleave me but  JTree is operating on a TreeModel instance and
> TreeModel operates on any kind of objects not just TreeNode instances.
> JTree is not relying on the node objects implementing any specific
> interface, nowhere! The same is true for the current tree component.  In
> my opinion TreeModel is the more flexible, lightweight and
> resource-saving approach and so far I did not get an idea what your
> argument is against TreeModel and for TreeNode. Your decision to force
> the user to implement TreeNode for all of his node objects is no
> improvement but a step backwards from my POV.

Yes you are repeating yourself over and over on this point.  I do not
see how tree2 has changed the basic requirments of the user.  You keep
saying that I am against TreeModel and for TreeNode.  That is not the
case.  Let me try to phrase my argument differently ...

You are correct that JTree operates on a TreeModel instance.  It also
has TreeNode interface.  Data is first wrapped in TreeNode instance
before being added to the model.  See this example from Sun's JTree
example:

rootNode = new DefaultMutableTreeNode("Root Node");
treeModel = new DefaultTreeModel(rootNode);
treeModel.addTreeModelListener(new MyTreeModelListener());
tree = new JTree(treeModel);

You are correct that JTree does not require a TreeNode interface.  I
agree with you there.  JTree does require a *different* interface,
however, and that interface is TreeModel.  You cannot just add some
arbitrary String "Foo" to a JTree.  How would the tree know what to do
with it?  Is this string a leaf or not?  How can you add children to a
String?  You have two choices.  First choice is to use
DefaultMutableTreeNode and DefaultTreeModel (as shown above.)  That
option *requires* TreeNode.  Second choice is to write your own class
that implements TreeModel.  Either way, you cannot just add an
arbitrary String to a JTree.

Again, I urge us not to think in terms of JTree.  Lets leave JTree out
of this for now.  Lets just talk about the shortcomings of tree2.  If
we can address those then we can move forward.  IMO discussing JTree
is not helpful in reaching consensus on this.
 
> Exactly that's my argument: the TreeNodeBase instance is the extra
> object you force me to create!!! When implementing TreeModel there is no
> need for this extra object, I'm able to use just the 3rd party data
> objects, naked and unwrapped as I get the from the external library. I
> don't have to wrap them with DefaultMutableTreeNode or any other object.

I guarantee that your third party component is not returing objects
that implement TreeModel.  That is my point.  I think you are getting
hung up on the wording of TreeModel vs. TreeNode.  The current tree
needs to make the raw data compliant with what the component expects
(TreeModel).  The new tree does the same thing but calls it something
different (TreeNode.)   The current tree also has a TreeNode interface
and you say that its not required to use the tree.  That's fine.  I
won't argue that point.

To summarize, the current tree requires that data be adapted to the
TreeModel interface.  The new tree requires that data be adapted to
the TreeNode interface.  The fact that I am calling it TreeNode
instead of TreeModel does not make it any more difficult for the user
to implement.  The new tree also has a TreeModel class.  A difference
in the new implementation is that the model stuff is handled behind
the scenes.  There is no need for the user to provide their own model.
 We could look at changing that but basically its already possible to
provide your own models by extending the TreeModel class.

Please take another look at how I am using TreeNode and TreeModel.  If
you think its important that the user can provide their own models
then lets explore that!  Maybe this is the nature of your objection. 
If so, I'm happy to work with you on that.

I think some of the confusion is over the changes in implementation. 
This is primarily a difference of opinion between the two of us.  It
doesn't affect the users.  Most users are going to use
DefaultMutableTreeNode as you do in your example or TreeNodeBase as I
do in my example.
 
> Again you seem to ignore my argument. I'm not talking about
> expanded/collapsed state but about SELECTED nodes. Take the tree example
> in the examples webapp. When you click the text of the root node it will
> get bold as the root node is the selected node now. Go on and expand
> some of the children and click the text of one of the child nodes: again
> the text will get bold to mark the selected node. At any time it is
> possible to ask the current tree for the path to the node currently
> selected. In tree2 the component itself does not care about that so I
> have to implement that feature on my own. It can be done using some
> specific command links and actions but I think to keep track of a
> selected node is a feature so common to tree components that is should
> be implemented there.

This is the kind of specific use case that I have been asking you to
provide.  Until now you just kept telling me that the new tree could
not handle selection.  Now I see what you mean by selection.  Let me
see if I can't address it in the new tree.  I will get back to you on
this one.

> Actually that's what I'm doing I suppose: to talk about features that
> are missing for tree2. But you have to be open for the fact that there
> are other scenarios and applications than the one you have in mind. I
> understand that your effort is driven by the requirements of the project
> you are currently working on. The current tree component has it's origin
> in a similar effort. To get a general-purpose tree component we have to
> address the issues I brought on the table. Otherwise we end up with two
> tree implementations which have something in common but miss some
> feature the other implementation has and vice versa. This can not be the
> goal if you ask me.

I agree we need to address these issues.  In order to do that, I need
specifics.  I will look into the selection issue as you have asked.  I
think I can work something out on that one.  As for the interface
issue, please take another look at my reasoning on that.  If you want
the ability to provide your own TreeModel then maybe that's something
we can do (although I don't think its necessary.)
 
Believe it or not I think we are making progress.  I now know what you
mean by the selection problem.  So we are 50% there.  Lets see if we
can't reach an understanding on the inteface issue.

> Oliver

sean

Re: Tree2

Posted by Oliver Rossmueller <ol...@tuxerra.com>.
Sean,

I'm sorry but I feel somewhat like talking to stones at the moment :-( 
I'm repeating myself over and over again but you just seem to ignore my 
argument that TreeNode is nothing more than a helper interface to 
support the Swing JTree component. Please have a look at the sources if 
you don't beleave me but  JTree is operating on a TreeModel instance and 
TreeModel operates on any kind of objects not just TreeNode instances. 
JTree is not relying on the node objects implementing any specific 
interface, nowhere! The same is true for the current tree component.  In 
my opinion TreeModel is the more flexible, lightweight and 
resource-saving approach and so far I did not get an idea what your 
argument is against TreeModel and for TreeNode. Your decision to force 
the user to implement TreeNode for all of his node objects is no 
improvement but a step backwards from my POV.

Sean Schofield wrote:

>>o) TreeNode instead of TreeModel
>>
>>My argument here is that TreeModel in the way it is used by the current
>>tree component and in the way it is used by the Swing JTree is more
>>generic and lightweight than your approach using TreeNode. If you have a
>>look at the JTree sources you'll see that despite there are constructors
>>taking a TreeNode as their argument, internally JTree is operating on a
>>TreeModel. The TreeNode interface and DefaultTreeModel are just helpers
>>to make it easier for the user to create a TreeModel instance. You will
>>not find any reference to TreeNode in the JTree sources besides the
>>constructors which just take the node to build a DefaultTreeModel
>>instance used as the model.
>>    
>>
>
>If you look at the javadoc for the Swing TreeNode interface it states
>"Defines the requirements for an object that can be used as a tree
>node in a JTree."  That's all I am using TreeNode for as well.  You
>can't just add arbitrary data to the tree you need some kind of
>interface to guarantee certain functionality.  Swing uses it and both
>of our trees use it.
>
>The differences between our two TreeNode interfaces is very slight. 
>Lets focus on that and not worry about what Swing is doing.  What
>Swing is doing is similar and serves as an example of how one might do
>things but I think its a mistake for us to dwell on it too much at
>this point.
> 
>  
>
>>And according the 3rd party library: I have a java library based on a
>>library of C functions which provides access to some kind of
>>hierarchical data I have to present in a tree. At the moment I have an
>>implementation of TreeModel (as used by the current tree component)
>>which uses named 3rd party lib to provide the tree with the data to
>>display. The implementation of TreeModel is straightforward as it's just
>>an adapter to the external API and uses/returns the objects it gets from
>>there. So far, so simple.  Now consider your programming model where I
>>have to provide the tree with objects implementing the TreeNode
>>interface. As I have no access to the sources of named 3rd party library
>>I have to wrap the objects I get from the library with another object
>>implementing TreeNode to fulfill the contract. This makes the
>>implementation a little bit more complex and increases memory
>>consumption as I definitely would have to deal with two objects per node.
>>    
>>
>
>OK.  You are adapting your third party data to TreeModel.  This is
>where the *slight* code change comes into play.  You need to change
>your adapter and adapt to a new interface.
>
>Here is the difference as I see it.  The new component has one
>interface the user needs to worry about: TreeNode.  The current one
>has two: TreeNode and TreeModel.  The tree.jsp example shows the
>mapping of data to DefaultMutableTreeNode.  In tree2.jsp the data is
>put into TreeNodeBase.  Please explain to me how this is substantially
>different?  Your third party data is not going to implement TreeNode. 
>You must be putting it in DefaultMutableTreeNode or something
>equivalent.  So you put it in TreeNodeBase instead.      You don't
>need any extra objects in the new tree.
>  
>
Exactly that's my argument: the TreeNodeBase instance is the extra 
object you force me to create!!! When implementing TreeModel there is no 
need for this extra object, I'm able to use just the 3rd party data 
objects, naked and unwrapped as I get the from the external library. I 
don't have to wrap them with DefaultMutableTreeNode or any other object.

>Now if TreeNodeBase is not doing it for you, then we can talk about
>other implementations of TreeNode that could provide what you want. 
>But I can't really see how you can say that the new approach requires
>substantial code changes let alone more memory.
>
>The current tree control (in tree.jsp) does one extra step that the
>new tree control does not require.  You need to create a
>DefaultTreeModel using the DefaultMutableTreeNodes you just created. 
>The new control does not require the user to do this.  It does
>something similar but behind the scenes.  So if anything the new tree
>component is simpler to configure your tree data.
> 
>  
>
>>o) node selection
>>
>>The current tree keeps track of selected nodes as does Swing JTree and
>>there are events emitted when selection changes as there is a
>>possibility to register listeners interested in this kind of events. If
>>I did not miss something there is no such functionality in tree2. In
>>fact I do not have a proposal at the moment on how to implement it, but
>>that's an important feature from my POV and we should not tell the user
>>to find a way on his own on how to deal with that.
>>    
>>
>
>Tree2 is definitely keeping track of which nodes are open and closed. 
>How else could it show the correct expand/collapse every time you
>clicked a new node?  Its just not doing it in the same way as the
>current tree control.
>
>As for the other aspect of this argument, you are correct that there
>is no special event for node selection.  I studied what the current
>tree is doing in this regard and considered it to be unecessary.  I am
>happy to debate that conclusion with you and I am willing to
>reconsider if you can demonstrate that its necessary.
>
>Recall the two major usecases are client-side and server-side toggle. 
>In client-side toggle the user may open and close numerous nodes
>before ever submitting anything back to the server.  In this case its
>impossible to generate events every time a node opens and closes
>because the expanding and collapsing is handled by the client.  Also,
>if you click a link in your tree that would navigate you to another
>page, you don't even really care anymore.
>
>The important thing is to know which nodes are open and which are
>closed.  Whether or not a node was "selected" only really matters in
>that it helps us answer this question.  (We're talking branch nodes,
>not leaf nodes here.)  Do you agree with me on that point?
>
>I've basically come up with a mechanism to maintain the
>expand/collapse state without adding a new event.  The actual clicking
>on a leaf node can be handled by ActionEvent.  So I've cut down on the
>amount of code and relied on standard JSF functionality that the user
>will be more familiar with.
>  
>
Again you seem to ignore my argument. I'm not talking about 
expanded/collapsed state but about SELECTED nodes. Take the tree example 
in the examples webapp. When you click the text of the root node it will 
get bold as the root node is the selected node now. Go on and expand 
some of the children and click the text of one of the child nodes: again 
the text will get bold to mark the selected node. At any time it is 
possible to ask the current tree for the path to the node currently 
selected. In tree2 the component itself does not care about that so I 
have to implement that feature on my own. It can be done using some 
specific command links and actions but I think to keep track of a 
selected node is a feature so common to tree components that is should 
be implemented there.

> 
>  
>
>>o) node rendering rules
>>
>>In fact I had the first point in mind here: if the node objects do not
>>have to implement TreeNode then there is no way to use getType() to
>>decide which facet to use to render a node.
>>    
>>
>
>I can see this concern but I think we have a way around it.  getType()
>is about the only new method to TreeNode interface that I am adding so
>lets explore what new requirements this would put on our legacy users.
> getType() is just to provide additional information to the renderer
>so you can customize rendering of the nodes based on the type of the
>node.
>
>We *definitely* require this method.  This gives you additional
>flexability to customize the look of your tree that you cannot do now.
> If you do not want to take advantage of this extra functionality then
>you can just pick an arbitrary string (say "default") and set this to
>be the type of all of your TreeNodes.  You would do this as you adapt
>your data to TreeNode.  No big deal really.
>
>I would really like to reach closure on this soon.  I think the new
>tree is quite powerful and useful and I have an immediate need for it
>in my current project at work.  Also other users are reporting to me
>that they are using it in their own projects.  It will be easier for
>all involved if we can stop using tree2 package refs in our code and
>start using tree.
>
>I haven't really heard an objection that we cannot handle through the
>existing code.  If there is a use case for tree selection event then
>we can look at adding that back in.  But right now the new tree has a
>lot of new functionaltiy with about 50% of the code base.  I don't
>think we should stop moving forward because its implemented
>differently behind the scenes.  In fact, the changes behind the scenes
>are what result in less code to maintain.
>Lets focus on what features are missing (I don't think there are any)
>and what changes to the user's code are required (I think they are
>small.)
>  
>
Actually that's what I'm doing I suppose: to talk about features that 
are missing for tree2. But you have to be open for the fact that there 
are other scenarios and applications than the one you have in mind. I 
understand that your effort is driven by the requirements of the project 
you are currently working on. The current tree component has it's origin 
in a similar effort. To get a general-purpose tree component we have to 
address the issues I brought on the table. Otherwise we end up with two 
tree implementations which have something in common but miss some 
feature the other implementation has and vice versa. This can not be the 
goal if you ask me.

Oliver

>>Oliver
>>    
>>
>
>sean
>  
>


-- 
Oliver Rossmueller
Software Engineer and IT-Consultant
Hamburg, Germany
http://www.rossmueller.com


Re: Tree2

Posted by Sean Schofield <se...@gmail.com>.
> o) TreeNode instead of TreeModel
> 
> My argument here is that TreeModel in the way it is used by the current
> tree component and in the way it is used by the Swing JTree is more
> generic and lightweight than your approach using TreeNode. If you have a
> look at the JTree sources you'll see that despite there are constructors
> taking a TreeNode as their argument, internally JTree is operating on a
> TreeModel. The TreeNode interface and DefaultTreeModel are just helpers
> to make it easier for the user to create a TreeModel instance. You will
> not find any reference to TreeNode in the JTree sources besides the
> constructors which just take the node to build a DefaultTreeModel
> instance used as the model.

If you look at the javadoc for the Swing TreeNode interface it states
"Defines the requirements for an object that can be used as a tree
node in a JTree."  That's all I am using TreeNode for as well.  You
can't just add arbitrary data to the tree you need some kind of
interface to guarantee certain functionality.  Swing uses it and both
of our trees use it.

The differences between our two TreeNode interfaces is very slight. 
Lets focus on that and not worry about what Swing is doing.  What
Swing is doing is similar and serves as an example of how one might do
things but I think its a mistake for us to dwell on it too much at
this point.
 
> And according the 3rd party library: I have a java library based on a
> library of C functions which provides access to some kind of
> hierarchical data I have to present in a tree. At the moment I have an
> implementation of TreeModel (as used by the current tree component)
> which uses named 3rd party lib to provide the tree with the data to
> display. The implementation of TreeModel is straightforward as it's just
> an adapter to the external API and uses/returns the objects it gets from
> there. So far, so simple.  Now consider your programming model where I
> have to provide the tree with objects implementing the TreeNode
> interface. As I have no access to the sources of named 3rd party library
> I have to wrap the objects I get from the library with another object
> implementing TreeNode to fulfill the contract. This makes the
> implementation a little bit more complex and increases memory
> consumption as I definitely would have to deal with two objects per node.

OK.  You are adapting your third party data to TreeModel.  This is
where the *slight* code change comes into play.  You need to change
your adapter and adapt to a new interface.

Here is the difference as I see it.  The new component has one
interface the user needs to worry about: TreeNode.  The current one
has two: TreeNode and TreeModel.  The tree.jsp example shows the
mapping of data to DefaultMutableTreeNode.  In tree2.jsp the data is
put into TreeNodeBase.  Please explain to me how this is substantially
different?  Your third party data is not going to implement TreeNode. 
You must be putting it in DefaultMutableTreeNode or something
equivalent.  So you put it in TreeNodeBase instead.      You don't
need any extra objects in the new tree.

Now if TreeNodeBase is not doing it for you, then we can talk about
other implementations of TreeNode that could provide what you want. 
But I can't really see how you can say that the new approach requires
substantial code changes let alone more memory.

The current tree control (in tree.jsp) does one extra step that the
new tree control does not require.  You need to create a
DefaultTreeModel using the DefaultMutableTreeNodes you just created. 
The new control does not require the user to do this.  It does
something similar but behind the scenes.  So if anything the new tree
component is simpler to configure your tree data.
 
> o) node selection
> 
> The current tree keeps track of selected nodes as does Swing JTree and
> there are events emitted when selection changes as there is a
> possibility to register listeners interested in this kind of events. If
> I did not miss something there is no such functionality in tree2. In
> fact I do not have a proposal at the moment on how to implement it, but
> that's an important feature from my POV and we should not tell the user
> to find a way on his own on how to deal with that.

Tree2 is definitely keeping track of which nodes are open and closed. 
How else could it show the correct expand/collapse every time you
clicked a new node?  Its just not doing it in the same way as the
current tree control.

As for the other aspect of this argument, you are correct that there
is no special event for node selection.  I studied what the current
tree is doing in this regard and considered it to be unecessary.  I am
happy to debate that conclusion with you and I am willing to
reconsider if you can demonstrate that its necessary.

Recall the two major usecases are client-side and server-side toggle. 
In client-side toggle the user may open and close numerous nodes
before ever submitting anything back to the server.  In this case its
impossible to generate events every time a node opens and closes
because the expanding and collapsing is handled by the client.  Also,
if you click a link in your tree that would navigate you to another
page, you don't even really care anymore.

The important thing is to know which nodes are open and which are
closed.  Whether or not a node was "selected" only really matters in
that it helps us answer this question.  (We're talking branch nodes,
not leaf nodes here.)  Do you agree with me on that point?

I've basically come up with a mechanism to maintain the
expand/collapse state without adding a new event.  The actual clicking
on a leaf node can be handled by ActionEvent.  So I've cut down on the
amount of code and relied on standard JSF functionality that the user
will be more familiar with.
 
> o) node rendering rules
> 
> In fact I had the first point in mind here: if the node objects do not
> have to implement TreeNode then there is no way to use getType() to
> decide which facet to use to render a node.

I can see this concern but I think we have a way around it.  getType()
is about the only new method to TreeNode interface that I am adding so
lets explore what new requirements this would put on our legacy users.
 getType() is just to provide additional information to the renderer
so you can customize rendering of the nodes based on the type of the
node.

We *definitely* require this method.  This gives you additional
flexability to customize the look of your tree that you cannot do now.
 If you do not want to take advantage of this extra functionality then
you can just pick an arbitrary string (say "default") and set this to
be the type of all of your TreeNodes.  You would do this as you adapt
your data to TreeNode.  No big deal really.

I would really like to reach closure on this soon.  I think the new
tree is quite powerful and useful and I have an immediate need for it
in my current project at work.  Also other users are reporting to me
that they are using it in their own projects.  It will be easier for
all involved if we can stop using tree2 package refs in our code and
start using tree.

I haven't really heard an objection that we cannot handle through the
existing code.  If there is a use case for tree selection event then
we can look at adding that back in.  But right now the new tree has a
lot of new functionaltiy with about 50% of the code base.  I don't
think we should stop moving forward because its implemented
differently behind the scenes.  In fact, the changes behind the scenes
are what result in less code to maintain.
Lets focus on what features are missing (I don't think there are any)
and what changes to the user's code are required (I think they are
small.)

> Oliver

sean

Re: Tree2

Posted by Oliver Rossmueller <ol...@tuxerra.com>.
Sean,

I'm sorry if I was not specific enough in my first attempt so let's try 
again:

o) TreeNode instead of TreeModel

My argument here is that TreeModel in the way it is used by the current 
tree component and in the way it is used by the Swing JTree is more 
generic and lightweight than your approach using TreeNode. If you have a 
look at the JTree sources you'll see that despite there are constructors 
taking a TreeNode as their argument, internally JTree is operating on a 
TreeModel. The TreeNode interface and DefaultTreeModel are just helpers 
to make it easier for the user to create a TreeModel instance. You will 
not find any reference to TreeNode in the JTree sources besides the 
constructors which just take the node to build a DefaultTreeModel 
instance used as the model.

And according the 3rd party library: I have a java library based on a 
library of C functions which provides access to some kind of 
hierarchical data I have to present in a tree. At the moment I have an 
implementation of TreeModel (as used by the current tree component) 
which uses named 3rd party lib to provide the tree with the data to 
display. The implementation of TreeModel is straightforward as it's just 
an adapter to the external API and uses/returns the objects it gets from 
there. So far, so simple. Now consider your programming model where I 
have to provide the tree with objects implementing the TreeNode 
interface. As I have no access to the sources of named 3rd party library 
I have to wrap the objects I get from the library with another object 
implementing TreeNode to fulfill the contract. This makes the 
implementation a little bit more complex and increases memory 
consumption as I definitely would have to deal with two objects per node.

o) node selection

The current tree keeps track of selected nodes as does Swing JTree and 
there are events emitted when selection changes as there is a 
possibility to register listeners interested in this kind of events. If 
I did not miss something there is no such functionality in tree2. In 
fact I do not have a proposal at the moment on how to implement it, but 
that's an important feature from my POV and we should not tell the user 
to find a way on his own on how to deal with that.

o) node rendering rules

In fact I had the first point in mind here: if the node objects do not 
have to implement TreeNode then there is no way to use getType() to 
decide which facet to use to render a node.

Hope I was more specific this time.

Oliver


Sean Schofield wrote:

>>- I don't like how you changed the way the data is handed over to the
>>tree by forcing the user to provide TreeNode implementors? To use
>>TreeModel in swing was a wise decision of the designers at sun as it's
>>an interface which can be implemented for any kind of hierarchical data
>>in a simple and lightweight manner. That's why I duplicated it in my
>>tree impl. In you model I would be forced to wrap all my internal node
>>objects with a TreeNode implementor because I'm not able to change the
>>internal node objects as  they are provided by a 3rd party library. It
>>can be done but in comparison to the TreeModel implementation I have in
>>place at the moment it's a more complex and more heavyweight solution.
>>And I don't like to have to ask my boss to buy better machines and more
>>RAM because instead of one object per node now I have to create two of them.
>>    
>>
>
>I don't quite understand your objection.  The new approach to the data
>is similar to the old except simpler.  Yes the data will have to be in
>TreeNode objects but that's true in the current tree and its true in
>Swing.  Take a look at your tree.jsp example.  You are putting the
>data in DefaultMutableTreeNode which extends your TreeNode interface. 
>In my example you put the data in TreeNodeBase which extends my
>TreeNode interface.  OK so you have to change your data population
>code slightly but that doesn't seem to be what you're complaining
>about.
>
>In both versions of the component (and in Sun's JTree) you have to put
>the data in an object that implements a TreeNode interface.  The new
>tree is no different.   In fact, the interface is simpler.  I don't
>understand the third party tool argument.  Do you really have third
>party tools that are returning objects that implement
>org.apache.myfaces.custom.tree.TreeNode?  If not, then what do third
>party objects have to do with anything?
>
>I will play Devil's advocate for a moment and say that the best
>argument against the new tree is that you might have to make slight
>changes to your code so that your are populating TreeNodeBase (or you
>own custom TreeNode) instead of whatever your were populating before. 
>A non trivial change but IMO well worth it to get the new features of
>the new tree.  You definitely do not have to have two sets of objects
>or buy more RAM.
>
>  
>
>>- tree2 is not able to deal with node selection so anybody would be on
>>his own to implement this feature; I think there should be a way to have
>>the tree handle node selection
>>    
>>
>
>I'm not sure how to respond to that.  Tree2 handles node selection
>perfectly fine IMO.  What do you mean by this?  What is it not able to
>do that you need it to be able to do?  The nodes open and close when
>you click on them.  It works in javascript or through server post.  It
>remembers which nodes are open.  And you can put pretty much any JSF
>component in the node (checkbox, image, commandLink, radio buttons,
>whatever) and it handles the events appropriately.
>
>  
>
>>- your scheme of defining how the nodes are rendered is nice and simple,
>>but it will not work out for some of the scenarios I have to deal with;
>>so we have to find a more powerful way to specify rendering rules
>>    
>>
>
>I'd be interested in hearing what kinds of scenarios this scheme
>couldn't handle.  Perhaps you there are some but if the component can
>be improved by understanding your scenario then I'd like to know. 
>Both you and Heath have thrown some intersesting scenarios my way in
>the past and I think I have adressed them (and the component is better
>for it.)
>
>  
>
>>Oliver
>>    
>>
>
>sean
>  
>


-- 
Oliver Rossmueller
Software Engineer and IT-Consultant
Hamburg, Germany
http://www.rossmueller.com


Re: Tree2

Posted by Sean Schofield <se...@gmail.com>.
> - I don't like how you changed the way the data is handed over to the
> tree by forcing the user to provide TreeNode implementors? To use
> TreeModel in swing was a wise decision of the designers at sun as it's
> an interface which can be implemented for any kind of hierarchical data
> in a simple and lightweight manner. That's why I duplicated it in my
> tree impl. In you model I would be forced to wrap all my internal node
> objects with a TreeNode implementor because I'm not able to change the
> internal node objects as  they are provided by a 3rd party library. It
> can be done but in comparison to the TreeModel implementation I have in
> place at the moment it's a more complex and more heavyweight solution.
> And I don't like to have to ask my boss to buy better machines and more
> RAM because instead of one object per node now I have to create two of them.

I don't quite understand your objection.  The new approach to the data
is similar to the old except simpler.  Yes the data will have to be in
TreeNode objects but that's true in the current tree and its true in
Swing.  Take a look at your tree.jsp example.  You are putting the
data in DefaultMutableTreeNode which extends your TreeNode interface. 
In my example you put the data in TreeNodeBase which extends my
TreeNode interface.  OK so you have to change your data population
code slightly but that doesn't seem to be what you're complaining
about.

In both versions of the component (and in Sun's JTree) you have to put
the data in an object that implements a TreeNode interface.  The new
tree is no different.   In fact, the interface is simpler.  I don't
understand the third party tool argument.  Do you really have third
party tools that are returning objects that implement
org.apache.myfaces.custom.tree.TreeNode?  If not, then what do third
party objects have to do with anything?

I will play Devil's advocate for a moment and say that the best
argument against the new tree is that you might have to make slight
changes to your code so that your are populating TreeNodeBase (or you
own custom TreeNode) instead of whatever your were populating before. 
A non trivial change but IMO well worth it to get the new features of
the new tree.  You definitely do not have to have two sets of objects
or buy more RAM.

> - tree2 is not able to deal with node selection so anybody would be on
> his own to implement this feature; I think there should be a way to have
> the tree handle node selection

I'm not sure how to respond to that.  Tree2 handles node selection
perfectly fine IMO.  What do you mean by this?  What is it not able to
do that you need it to be able to do?  The nodes open and close when
you click on them.  It works in javascript or through server post.  It
remembers which nodes are open.  And you can put pretty much any JSF
component in the node (checkbox, image, commandLink, radio buttons,
whatever) and it handles the events appropriately.

> - your scheme of defining how the nodes are rendered is nice and simple,
> but it will not work out for some of the scenarios I have to deal with;
> so we have to find a more powerful way to specify rendering rules

I'd be interested in hearing what kinds of scenarios this scheme
couldn't handle.  Perhaps you there are some but if the component can
be improved by understanding your scenario then I'd like to know. 
Both you and Heath have thrown some intersesting scenarios my way in
the past and I think I have adressed them (and the component is better
for it.)

> Oliver

sean