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
<[EMAIL PROTECTED]> 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
> ><[EMAIL PROTECTED]> 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
>
>