Using Navigator for creating bookmarkable applications with back-forward button support
Vaadin 7 has introduced a new capability for easy creation of bookmarkable applications with back and forward button support: the Navigator.
We will see how to use the Navigator
class and what is needed to get it working. Navigator
works with views, layouts that implement the View
interface.
We are going to make an application with two views. We will be able to navigate between these two views with the back and forward buttons or make a bookmark.
The first view will be the welcome view, which we map to an empty URL fragment, so it becomes accessible at http://localhost:8080 address
.
When a user clicks on the Open new Orders button, the orders view is displayed with the orders URL fragment.
How to do it...
Carry out the following steps to learn how to work with Views
in Vaadin 7:
- Create a new Vaadin project with the main UI class called, for example,
MyVaadinUI
. - Create the welcome view that will show a flattering label with the greeting Welcome back handsome.
public class WelcomeView extends VerticalLayout implements View { public static final String VIEW_NAME = ""; public WelcomeView() { Label lblWelcome = new Label("Welcome back handsome."); addComponent(lblWelcome); Button btnOrders = new Button("Open new Orders"); btnOrders.addClickListener(new Button.ClickListener() { @Override public void buttonClick(Button.ClickEvent clickEvent) { UI ui = UI.getCurrent(); Navigator navigator = ui.getNavigator(); navigator.navigateTo(OrdersView.VIEW_NAME); } }); addComponent(btnOrders); } @Override public void enter(ViewChangeListener.ViewChangeEvent event){ } }
- Create a new view for orders and also, place there a label, which indicates we are browsing the orders.
public class OrdersView extends VerticalLayout implements View { public static final String VIEW_NAME = "orders"; public OrdersView() { Label lblOrders = new Label("New orders: "); addComponent(lblOrders); } @Override public void enter(ViewChangeListener.ViewChangeEvent event) { // for example: load / reload data from database } }
- Create a new UI class and set up the navigator.
public class MyVaadinUI extends UI { @Override protected void init(VaadinRequest request) { Navigator navigator = new Navigator(this, this); navigator.addView(WelcomeView.VIEW_NAME, new WelcomeView()); navigator.addView(OrdersView.VIEW_NAME, OrdersView.class); navigator.navigateTo(WelcomeView.VIEW_NAME); } }
- Run the application and click on the Open new Orders button. Orders view appears and when we click on the back button in the browser, we will be returned to the welcome view.
How it works...
We have made a new instance of Navigator
in the init
method. Then we have added two views into the navigator and we have commanded the navigator to navigate to WelcomeView
.
The first view has been added as a new instance of the WelcomeView
class. That way, we ensure there will be only one instance of the WelcomeView
class created for all navigation events.
navigator.addView(WelcomeView.VIEW_NAME, new WelcomeView());
The second view has been initialized via the OrdersView
class. Setting a class instead of an instance is the opposite approach to setting an instance of a view to the navigator. Because when we add a class as a view to the navigator, a new instance of the view class is created for each navigation event.
navigator.addView(OrdersView.VIEW_NAME, OrdersView.class);
Both Welcome and Orders views are created as layouts that implement the View
interface and contain a static field VIEW_NAME
that defines the name of the view that is going to be set as a fragment into the URI.
When a view is being opened, the enter
method is called. For example, we could fetch data from the database in the enter
method, instead of fetching data in the constructor. The reasoning why we don't touch the database in a constructor is that, when we have tied I/O operations with the constructor, the class will become difficult to test.
There's more...
We can pass additional parameters into the view. We just extend the link with additional parameters, for example, http://localhost:8080/#!order/detail/1
.
Then we get the parameters in the enter
method. The parameters variable contains detail/1
string from the previous example.
public void enter(ViewChangeListener.ViewChangeEvent event) { String parameters = event.getParameters(); addComponent(new Label(parameters));