I'm trying to update a grid in Vaadin after a change has been made to the grid from a different UI instance.
To elaborate, I have two different UI instances, UI1 and UI2 (tabs from two different browsers). These UI instances contain a view which contains a grid consisted of Contact objects that have various properties such as name, age, gender...
I add a Contact to the grid from UI1 and I want UI2 to see the updated grid instantly without having to refresh.
To accomplish that, I know I have to use Vaadin Push which I already set up using a Broadcaster class. I have a receiveBroadcast()
method in my UI class which will update the UI whenever a View class sends a broadcast to UIs using broadcast()
method. Part of my UI class looks like this:
@Title("Contact Book")
@Theme("reindeer")
@Push
public class UserInterface extends UI implements BroadcastListener{
private Navigator navigator;
@Override
protected void init(VaadinRequest request){
navigator = new Navigator(this, this);
navigator.addView(ContactBookView.NAME, new ContactBookView());
Broadcaster.register(this);
}
@Override
public void detach(){
Broadcaster.unregister(this);
super.detach();
}
@Override
public void receiveBroadcast(Grid grid) {
access(()->{
// update grid here
Notification.show("Grid updated", Notification.Type.TRAY_NOTIFICATION);
});
}
}
And my Broadcaster class is as the same in this link (I just altered the methods a bit so I can pass the grid as a parameter)
Then in my ContactBookView class I call Broadcaster.broadcast(grid)
method after adding or changing an item, so that I can update the grid somehow in my UI class' access()
method but nothing I tried seems to work. I know that push is working because I can see the "Grid updated" message in all UI instances when broadcast is received.
I tried to remove the view and re-initialize
navigator.removeView(ContactBookView.NAME);
navigator.addView(ContactBookView.NAME, new ContactBookView());
Tried to completely empty the grid and refill
grid.removeAllColumns();
grid.setContainerDataSource(container);
Tried to force the grid to update itself using this ugly workaround
grid.setContainerDataSource(grid.getContainerDataSource());
Tried to execute a JavaScript query to force the UIs to sync
JavaScript.getCurrent().execute("javascript:vaadin.forceSync();");
But none of these worked. Maybe I'm doing something else wrong? FYI my Vaadin version is 7.5.0.
I'd appreciate any kind of feedback or advice,
Thanks.
I managed to solve the issue by re-navigating to the current view after I reinitialized it. Final UI access method looks like this:
public void receiveBroadcast() {
access(()->{
navigator.removeView(ContactBookView.NAME);
navigator.addView(ContactBookView.NAME, new ContactBookView());
navigator.navigateTo(ContactBookView.NAME);
Notification.show("Grid updated", Notification.Type.TRAY_NOTIFICATION);
});
With this, the view gets refreshed in the background and pushed to the UI instances without having to refresh physically.
I'm sure there might be better workarounds and this one seems kind of ugly but it currently satisfies my needs. However, I'd still appreciate any different approach.