Trees in Vaadin: Shared children or multiple parents

Hello vaadin community,

I have got a question regarding the tree component in Vaadin. In my application, I´d like to use a tree for navigation and editing purposes, similar to the example contained in the book of vaadin (see [1]
). The main difference now is that items may have multiple parents or in reverse may be children of different items. In the attached example the item “Child2” is child of “Root1” as well as of “Root2” and therefore is represented twice in the resulting tree. The child/parent relationships in the tree depend on different association properties contained in my domain model. Ideally I would like to make use of BeanItems and the BeanItemContainer to wrap my domain model POJOs and ease the access to their properties.

Is there some component or adviseable pattern I may use to achieve this in vaadin? So far, it seems items within a tree should only have one parent. Thank you for your efforts.

Greetings
Christian

[1]
https://vaadin.com/book/-/page/components.tree.html#figure.components.tree
13550.png

Hi Christian,

BeanItemContainer uses the BeanItem as itemId, so you will have problems there. You should use another item container strategy not using the item as itemId, so you can add to your TreeTable two different itemIds referencing to the same item.

I did never try this out, but maybe you could inject another BeanIdResolver to your BeanItemContainer. You “just” have to think how to find a bean

Or maybe you can wrap the bean into another class, and make multiple instances out of that class which do not equal (as in the methods equals() and hashCode()). That way changes in bean will be accessable in all instances pointing to the same bean.

Alternatively you could go with HierarchicalContainer and add a new Item for every instance of the bean, with something else than the bean as the value.

Hello Wolfgang,
hello Jens,

thank you for your suggestions. I will give those a try and provide feedback.

I am really looking forward to your solution :slight_smile: Good luck finding an elegant way!

Hello again,

for now I have settled with the following solution:

I took a look at the container types and UI components that come with vaadin and decided not to change these components if there is another way which does not add too much additional complexity to my domain model. Speaking of which I also took a second look at my requirements and noticed the need for duplicate elements in the tree does only apply across different root elements of the tree. Therefore, I followed Jens suggestion and wrapped my beans for the tree inside a new bean class. This class is aware of some bean from the domain model and its current root in the tree. This enables unique identication by means of equals() and hashcode() for each bean in the tree, as long as the different instances exist under different roots. The overhead this way should be rather small and the change/addition intruduced is optional and also limited to this special use case not affecting the domain model in general.

Again, thank you very much for your input.

Cheers,
Christian

Not sure if you meant that the wrapper bean’s equals() and hashcode() should match those methods of the actual bean itself, ie. wrapper1OfBean1.equals(wrapper2OfBean1) == true. If that is what you meant then it won’t work as containers use those methods when you use addItem() and if it finds already some bean that is equal, then it won’t the second one into there any more (because it thinks it already is in the collection).

You have to do it so that the separate instances of the wrapper doesn’t equal each others. That might have been what you already meant but I’m just making sure. :slight_smile:

Hello Jens,

a wrapper object is identified on the one hand by the bean it wraps and on the other hand by the bean that represents the root of its hierarchy. So in case of the example from my first post, the occurrences of “Child2” in the tree are identified as “Child2+Root1” and “Child2+Root2”. This is sufficient in my case as duplicate elements as of now are not needed under the same root.

hey !

You can override hashcode() and equal()…it will work as your expectation :slight_smile: