Vaadin – Using Input Components and Forms

Exclusive offer: get 50% off this eBook here
Vaadin 7 UI Design By Example: Beginner’s Guide

Vaadin 7 UI Design By Example: Beginner’s Guide — Save 50%

Build exciting Vaadin applications in no time with this book and ebook

$29.99    $15.00
by Alejandro Duarte | August 2013 | Beginner's Guides Open Source

Vaadin is an open source framework to ease development of Java web applications that provides a programming model close to Swing or AWT. Vaadin is licensed under the Apache License, is well documented, comes with out-of-the-box theming facilities, and is supported by a committed company and a vibrant community contributing to the framework through forums and hundreds of add-ons. Vaadin allows developers to write web applications using only Java. Of course, HTML, CSS, and JavaScript are building blocks of web application development, however, by using Vaadin, developers will be maintaining Java code most of the time.

In this article, by Alejandro Duarte, the authors of Vaadin 7 UI Design By Example Beginner's Guide, we will take a closer look at the main components for retrieving and processing all the data that users want your application to be aware of. This article will cover the following topics:

  • Separating business classes from UI classes
  • Responding to value changes in input components
  • Getting and setting the value of input components
  • Tooltips and error indicators
  • Underlying Vaadin technologies
  • UI components hierarchy
  • Vaadin's data model
  • Comboboxes, checkboxes, text areas, option groups, twin column selects, and date/time pickers
  • File uploading

(For more resources related to this topic, see here.)

The Time It application

