You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CreatingABookmarkableApplicationWithBackButtonSupport.asciidoc 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. ---
  2. title: Creating A Bookmarkable Application With Back Button Support
  3. order: 55
  4. layout: page
  5. ---
  6. [[creating-a-bookmarkable-application-with-back-button-support]]
  7. Creating a bookmarkable application with back button support
  8. ------------------------------------------------------------
  9. Vaadin 7 comes with a new set of APIs to aid creation of navigation
  10. within your application. The main concepts are *Navigator* and *View*,
  11. and using these you can easily create an application that supports the
  12. standard browser methods for navigation; bookmarking, history, back- and
  13. forward navigation using browser buttons. This is (usually) done using
  14. browser "fragments" (the stuff after the #-character in the URI).
  15. At the same time, the API provides a natural way of partitioning your
  16. application into views - something most applications did previously
  17. anyway, but previously without framework 'guidance'.
  18. Let's start by making a View that counts the times it has been created.
  19. This is a simple example, but will later shed some light on when Views
  20. are created, but let's not worry about that just yet:
  21. [source,java]
  22. ....
  23. import com.vaadin.navigator.View;
  24. import com.vaadin.ui.Label;
  25. import com.vaadin.ui.Panel;
  26. public class CountView extends Panel implements View {
  27. public static final String NAME = "count";
  28. private static int count = 1;
  29. public CountView() {
  30. setContent(new Label("Created: " + count++));
  31. }
  32. public void enter(ViewChangeEvent event) {
  33. }
  34. }
  35. ....
  36. We'll extend Panel as a convenient base, and add a Label to that in the
  37. constructor, updating the static count. The _enter()_ -method comes from
  38. View, and is called when our View is activated, but we'll do nothing
  39. about that in our simplistic View.
  40. Note the _static final NAME_: we'll use it instead of a 'magic' string
  41. when we register the View with the Navigator later. Feel free to use any
  42. method you like to keep track of your View-names (e.g Enum, simpleName
  43. of the View's class, and so on…)
  44. In order to do any navigating, we'll need at least two views, so let's
  45. create a main view that has a link to the counting view we just created.
  46. [source,java]
  47. ....
  48. import com.vaadin.navigator.View;
  49. import com.vaadin.server.ExternalResource;
  50. import com.vaadin.ui.Link;
  51. import com.vaadin.ui.Panel;
  52. public class MainView extends Panel implements View {
  53. public static final String NAME = "";
  54. public MainView() {
  55. Link lnk = new Link("Count", new ExternalResource("#!"
  56. + CountView.NAME));
  57. setContent(lnk);
  58. }
  59. public void enter(ViewChangeEvent event) {
  60. }
  61. }
  62. ....
  63. Note the empty string used as _NAME_. This is because we want this to be
  64. our main ("home") View, displayed before any navigation is done.
  65. In this example we use a Link and let the browser do the navigating. We
  66. could just as easily use a Button and tell the Navigator where we want
  67. to go when the button's ClickListener is invoked. Note that we're using
  68. _CountView.NAME_, and what we're actually doing is using the "fragment"
  69. part of the application URI to indicate the view. The resulting URI will
  70. look something like http://.../application#!count .
  71. Ok, one last thing: we need to set up a UI with a Navigator, and
  72. register our views:
  73. [source,java]
  74. ....
  75. import com.vaadin.navigator.Navigator;
  76. import com.vaadin.navigator.Navigator.SimpleViewDisplay;
  77. import com.vaadin.server.Page;
  78. import com.vaadin.server.WrappedRequest;
  79. import com.vaadin.ui.UI;
  80. public class NavigationtestUI extends UI {
  81. @Override
  82. public void init(VaadinRequest request) {
  83. // Create Navigator, use the UI content layout to display the views
  84. Navigator navigator = new Navigator(this, this);
  85. // Add some Views
  86. navigator.addView(MainView.NAME, new MainView()); // no fragment
  87. // #!count will be a new instance each time we navigate to it, counts:
  88. navigator.addView(CountView.NAME, CountView.class);
  89. // The Navigator attached to the UI will automatically navigate to the initial fragment once
  90. // the UI has been initialized.
  91. }
  92. }
  93. ....
  94. There are advanced ways to use the Navigator API, and there are simple
  95. ways. Most applications will do fine with the simple ways, and the
  96. Navigator constructor we used is written that in mind. It simply takes
  97. any ComponentContainer, assumes that all our Views are also Components,
  98. and on a view change sets the given view as the ComponentContainer's
  99. only child. Internally, it uses a _ViewDisplay_ subclass called
  100. ComponentContainerViewDisplay to do this. If we had more advanced
  101. requirements, we could write our own ViewDisplay subclass to show our
  102. views in whatever fashion we'd like.
  103. The Navigator finds out about URI fragment changes through the Page, and
  104. directs the ViewDisplay accordingly. We register our Views using
  105. _addView()_ so that the Navigator knows how to connect fragments with
  106. Views. Again notice how we use the static NAME instead of
  107. _addView("name", view)_ - but feel free to use other approaches.
  108. In order to illustrate how the two differ, we register an _instance_ of
  109. the MainView, but _CountView.class_. As a result, the MainView is
  110. created once, when the UI is created, and lives as long as the UI lives.
  111. On the other hand, a new CountView instance will be created each time we
  112. navigate to it (but no earlier). You can try navigating back-and-forth
  113. and see how the count is updated - try registering it using new
  114. CountView() instead…
  115. It's also good to keep in mind that a new UI is created each time you
  116. press reload in the browser, unless you use the @PreserveOnRefresh
  117. annotation on the UI.