Table - Using BeanItemContainer but adding additional properties?

[b]
Hi

I use the Table with BeanItemContainer - it’s just the easiest way to get a list POJOs in a table…

However sometimes I need an extra property/column to go along the container/table… and BeanItemContainer suports only its properties and no more…
[/b]

[b]
I know about addGeneratedColumn and it can work, but its data is not bounded to the container, so I have to maintain it parallel to the Table and the BeanItemContainer…

Does any one have an idea how to solve such an issue?

Thanks

Eyal
[/b]

OK, I’ll gladly answer my own question, with hope this will help others in the future


BeanItemContainer
is truly a great way to populate table data, especially if the table represents some POJO (e.g. Employee, Policy, AppParameter clasess) - It saves you all the hassle of defining table contained properties with classes and default values - just pick the columns you want to see and c’est tout, it’s there.

However, in some cases you might want to add an “external” column to your table , i.e. a column which does not respond to a property in the Bean/POJO… for example: a “%Raise” column for an Employee table with editable text field - there’s no setRaise/getRaise in the Employee POJO, however you still need it.

Vaadin invented
addColumnGenerator
for this manner, and in most cases it probably works great.
Only
ColumnGenerators DO NOT BIND to their table model
, meaning if you define a %Raise ColumnGenerator with a TextField, you can’t access that TextFiled or its value from the table itself, there’s just no API for that… you’ll have to write your own tracking for this data (i.e. maintain some map of itemId->value) and deal with listeners about row added/removed and such … this is a very bad practice.

My solution is to extend
BeanItemContainer
in a way that in addition to exposing all the properties a POJO (as it does so good today) it also accept s a list of properties (i.e. a property’s id, type and default value).
So if your POJO is Employee {id, name, department}, you could do this.

ExtendedBeanItemContainer x = new ExtendedBeanItemContainer<Employee>(Employee.class); x.addAnotherProperty("raise", Double.class, null); ... table.setColumnHeader("raise", "%Raise"); ... public class RaiseColumnGenerator implelements Table.ColumnGenerator { Object generateCell(Table source, Object itemId, Object columnId) { TextField txt = new TextField(); // Bind TextField with source.getItem(itemId).getProperty(columnId); return txt; } } ... table.getItemId(anId).getProperty("raise"); // Remember! raise is not in the Employee POJO ... I already wrote an alpha implementation for ExtendedBeanItemContainer and it works great.
Once I’ll make it production ready, I will fully post it here.
I hope that although my post here was a bit long, it could be usefull for others as it was for me…

Eyal