A couple of years ago I was working with some friends on a personal Java project. We used to meet every Saturday to review what we had done before building the entire system. Let me introduce you to my friends: Susan Obstinate and Mark Nowsitall (weird last names, aren't they?).

"I've spent the entire week writing this code, but it's ready now," said Susan with an embittered tone.

"Let me see how you handled that," replied Mark suspiciously. Though they didn't seem to be, they were a couple.

So Susan proudly showed us her piece of code:

// some nasty code was here (censored for respect of the reader) public String getUglyUrl(long total) { String url = "http://localhost/app/someservice?code="; for(long i = 0; i < total; i++) { url += someTrickyMath(i); } return url; } public String someTrickyMath(long i) { // (censored) }

"We can use an int object type instead of long for the loop in your getUglyUrl method," instantly affirmed Mark.

"I don't think we need that," said Susan.

"You could also use a StringBuilder class to..." I started to say, but suddenly got interrupted by Mark.

"An int object type would improve performance a lot. The int comparisons and manipulations are faster than long ones," Mark explained.

"What if the total gets too big? We'd need a long object type then," Susan argued.

"Total has never gone beyond 10,000 and I highly doubt it will in the near future," Mark replied.

We (actually it was Mark) finally managed to convince Susan to change her code.

There are lots of situations similar to this one, more complicated, and with tons of external factors that make it hard to be 100 percent sure about which of two code strategies will work faster. Let's take advantage of this story and develop a nice Vaadin application for timing code.

Introducing: Time It! The application that will show some facts to Susan.

Time for action – separating business classes from UI classes

Vaadin is mostly about UI. Vaadin's motto thinking of U and I is not in vain. I said mostly because you can additionally find a bunch of useful add-ons to deal with server-side technologies. Even Vaadin itself ships with some data components.

Most, if not all, applications have some kind of business logic. That is, something to do with the application's data. If you are an experienced developer you will agree with me that separating business logic from UI logic makes a lot of sense. For the "Time It" application, we will use two Java packages to separate business logic from UI logic:

  1. Create a new Vaadin project named time-it using your IDE.
  2. Delete the all the generated classes. We will add our own classes in a minute.
  3. Create the following package. Don't worry about the classes right now. Just create the Java packages timeit, timeit.biz, timeit.biz.test, and timeit.ui:

  4. Browse the book's source code and copy all the classes inside the biz package and paste them into your own biz package. Don't copy TimeItUI.java, we will work on that through the article.
  5. Create a new class with the TimeItUI name inside the ui package.
  6. Update your web.xml file to use TimeItUI as the starting application:

    <servlet> <servlet-name>Time It</servlet-name> <servlet-class>com.vaadin.server.VaadinServlet</servlet-class> <init-param> <description> Vaadin UI class to use</description> <param-name>UI</param-name> <param-value>timeit.ui.TimeItUI</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Time It</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>

  7. Let's start with an outline of our TimeItUI class. Modify your TimeItUI class to match something like this:

    public class TimeItUI extends UI { ... some variables ... @Override protected void init(VaadinRequest request) { ... } private void initCombo() { ... } private void initButton() { ... } private void initLayout() { ... } public boolean validate() { ... } public void runSelectedTest() { ... } private void showResults(Collection<String> results) { ... } }

What just happened?

Of course, the TimeItUI class won't compile. But now you have an outline with the structure of methods we will implement through the article. Just keep reading.

Most of the application is about business (the biz package) with only one class handling our UI logic. However, we will focus on the UI part. Business classes are not puzzling at all. We will use them as black boxes in our TimeItUI class (that's the reason we are just copying them).

Time for action – adding components as class members

To add UI components as class members, edit your TimeItUI class by adding these variables to it:

private static final TestSet[] testSets = new TestSet[] { new LongVsInt(), new StringVsStringBuffer(), new ShortCircuitVsNoShortCircuit() }; private VerticalLayout layout = new VerticalLayout(); private ComboBox combo = new ComboBox("Test"); private final TextField textField = new TextField("Number of iterations", "1000"); private CheckBox checkBox = new CheckBox("Keep previous results"); private Button button = new Button("Time it!"); private VerticalLayout resultsLayout = new VerticalLayout();

What just happened?

The first thing you see, testSets, is just an array of business objects, specifically, an array containing instances of TestSet (take a look at the TestSet interface in the book's source code). Think of TestSet as a single scenario from which we want to obtain timing results. For example, the LongVsInt class will run two tests: one to time a loop controlled by a long object type and another to time a loop controlled by an int object type. If you want to add some testing scenarios, all you must do is to implement the TestSet interface and add a new instance to the testSets array.

Time for action – adding some infrastructure

Edit the init method of your TimeItUI class to match the following:

@Override protected void init(VaadinRequest request) { initCombo(); initButton(); initLayout(); }

What just happened?

Here we are breaking up the functionality to initialize our UI components in a more suitable way by implementing smaller methods. Now that we have the required infrastructure, we can start adding input components.

Comboboxes

A combobox is an input component that allows users to select an option from a drop-down list. It looks like the following screenshot:

You must be thinking "yeah right, but how do you put those options in there?" This is easy:

ComboBox c = new ComboBox("Select an option"); c.addItem("Option one"); c.addItem("Option two"); c.addItem("Option three");

If you have the options in a Java Collection class, you can pass the Collection instance to the constructor like this:

ArrayList<String> options = new ArrayList<>(); options.add("Option 1"); options.add("Option 2"); options.add("Option 3"); ComboBox c = new ComboBox("Select an option", options);

The method addItem accepts an Object, so we can pass instances of any class. For example, if we had a User class we could have done this:

User user1 = new User("Jurka", "Rahikkala"); User user2 = new User("Joonas", "Lehtinen"); ComboBox c = new ComboBox("Select a user"); c.addItem(user1); c.addItem(user2);

Now, how will the ComboBox component know what to print as option captions? First, let's go back to our "Time It" application.

Time for action – adding a combobox

Implement the initCombo method of your TimeItUI class as shown in the following code snippet:

private void initCombo() { for(TestSet testSet : testSets) { combo.addItem(testSet); combo.setitemCaption(testSet, testSet.getTitle()); } combo.addValueChangeListener(new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { TestSet testSet = (TestSet) combo.getValue(); textField.setValue("" + testSet.getDefaultTimes()); button.setDescription(testSet.getDescription()); } }); combo.setimmediate(true); }

What just happened?

It's not that complicated. If we isolate the for portion of the previous code, we'll get this:

for(TestSet testSet : testSets) { combo.addItem(testSet); combo.setitemCaption(testSet, testSet.getTitle()); }

For each TestSet instance in our array, we add a TestSet instance and then we say, "Okay, Vaadin for this testSet array I just added, please show what testSet.getTitle() returns. Thank you very much". We are adding instances of TestSet and explicitly specifying what we want to be shown for each option inside the ComboBox component.

Responding to value changes

So, we have our combo ready and showing all available tests. If you have already played with the application, you may have noted that when you select a test, the number of iterations shown in the text field and the button tooltip explaining the test are updated accordingly. Well, the rest of the initCombo method implements this functionality.

Here, We are adding a ValueChangeListener instance to execute our code when the user selects an option:

combo.addValueChangeListener(new ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { // your code here } });

Getting and setting the value of input components

The user selects one option, the valueChange method of our anonymous listener is called, and now we can update the value in textField. That's one line of code:

textField.setValue(theValue);

Wait... how do we know what is the selected value in the combobox? If setValue is for setting the value, then getValue is for getting the value! Unbelievable! Let's get the value:

TestSet testSet = (TestSet) combo.getValue();

Now that we have the value, we can easily set the text in the textField:

textField.setValue("" + testSet.getDefaultTimes());

We've just learned something valuable (it's not wordplay): input components, they all have the getValue and setValue methods.

Tooltips

A tooltip is boxed text that appears when the user holds the mouse pointer over a UI element. The following screenshot shows a Vaadin tooltip:

Adding tooltips is a piece of cake. All we need to do is the following:

button.setDescription(testSet.getDescription());

Most UI components include this method. You can put any HTML you want to nicely format your tooltips.

Immediate mode

There is just one final line that we have not explained yet in the initCombo method:

combo.setimmediate(true);

This makes the component respond as soon as the user changes its value (and after the component loses focus). If we don't put this line, when the user changes the value, Vaadin could say "Okay, I will wait for some more events before I send that change in combo". This is not only for the ComboBox component, all input components have this method too.

Error indicators

We must provide feedback to the user when the input is incorrect. Error indicators are a way to provide such feedback.

Time for action – validating user input

We can run a TestSet instance only if the user selects one. Follow these steps to add a proper validation:

  1. Implement your initButton method to match this code:

    private void initButton() { button.addClickListener(new ClickListener() { @Override public void buttonClick(ClickEvent event) { if(isValid()) { runSelectedTest(); } } }); }

  2. Now implement your validate method. Here is how we validate:

    public boolean isValid() { combo.setComponentError(null); textField.setComponentError(null); boolean isValid = true; if(combo.getValue() == null) { combo.setComponentError( boolean isValid = true; if(combo.getValue() == null) { combo.setComponentError( new UserError("Select a test from the list.")); isValid = false; } if(textField.getValue().toString().isEmpty()) { textField.setComponentError(new UserError( "You must introduce the number of iterations to execute")); isValid = false; } return isValid; }

What just happened?

We have a button and we want to respond to click events, so we add ClickListener, using an anonymous class.

As you can see, if the isValid method returns true, we proceed to run the selected test. First two lines of the method are for clearing any error we may have added to the components in previous executions of the isValid method itself. Then, we declare a flag that will tell us whether the components have valid values or not. If the selected value in combo is null, we add an error message to the component using the following code line:

combo.setComponentError(new UserError("Select a test from the list."));

setComponentError expects an instance of ErrorMessage. UserError is an implementation of the ErrorMessage interface that allows us to show an error message on the component. Usually, the component will show an error indicator. If the user places the mouse cursor over the component, a tooltip will appear showing the error text:

A similar logic is used to show an error over textField if the users left it empty.

Layout spacing

We have our components ready. We know how they respond to events (clicks and value changes) and how they communicate. We still have to know how the tests are executed and how the results are shown. But first, let's incorporate all those components into the main layout.

Time for action – adding input component into the layout

Implement your initLayout method using the following snippet of code:

private void initLayout() { layout.setMargin(true); layout.setSpacing(true); layout.addComponent(combo); layout.addComponent(textField); layout.addComponent(checkBox); layout.addComponent(button); layout.addComponent(resultsLayout); setContent(layout); }

What just happened?

We let the layout to have an appropriate margin and spacing. This last one adds some space between components instead of having them bonded inside the layout. Following that, we add combo, textField, checkBox, button, and a VerticalLayout component to put some labels for showing the results of the test case execution. Finally, the last statement sets layout as content of the page.

Checkboxes

Everyone knows checkboxes. Have you ever accepted license agreements during software installations? Just in case, this is a checkbox:

We have already created our checkbox:

private CheckBox checkBox = new CheckBox("Keep previous results");

Removing components from layouts

Before explaining how we show the results, let's see how we can execute the selected TestSet instance.

Vaadin 7 UI Design By Example: Beginner’s Guide Build exciting Vaadin applications in no time with this book and ebook
Published: July 2013
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

Time for action – running the test set

Implement your runSelectedTest method. This method will be called when the user presses the Time it! button:

public void runSelectedTest() { Long times = Long.parseLong(textField.getValue()); Collection<String> results = TestSetExecutor.execute( (TestSet) combo.getValue(), times); showResults(results); }

What just happened?

Here, we're converting the string stored in the text field to a Long number using Long.parseLong (a potential exception, NumberFormatException, pokes its head).

Once we have the Long value, we execute the results using a helper class in the biz package (TestSetExecutor). This helper class has an execute method that expects the TestSet to execute and the number of iterations to perform for each test in the TestSet. The execute method returns all the results as a collection of strings that we can proudly show to the user. As proudly as Susan when she presented her code.

Have a go hero – add a validation to Time It

When converting the value in textField, the method parseLong will throw an evil NumberFormatException if the string to parse is not a number. Try it! Use "Time It" and type a wrong numeric expression in the text field. Now try making "Time It" a production-ready application by adding the missing validation (inside the isValid method) to show a proper error message when incorrect input is given for the textField component.

Time for action – showing the results

The default behavior of the application is to show only the results of the last execution. We need to remove all the results that have been previously added to the resultsLayout component if the user has not checked Keep previous results. To do that, implement your showResults method:

private void showResults(Collection<String> results) { if(!checkBox.getValue()) { resultsLayout.removeAllComponents(); } else if(resultsLayout.getComponentCount() > 0) { resultsLayout.addComponent(new Label("--")); } for(String result : results) { resultsLayout.addComponent(new Label(result)); } }

What just happened?

If the checkbox is not checked, we can remove all the components in resultsLayout (not in layout, we don't want baffled users here):

resultsLayout.removeAllComponents();

If we don't have to remove previous results, we add a separator and iterate over the results to add each one using a label.

Congratulations! We have finished a useful application. Try implementing your own test sets and learn more about Java performance.

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 article 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:

Property

Methods in Component

Description

Enabled

isEnabled()

setEnabled(boolean)

If enabled, the user cannot interact with the component.

Caption

getCaption()

setCaption(String)

The caption is the text that allows the user to know the component intention. Most of the times we give the caption using a constructor.

Visible

isVisible()

setVisible(boolean)

Visible components are shown, invisible component are not.

Read only

isReadOnly()

setReadOnly(boolean)

Users cannot change the value of read only components.

Icon

geticon()

seticon(Resource)

An icon is an image accompanying the component.

Parent

getParent()

Returns the parent component in the components tree.

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.

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.

Time for action – binding data to properties

There's no better way to learn than practice. Follow these steps to see how binding works in real life:

  1. Create a new project named binding using your IDE. A Vaadin one, of course.
  2. Don't hesitate and delete all the content in the generated BindingUI class.
  3. Create a new local instance of TextField and turn immediate mode on:

    @Override protected void init(VaadinRequest request) { TextField textField = new TextField("Data"); textField.setimmediate(true); }

  4. Create a new local instance of Label:

    Label label = new Label();

  5. Add the TextField and Label components to a new VerticalLayout and set it to be the content of the UI:

    VerticalLayout layout = new VerticalLayout(); layout.addComponent(textField); layout.addComponent(label); setContent(layout);

  6. Nothing new so far, so create a new instance of the ObjectProperty class:

    ObjectProperty<String> property = new ObjectProperty<String>("the value");

  7. Wow, that was new. More newness, bind the property to the UI components:

    textField.setPropertyDataSource(property); label.setPropertyDataSource(property);

  8. Deploy and run the application. Try changing the value in the textField component. While testing the application, make sure you click out of the textField or press Tab after changing its value, so the change will be sent to the server.

What just happened?

We bound two UI components to a single data source. One of the components (TextField) is capable of changing the data source (ObjectProperty) while the other just displays the data in the data source. Here is a screenshot:

If you change the value in the TextField component, it will in turn change the data source, causing the Label component to display the new value. textField and label are both connected to the same data source via the ObjectProperty instance:

This is useful because we can easily attach a single data source to multiple views (UI components).

What is property anyway? It is an object containing a value of a certain type. In the previous example, the type was String. The Property class is an interface, and Vaadin provides several implementations for this interface. We are using the ObjectProperty implementation that allows us to wrap any Java object into a property.

The Property interface has some methods to get and set the value, to get and set the read only state, and to get the type of the stored value. This is a graphical depiction of a property:

Items

Items are a way to group properties. Before grouping the properties each one receives an ID, the property ID (or PID):

Think of a Java object. It has several properties each one with its own name. For example:

class User { String login = "bill"; String password = "pass"; Boolean enabled = true; }

We can model this data abstraction using properties and items:

Items are used in components that deal with more complex data than labels or text fields. For example, Vaadin includes a FormGroup class that can be bound to an item.

Containers

Last, but not least, a container is a way to group items. And again, before grouping the items, each one receives an ID, the item ID (or IID):

Two common Vaadin components that can be bound to containers are Table and Tree.

More input components

It's time to continue with our trip. Vaadin has several built-in input components (or fields as they implement directly or indirectly the Field interface). All these components extend from AbstractField or AbstractSelect. Let's take a look at some of them.

Text area

TextArea is quite similar to TextField. The difference is that the user can enter multiline texts. Take a look at this sample application:

public class TextareaUI extends UI implements ValueChangeListener { @Override protected void init(VaadinRequest request) { // our TextArea component TextArea textArea = new TextArea( "Enter some multi-lined text and press TAB:"); textArea.addValueChangeListener(this); textArea.setimmediate(true); VerticalLayout layout = new VerticalLayout(); layout.addComponent(textArea); setContent(layout); } @Override public void valueChange(ValueChangeEvent event) { String userText = event.getProperty().getValue() .toString(); Notification.show("This is it: " + userText); } }

That's easy. It's the same as using TextField. We create an instance and add it to some layout. We are not using an anonymous class for ValueChangeListener this time. We let TextAreaUI implement ValueChangeListener and define the corresponding valueChange method.

Have a go hero – disable word wrap

By default, TextArea will word wrap the text in the field. However, you can disable this by using the setWordwrap method. Try it! Call this method giving false as parameter and test the application typing a long word like honorificabilitudinitatibus.

Rich text area

A RichTextArea component allows complex styling and formatting. Take a look at the example application:

Here is what goes in the init method:

RichTextArea richText = new RichTextArea("Rich text area:"); richText.setimmediate(true); Label label = new Label(richText, ContentMode.HTML); VerticalLayout layout = new VerticalLayout(); layout.addComponent(richText); layout.addComponent(label); setContent(layout);

Pretty straightforward except for the Label constructor. The constructor we are calling is this:

public Label(Property contentSource, ContentMode contentMode)

Is RichTextArea a Property? That makes no sense! In fact it makes a lot of sense. A Field interface stores a typed value, and Property is just that. Remember we saw that AbstractField is the default implementation of the Field interface? Well, Field itself extends Property. So any Field is a Property too.

Option groups

OptionGroup is an alternative to ComboBox, it allows the user to select elements. The usage is similar to ComboBox:

OptionGroup og = new OptionGroup( "Are you enjoying the book?"); og.addItem("Oh yeah"); og.addItem("Kind of"); og.addItem("Not really");

This is how the previous OptionGroup code would be rendered:

Hope you agree with the answer in the screenshot. You can easily disable individual options. For example, to disable the Kind of option, we can use this line of code:

og.setitemEnabled("Kind of", false);

If you want to use HTML on the options, use this code:

og.setHtmlContentAllowed(true);

Now take a look at this example:

public class OptiongroupUI extends UI implements ValueChangeListener { @Override protected void init(VaadinRequest request) { // an array with the options ArrayList<String> answers = new ArrayList<String>(); answers.add("Vaadin beans"); answers.add("Session beans"); answers.add("Enterprise App for Vaadin beans"); answers.add("Message-driven beans"); // our OptionGroup component OptionGroup og = new OptionGroup( "Two kinds of EJBs in Java EE are:", answers); og.addValueChangeListener(this); og.setimmediate(true); // our main layout VerticalLayout layout = new VerticalLayout(); layout.addComponent(og); setContent(layout); } @Override public void valueChange(ValueChangeEvent event) { String answer = event.getProperty().getValue().toString(); Notification.show("Your answer: " + answer); } }

Note that we are getting the value in OptionGroup through the event variable that allows us to get the property bound to the field that triggered the value change event.

This application has a fundamental problem. We are asking the user to select two options, but the OptionGroup component allows only one option to be selected at a time.

Time for action – fixing the OptionGroup example

It's time for our good deed of the day. OptionGroup has a very simple method to turn on a multiple selection mode: setMultiSelect.

  1. Open or import the optiongroup example in your IDE.
  2. Add og.setMultiSelect(true) after instantiating og.
  3. Deploy and run the example.

What just happened?

Take a look at the new interface:

As you can see, now the component is displayed as an assortment of checkboxes and the getValue method (of both OptionGroup and Property) returns a Java Collection (actually a Set). This happens when we activate multiselect mode.

Have a go hero – improve the OptionGroup example

Try changing the OptionGroup example application to show a message informing whether the answer is correct or not. Here is a quick hint: cast the value to a Java Set instance.

Twin column selects

Instead of the OptionGroup component we can use TwinColSelect. We can change OptionGroup for TwinColSelect in the previous example:

TwinColSelect og = new TwinColSelect ("Two kinds of EJBs in Java EE are:",
answers);

With this, we get an interesting component for selection:

Date/time pickers

Vaadin includes a nice date/time picker with multiple configuration options. You can add a date picker using this:

DateField dateField = new DateField("Select a date");

This will display a field to directly type the date and a button to open a convenient calendar:

The getValue method of DateField returns a java.util.Date object. You can configure the resolution of DateField. For example, to allow users select only a year, we can do this:

dateField.setResolution (Resolution.YEAR);

This will show a more restrictive component:

A date format can be specified using the setDateFormat method:

dateField.setDateFormat ("yyyy-MM-dd");

Time for action – using an InlineDateField component

Let's change the DateField example a little bit:

  1. Open or import the datefield example in your IDE.
  2. Replace DateField with InlineDateField in DateFieldUI.java.
  3. Deploy and run the example.

What just happened?

This is the result you get:

You cannot type the year now, you have to select it from the component.

Uploading files

Study this simple example that displays (in the console) the content of a text file uploaded by the user:

public class UploadUI extends UI implements Receiver { @Override protected void init(VaadinRequest request) { Upload upload = new Upload( "Select a text file and look at the console", this); VerticalLayout layout = new VerticalLayout(); layout.addComponent(upload); setContent(layout); } @Override public OutputStream receiveUpload(String filename, String mimeType) { return new OutputStream() { @Override public void write(int b) throws IOException { System.out.print((char) b); } }; } }

The Upload class displays a native (browser-dependent) button to select a file and a Vaadin button to upload the file to the server:

Summary

We covered some really useful components in this article. This is what we have covered:

  • We learned how layout components are used to arrange other components, even layout themselves.
  • We learned how to use HorizontalLayout, AbsoluteLayout, GridLayout, and FormLayout.
  • We added listeners to handle click events on layouts.
  • We learned how HorizontalSplitPanel, VerticalSplitPanel, Panel, TabSheet, and Accordion, let us arrange components in very flexible ways.
  • We learned many features of Window, such as limiting resizing and dragging, setting the position programmatically, listening to close events, and using modal windows.

This article showed you many features of Vaadin layouts. Now you can arrange your components as you wish.

Resources for Article:


Further resources on this subject:


Vaadin 7 UI Design By Example: Beginner’s Guide Build exciting Vaadin applications in no time with this book and ebook
Published: July 2013
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

About the Author :


Alejandro Duarte

Alejandro Duarte learned how to program at age 13 using the Basic language on a black screen with a blinking cursor. He used to spend hours thinking of ideas for software that would be good to have and even more hours bringing these ideas to life. Alejandro graduated from National University of Colombia with a BS in Computer Science and has been involved in many Java-related software development projects. He first started working with Struts 2 and quickly switched to more RIA friendly frameworks such as Grails, jQuery, GWT, and Vaadin. Alejandro is the author of the Enterprise App for Vaadin add-on and InfoDoc Pro, both open source projects based on the Vaadin framework. He currently works as a developer for several companies and customers mainly in Colombia, Chile, India, Kenya, and the UK.

When not writing code, Alejandro splits his free time between his family, his beautiful girlfriend, and his passion for the electric guitar. You can contact him at alejandro.d.a@gmail.com or through his personal blog http://www.alejandrodu.com. If you are feeling social, you can follow him on Twitter at @alejandro_du.

Books From Packt


Learning Vaadin
Learning Vaadin

Learning Vaadin 7: Second Edition
Learning Vaadin 7: Second Edition

Vaadin 7 Cookbook
Vaadin 7 Cookbook

jQuery UI 1.8: The User Interface Library for jQuery
jQuery UI 1.8: The User Interface Library for jQuery

jQuery Tools UI Library
jQuery Tools UI Library

 jQuery UI Themes Beginner's Guide
jQuery UI Themes Beginner's Guide

Ext JS 4 Web Application Development Cookbook
Ext JS 4 Web Application Development Cookbook

Android User Interface Development: Beginner's Guide
Android User Interface Development: Beginner's Guide


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
F
g
Y
2
a
w
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software