In Vaadin 7, a web application can have multiple entry points; the UIs. Each UI can only have a single Navigator containing Views.
We are working on an application which requires multi-level navigation, and for some screens we don't know if we should have a single UI with a navigator or multiple UIs with a shared menu component.
What are the advantages and inconveniences of UI and Navigator? Are there any guidelines about this choice?
I recommend using one UI with Navigator as in my opinion it's enough to do the job. Main inconvinience of many UIs is reload when switching between them. Also you would need to remember about desired consistency, eg. to have same header in each UI. And from my experience you would for sure encounter more problems ;-)
To make it clean you should use MVP patter. I use similar to this one with com.google.common.eventbus.EventBus to handle events. I add eventBus to my views, post events there and handle them in appropriate presenter, without implementing listeners in view which in my opinion is more problematic. As MVP already reserves 'presenter' and 'view' I call Vaadin view 'page'.
You can create header, footer main menu and then content container (eg. some Layout) to wire navigator with:
Navigator n = new Navigator(UI.getCurrent(), layout);
To manage navigation I created PagesEnum and when changing view I post ChangePageEvent which gets PageEnum.SOME_PAGE as parameter. Optionally there is also an id of item to display. So in MainPresenter I have:
@Subscribe
public void changePage(ChangePageEvent event) {
String url = event.getPageName();
if (event.hasId()) {
url += "/" + event.getEntityId();
}
navigator.navigateTo(url);
}
Then there are different possibilities:
in enter method of the page (Vaadin view) make sure that appropriate submenu is displayed.
add it as parameter to ChangePageEvent and handle it in changePage method.
hardcode it in PageEnum as new field, eg. subMenu and create other enum for submenus, chandle it in changePage method.
Submenu will be probably outside of the container that you wire Navigator with, so there you can create SubMenuPresenter and SubMenuView to handle submenu change.
the subject of your question made me sweat very much in the past 2013.
I studied, analyzed and tested various aspects of Vaadin 7 UIs and Navigator.
I looked a great number of framework, wiki and paper on the subject; related and non related to Vaadin 7.
It was some time ago (in early 2013), I'm not fresh on the subject; anyway these are some of the links I'm able to resurrect:
- Vaadin MVP Lite for Vaadin 6
- MVP4Vaadin - Basic Principle
- Views content switching
- Vaadin 7 Navigator problem - Vaadin forum
- Sub-navigation - Vaadin forum
Our requirements was somewhat similar to the scenario of Vaadin MVP Lite; but we needed more abstraction and flexibility on the composition of the views.
I tried hard to use the provided Navigator but It wasn't easily customizable.
Navigator is a concrete class. UIs can have only one Navigator.
In the Navigator constructor you can find this line:
this.ui.setNavigator(this);
Navigator do a great job for most application with simple needs and provide nice functionality out of the box, but it isn't really intended for extension or customization.
Another aspect to keep in mind is that when changing view with Navigator, you change all the components on screen; you cannot change small bits.
Then I found this guide that put me on a interesting road:
Composing the User Interface, Chapter 7 - MSDN Microsoft
The article is really nice and illuminating; though it has many commonalities with the way Delphi or any other component based framework work, the 'Region' concept was really a bless.
The other chapters are really interesting too (Modular application development, and MVVP).
In the end we adopted the concept of Region with only one UI.
Briefly it works like this:
- There is a GUI component that is able to host other component(s); The places where it can hosts other components are like 'holes'. Each hole is registered and it is a Region bonded to a String name (simple hasmap)
- Through the Region name, one can 'put' another Vaadin component in a Region in order to make it visible.
What happens when the UI is inited is that one Region is registered (the entire UI) as the 'root' Region.
Then a component that represent the login form is hosted in the 'root' region.
If a successful login attempt is made then another component is hosted in the 'root' region (removing the login component); this very component is a host too: it registers another Region called 'main' and have a left side navigation menu too.
Now, if one want to display a component (the welcome page, for example) can retrieve the 'main' Region and put the component to display.
Vaadin Navigator implements bookmarking and back button support.
I was sad because we didn't develop it but it was not a requirement for our application.
IMHO, the Vaadin guys did a hard but good decision keeping Navigator simple; state management is not easily implemented. It would be nice for the future have a Navigator more extensible.
Anyway I think current Navigator respond to most average needs.
My answer is longer then foreseen; I hope my effort can help.