Vaadin 7 UI Design By Example:Beginner’s Guide
上QQ阅读APP看书,第一时间看更新

Thinking in Vaadin

Your brain must have started to feel comfortable using UI components such as labels, text fields, comboboxes, buttons, vertical layouts, and notifications. You know how to respond to events on these components by implementing click listeners and value change listeners. You can get the introduced (or selected) values from input components, and you can wire all this up inside a custom class extending Vaadin's UI.

The rest of the trip in this book is about learning more components, how to respond to events on components, and how to make them look as we want them to look. To prepare your brain for this trip, we will right now cover some basic theory about Vaadin. So relax, close your IDE for a little while, and let your fingers have a rest while we learn some nuts and bolts of Vaadin.

Servlets and GWT

How can Vaadin render all those nice widgets on the browser using only an instance of a class (the one that extends UI)? Let's expose Vaadin's magic.

We can easily think of the browser making requests to a web server. In fact, the first thing we do when we are using a Vaadin application is to request a URL, something like http://localhost:8080/webapp. When we do this, the server will respond with an HTML page that the browser is able to render. The server (or web container in the Java ecosystem) is a software component that understands HTTP operation quite well. What the server doesn't understand well are our particular requirements, so the server just delegates that part to other components. We create these components, and we do it by using a powerful Java technology called servlet.

Servlet is a class that processes requests and constructs responses. We map URLs with the Servlet classes in a web deployment descriptor (web.xml). For example:

<servlet>
  <servlet-name>My servlet</servlet-name>
  <servlet-class>my.package.MyVeryOwnServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>My servlet</servlet-name>
  <url-pattern>/myurl/*</url-pattern>
</servlet-mapping>

With this configuration, an instance of my.package.MyVeryOwnServlet will be created and invoked when a URL such as http://localhost:8080/webapp/myurl is requested. We are not covering the details of Servlet technology here, just make sure you understand that the MyVeryOwnServlet class will generate a response (probably an HTML response) when the mapped URL is invoked. This response contains the HTML that the browser will render as depicted in the following figure:

Well, it turns out that Vaadin comes with a Servlet implementation, com.vaadin.server.VaadinServlet. We use this ready-to-use Servlet class to create Vaadin applications. VaadinServlet will handle all the HTTP requests for us. That's nice, but, how the heck can VaadinServlet construct an HTML response showing all our UI components? When you configure VaadinServlet in your web.xml file (actually the IDE does it for us when we create a new Vaadin project), you must give the fully qualified name of your UI class as a parameter of the servlet, as shown in the following code snippet:

<init-param>
  <description>Vaadin UI class to use</description>
  <param-name>UI</param-name>
  <param-value>my.package.MyUI</param-value>
</init-param>

This goes inside the <servlet> tag in web.xml. Here we are connecting our logic with the ready-to-use servlet, VaadinServlet. Now, it is able to create an instance of our UI class and start working to generate the HTML response for us based on the components tree that we have constructed:

It seems to be that VaadinServlet has a lot of work to do now. Well, it certainly has, but VaadinServlet takes advantage of another cool technology: Google Web Toolkit (or GWT for short). It is a set of open source tools to develop web applications based on HTML and JavaScript.

Web application development is basically the process of creating applications that are to be shown on a web browser. The browser understands HTML and JavaScript, so we ultimately have to generate HTML and JavaScript to build web user interfaces. This means that most of the time you must be proficient enough with HTML, JavaScript, and the backend programming language (probably Java). When a new developer joins your team, you must be sure that the new guy knows these languages well, right? Not at all if you are using GWT (and Vaadin of course!).

GWT, and therefore Vaadin, are capable of converting your Java UI classes into equivalent JavaScript. Actually, what GWT does is to compile your Java code and generate JavaScript that communicates with your server-side components. By using GWT solely you are using a client-side technology. GWT takes your classes and compiles them to JavaScript. You still need to handle all the communication happening between the client and the server, so you will end up with some classes being compiled to JavaScript and some classes handling the communication and server-side logic. Vaadin hides the complexity of developing this communication logic by providing an API on top of GWT, while still allowing you write pure client-side applications. Vaadin is like an augmented version of GWT.

Back to the servlet part, VaadinServlet takes advantage of GWT to generate JavaScript and HTML while adding all the client/server communication plumbing for you. This will lead to simpler architectures in your applications.

UI components hierarchy

UI components form an interesting hierarchy. Take a look at the main interfaces and abstract classes in the hierarchy:

Component

The Component interface is the root of the hierarchy, which means that you can assign any UI component to a Component reference. We have already used a method declared in this interface, the setDescription method (to display tooltips). This class also declares methods (usually getters and setters) to deal with common properties of UI components. The following table shows some of these properties:

The following is the list of components seen in the previous figure:

  • AbstractComponent provides a default implementation for all the methods in the Component interface, plus some methods to handle size, errors, and immediate mode.
  • The ComponentContainer interface defines common methods to add and remove components to other components.
  • The AbstractComponentContainer class extends AbstractComponent and defines the default implementation for all the methods in ComponentConainer. So, an AbstractContainer interface is AbstractComponent, and of course, you can use it as a Component. Additionally, you can add and remove components to it.
  • Layout is an extension of ComponentContainer that defines inner interfaces to handle alignment, spacing, and margin.
  • The AbstractLayout class extends AbstractComponentContainer and defines the default implementation for all the methods in Layout.
  • The AbstractOrderedLayout class is the base class for layouts that need to keep components in linear order. VerticalLayout extends this class.
  • The Field interface is the base interface for input components.
  • The AbstractField class extends AbstractComponent and provides basic functionality for input components. TextField and Button are the examples of the classes extending AbstractField.
  • AbstractSelect is a base class for input components that allows users to select items. ComboBox is the component of an AbstractSelect class.

Vaadin's data model

UI components can manage data using a simple yet powerful generic data model. This model is an abstraction that allows UI components to be bound to several data sources, such as filesystems or databases.

Note

Data binding is the process of establishing a connection between UI components and data sources. If the data changes then UI components act accordingly.

The data model is a central topic when developing Vaadin applications. It provides a framework for implementing any representation of the underlying data. This means that it's possible to represent (or display) any kind of data, from filesystems to database queries. Vaadin has a number of ready-to-use implementations of the data model and they are used as the default data model for many of the input components.

The model breaks up the data in three main concepts: properties, items, and containers. In short, a container has many items and an item has many properties.

Well, we have been talking too seriously for too many paragraphs; it's time to have some fun.