Everytime the user presses enter on a filled filter field, the following things happen:
Information about the filter is sent to the backend. Which element is to be filtered? Which criterias, maybe operators, etc.
The backend filters using hibernate. Important is, I’m forced to use beans here, so there’s no possibility for me to use SQLContainers for example (I think, at least).
The backend sends back a Java Collection with the filtered data to the frontend.
Where everything after step 3 is my actual problem. The table is using a BeanItemContainer as datasource.
Is it possible to refill the BeanItemContainer with new items, displaying the results instantly? Replacing the BeanItemContainer by a new one results in empty filter input fields.
if (((BeanItemContainer<Company>)this.getContainerDataSource()).size() > 0) {
((BeanItemContainer<Company>)this.getContainerDataSource()).removeAllItems();
}
for(Company c : entities) {
BeanItem<Company> item = new BeanItem<Company>(c);
BeanItem<Company> notNull = ((BeanItemContainer<Company>)this.getContainerDataSource()).addBean(item.getBean());
System.out.println("The following is supposed to be not null: ");
System.out.println(notNull);
}
}
[/code]The code you see above is supposed to be called multiple times: On initialization of the view - so with all entities - and when a filter was called. As you can see, I’m using the addBean()-Method here. However, this method returns null when I try to call the refresh() method. As from the API documentation, addBean() returns null when adding a Bean to the container fails.
The code you see above is supposed to be called multiple times: On initialization of the view - so with all entities - and when a filter was called. As you can see, I’m using the addBean()-Method here. However, this method always returns null when I try to call the refresh() method AFTER the initialization of the view. As explained in the API documentation, addBean() returns null when adding a Bean to the container fails.
an interesting use case. Can’t help you directly since I haven’t really used FilteringTable in this way. The recommended way is to handle the filtering within the container (or pass the filtering to backend through the container if lazy-loading is needed) so this would not become an issue.
On the other hand, from your code I don’t immediately see why this should fail. Can you debug into the container to see why the addBean actually returns null? Looking at the container code there seems to be many things that can go wrong.
Another issue with this approach is that on each add, it would cause an ItemSetChange event which can be quite expensive when the container is attached to a table. If you get this to work, I’d recommend calling setRefreshingEnabled(false) on the FilterTable before starting your update, and setRefreshingEnabled(true) after all updating is done. This will ensure only one update of the table data structures will be done.
first of all: Sorry for my double posts here. For some reason, I’m not able to press on “Confirm Edit” here in the forum. And thanks for your answer!
I debugged the container-hierarchy. I already figured that the problem is somewhere within the abstract container classes. However, the result is a halt at line 4:
// Make sure that the item has not been added previously
if (getAllItemIds().contains(itemId)) {
return null;
}
Which originates from AbstractInMemoryContainer, line 767. Problem is: I remove all items from the container before I refill it.
So what am I supposed to do know? Overriding the method for removing these 3 (4) lines?
I think the problem is in your first if clause. The size method returns the filtered size of the container, and at this point the FilterTable has already added a filter so the size of the filtered item set might actually be 0. Try removing that if clause - it should have no side effects since removing all items from an empty container does nothing anyway.
That’s probably because the Filter is in your container still and probably your newly added items do not pass that filter. The whole Container/Filterable thing isn’t really designed to be used this way. You might want to either modify your items so they will pass the filter, or, preferably use a container implementation which delegates the filtering to the back end. In this case you might need to write it yourself.
Finally! That’s the solution. Just for a test, I did the following:
((BeanItemContainer<Company>)this.getContainerDataSource()).removeAllContainerFilters();
This seems not to affect the GUI elements of the table. Very good news!