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

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.

Tip

The RichTextArea component stores the value as a String containing HTML (or more precisely, XHTML). A user could try to attempt a cross-site scripting attack here. This kind of attack is about injecting malicious JavaScript code that could be executed later. If you think that a user can input HTML that another user could see, parse the HTML so you can be sure no offensive JavaScript could be executed. This process is also known as sanitizing.

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.