Refresh Table with BeanItemContainer

Hi,

I have a refresh problem with a Table binded to a BeanItemContainer.
The idea is to load the minimum information in a table, then retrieve the full BeanItem with respect to the selected element. Here is what I do:

  1. I load the table with BeanItems but only the id, name and description fields
  2. On value change, I ‘fully’ load the BeanItem into an editor panel (meaning retrieving all the fields)
  3. After I save the new values from the editor panel, this is not reflected in the table

Of course the selected BeanItem from the table, is not the same as the “full” BeanItem that was edited. So I tried to reset the ContainerDataSource of the table with table.setContainerDataSource(new MyContainer(data))
But even that way, the table do not refresh after the I click the save button from the editor panel.

Any advice on how to handle this ?

Thanks,
Eric

Did I understand correctly that you are trying to do the typical Master-Details view pattern?

If so, everything should word OK as long as you edit the items through the data model all along.

See
this example
.

If you’re a Pro Account subscriber, see the article
#255
.

Hi,

Thanks for you link.
This is indeed a kind of Master-Detail pattern.

The only difference is that I’m not dealing with the same BeanItem.
In the table (master), I have a light BeanItem with 3 fields.
On selection, I retrieve the full BeanItem with all fields (based on the id) and then I use it in the “detail” section.
If you try to save the bean, everything runs fine, database and “detail” section are updated but the table (master) is not, since it’s not the same BeanItem as the one selected in the table.

That’s why I tried to set again the table ContainerDataSource… but that’s doesn’t refresh the content either.

My actual solution is derived from http://vaadin.com/forum/-/message_boards/message/213115


container.updateItem(currentItem.getBean())
container = new CodeListContainer(CodeListApplication.application.getCodeListService())
table.setContainerDataSource(container)
table.setVisibleColumns(CodeListContainer.NATURAL_COL_ORDER)
table.setColumnHeaders(CodeListContainer.COL_HEADERS_ENGLISH)
// table.requestRepaint()

I already have the table.setImmediate(true) so table.requestRepaint() is not needed
Since I also have a ValueChangeEvent on the table, you have to make sure there this.table.getItem(this.table.getValue()) is not a null value before invoking any other method.
Indeed, the setContainerDataSource seems to trigger this event but with no selection.

I’m still open for better solutions/suggestions :wink:

Eric

Replacing the container with a new one and that way rebuilding the table is one way to do it, but not really nice. It doesn’t do any harm, but…

The “proper” way is to update the summary version of the item through the data model API. You can do this by copying the properties one by one. For example, something like:

Item tableItem = table.getItem(table.getSelected());
for (Object pid: tableItem.getItemPropertyIds())
    tableItem.getItemProperty(pid).setValue(detailedItem.getItemProperty(pid).getValue());

If I understood correctly that you have a summary bean, which you use in the table, and a detailed bean, which you use in the editor.

Hi,

totally agree with you :wink:
I also tried to set manually the values of the detailed bean into the summary bean. But this didn’t trigger the refresh of the table. But maybe my code was wrong, I will try your version with the ItemProperty approach.
It definitely sounds better than reloading the whole container :wink:

Eric

Nice, it’s finally working as expected :smiley:

Thank you !
Eric

Just copying the data from the bean to the other doesn’t work properly, because the BeanItem can’t know about such direct changes in the bean.

The BeanItem properties are ValueChangeNotifiers, so setting the properties through the API causes ValueChangeEvents, which are noticed by the table, which then updates its content automatically.

Hi

the mentioned example above helped me a lot. But there is one problem. I click on a bean to show them in the form, then i change any value and press the Cancel-button. The changed value will shown in the table.

It is not a big problem. I only want to mentioned it. :slight_smile:

Greets

If I understand your problem correctly, you use in the form the bean item used in the table. Use a copy of the bean instead, and update the targeted bean only if the form is validated.

Hi

yes, this is actually what i do. I have no problem with that issue. I only mentioned it for people who maybe copy the code. :smiley:

Greets

You probably haven’t enabled buffering for your form - try myform.setWriteThrough(false);

Hi

Thanks Henri. This works great.

Greets