diff options
Diffstat (limited to 'documentation/application/application-architecture.asciidoc')
-rw-r--r-- | documentation/application/application-architecture.asciidoc | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/documentation/application/application-architecture.asciidoc b/documentation/application/application-architecture.asciidoc new file mode 100644 index 0000000000..77c1756594 --- /dev/null +++ b/documentation/application/application-architecture.asciidoc @@ -0,0 +1,258 @@ +--- +title: Building the UI +order: 2 +layout: page +--- + +[[application.architecture]] += Building the UI + +Vaadin user interfaces are built hierarchically from components, so that the +leaf components are contained within layout components and other component +containers. Building the hierarchy starts from the top (or bottom - whichever +way you like to think about it), from the [classname]#UI# class of the +application. You normally set a layout component as the content of the UI and +fill it with other components. + + +[source, java] +---- +public class MyHierarchicalUI extends UI { + @Override + protected void init(VaadinRequest request) { + // The root of the component hierarchy + VerticalLayout content = new VerticalLayout(); + content.setSizeFull(); // Use entire window + setContent(content); // Attach to the UI + + // Add some component + content.addComponent(new Label("Hello!")); + + // Layout inside layout + HorizontalLayout hor = new HorizontalLayout(); + hor.setSizeFull(); // Use all available space + + // Couple of horizontally laid out components + Tree tree = new Tree("My Tree", + TreeExample.createTreeContent()); + hor.addComponent(tree); + + Table table = new Table("My Table", + TableExample.generateContent()); + table.setSizeFull(); + hor.addComponent(table); + hor.setExpandRatio(table, 1); // Expand to fill + + content.addComponent(hor); + content.setExpandRatio(hor, 1); // Expand to fill + } +} +---- + +The component hierarchy could be illustrated with a tree as follows: + + +---- +UI + `-- VerticalLayout + |-- Label + `-- HorizontalLayout + |-- Tree + `-- Table +---- + +The result is shown in <<figure.application.architecture.example>>. + +[[figure.application.architecture.example]] +.Simple Hierarchical UI +image::img/ui-architecture-hierarchical.png[] + +Instead of building the layout in Java, you can also use a declarative design, +as described later in +<<dummy/../../../framework/application/application-declarative#application.declarative,"Designing +UIs Declaratively">>. The examples given for the declarative layouts give +exactly the same UI layout as built from the components above. + +The built-in components are described in +<<dummy/../../../framework/components/components-overview.asciidoc#components.overview,"User +Interface Components">> and the layout components in +<<dummy/../../../framework/layout/layout-overview.asciidoc#layout.overview,"Managing +Layout">>. + +The example application described above just is, it does not do anything. User +interaction is handled with event listeners, as described a bit later in +<<dummy/../../../framework/application/application-events#application.events,"Handling +Events with Listeners">>. + +[[application.architecture.architecture]] +== Application Architecture + +Once your application grows beyond a dozen or so lines, which is usually quite +soon, you need to start considering the application architecture more closely. +You are free to use any object-oriented techniques available in Java to organize +your code in methods, classes, packages, and libraries. An architecture defines +how these modules communicate together and what sort of dependencies they have +between them. It also defines the scope of the application. The scope of this +book, however, only gives a possibility to mention some of the most common +architectural patterns in Vaadin applications. + +The subsequent sections describe some basic application patterns. For more +information about common architectures, see +<<dummy/../../../framework/advanced/advanced-architecture#advanced.architecture,"Advanced +Application Architectures">>, which discusses layered architectures, the +Model-View-Presenter (MVP) pattern, and so forth. + +ifdef::web[] +The +<<dummy/../../../framework/advanced/advanced-global#advanced.global,"Accessing +Session-Global Data">> discusses the problem of passing essentially global +references around, a common problem which is also visited in +<<application.architecture.accessing>>. +endif::web[] + + +[[application.architecture.composition]] +== Compositing Components + +User interfaces typically contain many user interface components in a layout +hierarchy. Vaadin provides many layout components for laying contained +components vertically, horizontally, in a grid, and in many other ways. You can +extend layout components to create composite components. + + +[source, java] +---- +class MyView extends VerticalLayout { + TextField entry = new TextField("Enter this"); + Label display = new Label("See this"); + Button click = new Button("Click This"); + + public MyView() { + addComponent(entry); + addComponent(display); + addComponent(click); + + // Configure it a bit + setSizeFull(); + addStyleName("myview"); + } +} + +// Use it +Layout myview = new MyView(); +---- + +This composition pattern is especially supported for creating forms, as +described in +<<dummy/../../../framework/datamodel/datamodel-itembinding#datamodel.itembinding.formclass,"Binding +Member Fields">>. + +While extending layouts is an easy way to make component composition, it is a +good practice to encapsulate implementation details, such as the exact layout +component used. Otherwise, the users of such a composite could begin to rely on +such implementation details, which would make changes harder. For this purpose, +Vaadin has a special [classname]#CustomComponent# wrapper, which hides the +content representation. + + +[source, java] +---- +class MyView extends CustomComponent { + TextField entry = new TextField("Enter this"); + Label display = new Label("See this"); + Button click = new Button("Click This"); + + public MyView() { + Layout layout = new VerticalLayout(); + + layout.addComponent(entry); + layout.addComponent(display); + layout.addComponent(click); + + setCompositionRoot(layout); + + setSizeFull(); + } +} + +// Use it +MyView myview = new MyView(); +---- + +For a more detailed description of the [classname]#CustomComponent#, see +<<dummy/../../../framework/components/components-customcomponent#components.customcomponent,"Composition +with CustomComponent">>. + + +[[application.architecture.navigation]] +== View Navigation + +While the most simple applications have just a single __view__ (or __screen__), +perhaps most have many. Even in a single view, you often want to have sub-views, +for example to display different content. +<<figure.application.architecture.navigation>> illustrates a typical navigation +between different top-level views of an application, and a main view with +sub-views. + +[[figure.application.architecture.navigation]] +.Navigation Between Views +image::img/view-navigation-hi.png[] + +The [classname]#Navigator# described in +<<dummy/../../../framework/advanced/advanced-navigator#advanced.navigator,"Navigating +in an Application">> is a view manager that provides a flexible way to navigate +between views and sub-views, while managing the URI fragment in the page URL to +allow bookmarking, linking, and going back in browser history. + +Often Vaadin application views are part of something bigger. In such cases, you +may need to integrate the Vaadin applications with the other website. You can +use the embedding techniques described in +<<dummy/../../../framework/advanced/advanced-embedding#advanced.embedding,"Embedding +UIs in Web Pages">>. + + +[[application.architecture.accessing]] +== Accessing UI, Page, Session, and Service + +You can get the UI and the page to which a component is attached to with +[methodname]#getUI()# and [methodname]#getPage()#. + +However, the values are [literal]#++null++# until the component is attached to +the UI, and typically, when you need it in constructors, it is not. It is +therefore preferable to access the current UI, page, session, and service +objects from anywhere in the application using the static +[methodname]#getCurrent()# methods in the respective [classname]#UI#, +[classname]#Page#, [classname]#VaadinSession#, and [classname]#VaadinService# +classes. + + +[source, java] +---- +// Set the default locale of the UI +UI.getCurrent().setLocale(new Locale("en")); + +// Set the page title (window or tab caption) +Page.getCurrent().setTitle("My Page"); + +// Set a session attribute +VaadinSession.getCurrent().setAttribute("myattrib", "hello"); + +// Access the HTTP service parameters +File baseDir = VaadinService.getCurrent().getBaseDirectory(); +---- + +You can get the page and the session also from a [classname]#UI# with +[methodname]#getPage()# and [methodname]#getSession()# and the service from +[classname]#VaadinSession# with [methodname]#getService()#. + +The static methods use the built-in ThreadLocal support in the classes. + +ifdef::web[] + The pattern is described in +<<dummy/../../../framework/advanced/advanced-global#advanced.global.threadlocal,"ThreadLocal +Pattern">>. +endif::web[] + + + + |