aboutsummaryrefslogtreecommitdiffstats
path: root/documentation/tutorial.adoc
diff options
context:
space:
mode:
Diffstat (limited to 'documentation/tutorial.adoc')
-rw-r--r--documentation/tutorial.adoc955
1 files changed, 955 insertions, 0 deletions
diff --git a/documentation/tutorial.adoc b/documentation/tutorial.adoc
new file mode 100644
index 0000000000..fa8ceecfed
--- /dev/null
+++ b/documentation/tutorial.adoc
@@ -0,0 +1,955 @@
+---
+title: Vaadin Tutorial
+order: 1
+layout: page
+subnav_auto_list_numbers: true
+subnav:
+ - title: Overview
+ href: '#framework.tutorial.overview'
+ subnav:
+ - title: Installing the Development Tools
+ href: '#framework.tutorial.overview.tools'
+ - title: Creating a project using an archetype
+ href: '#framework.tutorial.archetype'
+ - title: Adding a demo "backend"
+ href: '#framework.tutorial.backend'
+ - title: Listing entities in a Grid
+ href: '#framework.tutorial.grid'
+ - title: Creating live filtering for entities
+ href: '#framework.tutorial.filtering'
+ - title: Creating a form to edit Customer objects
+ href: '#framework.tutorial.form'
+ subnav:
+ - title: Creating a form using Vaadin Designer
+ href: '#framework.tutorial.form.designer'
+ subnav:
+ - title: Installing Vaadin Designer
+ href: '#framework.tutorial.form.designer.install'
+ - title: Creating the form design
+ href: '#framework.tutorial.form.designer.create'
+ - title: Creating a form using plain Java
+ href: '#framework.tutorial.form.java'
+ - title: Connecting the form to the application
+ href: '#framework.tutorial.form-connection'
+ - title: It works! What next?
+ href: '#framework.tutorial.next'
+---
+:sectnums:
+
+[[framework.tutorial]]
+= Vaadin Tutorial
+
+This tutorial gives you an overview of how you can use https://vaadin.com/framework[Vaadin Framework] to build single-page web UIs for your Java application.
+All you need to start with it is JDK 8 and an https://en.wikipedia.org/wiki/Integrated_development_environment[IDE], such as Eclipse.
+While this tutorial is written for Eclipse users, you can use your IDE of choice.
+No extensive knowledge of Java is needed, only basic programming skills are required.
+
+[[framework.tutorial.overview]]
+== Overview
+
+In this tutorial, we build a simple customer management system.
+It is not a real application; we use an in-memory "back-end", so that you can understand how to hook it to an existing Java based back-end.
+We cover the basic Vaadin development and you can use the result as a basis for more experiments with Vaadin, such as using add-ons, your own custom look-and- feel (aka. theme), adding new views, or optimizing the result for mobile support.
+
+[[figure.framework.tutorial.final-ui]]
+.UI to be built in the tutorial
+image::img/finalUI.jpg[]
+
+You need about 20 to 60 minutes to complete the tutorial, depending on your existing experience.
+Naturally, you can just do the beginning of the exercise or pick any of the steps you want.
+To start from a specific step, we have prepared the example code after each step to be downloaded as a zip file.
+If do not want to do the exercise at all, you can also just https://github.com/vaadin/tutorial/[download the final application] and play around with it.
+
+[[framework.tutorial.overview.tools]]
+=== Installing the Development Tools
+
+The tutorial uses Java 8, so please ensure that you have an up-to-date JDK 8 installed.
+Most Linux distributions can use package managers to install JDK8.
+Windows and Mac users should download it from http://www.oracle.com/technetwork/java/javase/downloads/index.html[Oracle's Java
+SE site].
+
+Also make sure you have the latest version of your IDE.
+Eclipse is available in various packages; be sure to download the *Eclipse IDE for Java EE Developers* from http://www.eclipse.org/downloads/[eclipse.org].
+
+Please refer to <<getting-started/getting-started-environment#getting-started.environment, "Setting up the Development Environment">> for information regarding installing the tools.
+
+[[framework.tutorial.archetype]]
+== Creating a Project from an Archetype
+
+As the starting point for the application, we use a Maven archetype called `vaadin-archetype-application`.
+Archetypes are project stubs that have some example code and a basic Maven build script.
+
+. Start by choosing "File > New > Maven Project" from the menu.
++
+[[figure.framework.tutorial.create-maven-project]]
+.Create a new Maven project
+image::img/createMavenProject.jpg[width=70%]
++
+TIP: If the [guilabel]#Maven Project# is not visible in the menu, you should switch to the _Java EE_ perspective.
+You can use the shortcut button in the tool bar or "Window > Perspective" to switch to the perspective.
+
+. The first step in the wizard is good as is for our purpose.
+Just click [guibutton]#Next#.
+
+. In the second step, you need to choose the `vaadin-archetype-application` archetype.
++
+.Selecting the archetype
+image::img/projectWizard2-top.jpg[width=70%]
++
+You can first try to find it using the filtering function.
++
+If Eclipse has not yet indexed the archetype catalog, you need to manually add the archetype details.
+// +
+// .Adding a new archetype
+// image::img/projectWizard2-add.jpg[width=70%]
++
+Click the [guibutton]#Add Archetype# button.
++
+.Settings for a new archetype
+image::img/projectWizardAddArchetype-crop.jpg[width=70%]
++
+Enter the following values:
++
+[guilabel]#Group ID#::
+ Give `com.vaadin`
+[guilabel]#Artifact ID#::
+ Give `vaadin-archetype-application`
+[guilabel]#Version#::
+ You can find the latest Vaadin version number from http://vaadin.com/download/[vaadin.com/download].
+[guilabel]#Repository URL#::
+ This can be left blank.
+
++
+And click [guibutton]#OK#.
+Now you can select the new archetype from the list.
+
++
+WARNING: Eclipse has a bug in its project wizard.
+The `vaadin-archetype-application` may not appear in the listing, even though you added it using the [guibutton]#Add Archetype# button.
+If this occurs, close the whole new project wizard and re-open it by selecting "File > New > Maven Project" again.
+The archetype then typically appears in the listing and can be found by the filtering functionality.
+
+. In the next wizard step, type in the following fields:
+[guilabel]#Group Id#:: `my.vaadin`
+[guilabel]#Artifact Id#:: `app`
+
++
+and click [guibutton]#Finish#.
+
+If this is your first Vaadin app, creating a project might take a while, depending on the speed of your network, as Vaadin libraries and other dependencies are being downloaded.
+Maven caches them on your local file system.
+Creating your next Maven-based Vaadin project will be much faster.
+
+Right click on the newly created project and choose "Run as > Maven Install".
+This initiates a full build of your application and finally creates a https://en.wikipedia.org/wiki/WAR_(file_format)[WAR] file into the [filename]#target# directory.
+You can deploy the WAR file to your application server.
+The first build will take a while, as Maven might again need to download some new modules.
+Also, the project uses add-ons and contains a project specific theme.
+Compiling them takes a while.
+
+TIP: For the Maven compilation to work you need a JDK to be configured in your
+Eclipse in "Window > Preferences > Java > Installed JREs > Add...".
+This step is necessary at least on Windows, if you are using a fresh installation of Eclipse or for some other reason haven't configured a JDK to your Eclipse.
+The JDK by default installs to [filename]#\Program Files\Java# on Windows.
+You can make JDK the default JRE for your Eclipse.
+
+While the build is running, let us have a look at what the archetype created for
+you.
+You can browse your project resources from the tree structure in the [guilabel]#Project Explorer#.
+Maven's [filename]#pom.xml# on top level contains settings for building your project and declares the used dependencies.
+Open [guilabel]#Java Resources# and below it [filename]#src/main/java#, the main source directory, and [packagename]#my.vaadin.app#, the main Java package that will contain your Vaadin UI code.
+
+TIP: Eclipse shows all project files in the Project Explorer.
+In this case, you can also find your [filename]#.java# files from under the top-level [filename]#src# node.
+However, the suggested method is to access them from under the [guilabel]#Java Resources# node, which is optimized for editing Java source code.
+
+The UI code (and the Servlet declaration) used by the application stub can be
+found in the [filename]#MyUI.java# file.
+Let us read it through to see how it works.
+The [methodname]#init()# method of a UI class is triggered when a user enters your web application.
+The [classname]#VerticalLayout# is one of the most used layout components, which
+are used to position and display other Vaadin components in your UI classes.
+The example code creates one [classname]#TextField# to allow the user to input her name and a [classname]#Button# whose click listener dynamically adds a new [classname]#Label# component to the main layout.
+In the end of the [methodname]#init()# method, we just configure the main layout and place components into it and set it to be the content of [classname]#MyUI#.
+
+To test your first Vaadin application, right-click on the project and choose "Debug as > Maven build...".
+The debug mode is slightly slower than the basic run mode, but it often helps you to figure out what is happening in your application.
+
+[[figure.framework.tutorial.debug-as-maven-build]]
+.Starting the server using a Maven target
+image::img/debugAsMavenBuild.jpg[]
+
+In the dialog, type `Run in jetty` to the [guilabel]#Name# input and `jetty:run` to the [guilabel]#Goals# input.
+
+[[figure.framework.tutorial.jetty-run]]
+.Generating a Maven launch for `jetty:run` target
+image::img/debugAsMavenBuild2.jpg[]
+
+Before clicking debug, to make sure debugging works properly, add your Java
+project to the source lookup path from the [guilabel]#Source# tab, as it is being done in <<figure.tutorial.creating.add-sources>>.
+
+[[figure.tutorial.creating.add-sources]]
+.Adding sources for debugging
+image::img/debugAsMavenBuildAddSources.jpg[]
+
+Now click [guibutton]#Debug# to continue.
+This will download a small Java web server (if not cached to your local Maven repository), and use it to host your application.
+Once the server has started, point your browser to the URL http://localhost:8080/[http://localhost:8080/] to see the running application.
+
+If you make changes to the code, the Jetty server will notice the changes and in
+a couple of seconds most changes are automatically deployed.
+Reloading the page in your browser will show the changes.
+
+TIP: In some cases your JVM might not allow injecting changes on the fly.
+In these cases, Eclipse will complain about "Hot code replacement error".
+Just choose to restart the server to get the latest changes.
+Many Java developers use a commercial tool called http://zeroturnaround.com/software/jrebel/[JRebel] to make code replacement work better.
+
+Mastering the usage of the Java debugger is also handy to better understand how your application actually works and fixing bugs that all developers write at some point.
+As Vaadin is "only" Java code, you can use all of Java's debugging tools, which cannot be done with other UI frameworks where the UI is written (partly) in HTML and/or JavaScript.
+Double-click on the line number in the Java editor, for example of the following line in the click listener:
+
+[source,java]
+----
+layout.addComponent(new Label("Thanks " + name.getValue()));
+----
+
+Doing so adds a breakpoint to the selected line.
+If you then click the button in your browser, the execution of the application will stop on that line.
+Eclipse will ask you to enter to _Debugging perspective_.
+That way you can step through the execution and inspect the variables.
+Clicking on the _play_ icon in the toolbar will continue the execution.
+Double-click the same line again to remove the breakpoint.
+
+[[figure.framework.tutorial.breakpoint]]
+.Execution in a break point in the button click listener
+image::img/debugInBreakPointVariable.jpg[]
+
+Clicking the red square in the [guilabel]#Console# view will terminate the server process.
+You can restart it easily form the run/debug history.
+You can find that from the small down arrow next to the green play button or bug button (for the debug mode) in the tool bar.
+Alternatively, you can use the main menu "Run > Run
+history/Debug history > Run in Jetty".
+
+To get back to the _Java EE Perspective_, an Eclipse mode designed for editing Java web app code, click the [guibutton]#Java EE# button in the toolbar.
+
+[[framework.tutorial.backend]]
+== Adding a demo "backend"
+
+Before getting more into real Vaadin development, let us introduce some domain objects and a "fake backend".
+In a real-world application, you will most likely have something similar, implemented with, for example, JPA and EJB or a Spring-based service.
+
+Copy the following three classes from github to your project.
+Class names point to the classes hosted in Github.
+Copying classes can be done in many ways.
+
+TIP: The fastest way to copy classes using Eclipse is to use your good old
+clipboard. Select the text content of the whole class from your browser, choose
+"Edit > Copy", focus the node representing the [packagename]#my.vaadin.app# Java package in Eclipse's Java Resources view and choose "Edit > Paste".
+Eclipse is smart enough to automatically create a properly named Java file for the class.
+
+ * https://raw.githubusercontent.com/vaadin/tutorial/master/src/main/java/my/vaadin/app/CustomerStatus.java[CustomerStatus] - this is a simple enum class
+ * https://raw.githubusercontent.com/vaadin/tutorial/master/src/main/java/my/vaadin/app/Customer.java[Customer] - this is the main domain object, a basic Java bean that we will be using in our example
+ * https://raw.githubusercontent.com/vaadin/tutorial/master/src/main/java/my/vaadin/app/CustomerService.java[CustomerService] - this is a simple facade via which you can request and modify [classname]#Customer# instances.
+ You can think of this as your entry point to your fake database.
+
+In the next steps, we will be using these classes and build a UI around them.
+The actual implementation of these classes is not relevant for this tutorial, but feel free to have a look around.
+
+[[framework.tutorial.grid]]
+== Listing entities in a Grid
+
+TIP: Starting from this step directly? https://github.com/vaadin/tutorial/archive/step2.zip[Download the project] for this step, extract the zip file and choose "Import... > Maven > Existing Maven project".
+
+Often when you start building a UI for a data-centric application, the first
+thing you want to do is to list your data from your back-end.
+There are several components and ways in Vaadin to do this.
+In this example, we will use the Grid component for tabular presentation of our customers.
+
+We start by introducing a [classname]#Grid# to the [classname]#MyUI# class.
+We could of course just introduce the Grid as a variable in the [methodname]#init()# method, but we most likely want to refer to it later.
+Also, let us get a reference to the [classname]#CustomerService#.
+
+[source,java]
+----
+public class MyUI extends UI {
+ // Add the next two lines:
+ private CustomerService service = CustomerService.getInstance();
+ private Grid grid = new Grid();
+
+ // The rest is already there...
+ @Override
+ protected void init(VaadinRequest vaadinRequest) {
+ ...
+----
+
+TIP: If you are new to Java development, you probably do not feel comfortable
+with the red compilation error for the line where the [classname]#Grid# got introduced, because of a missing import.
+This is easily fixed in Eclipse by using the
+menu:Source[Organize Imports] command. Learn its shortcut (kbd:[Ctrl-Shift-O] or
+kbd:[CMD-Shift-O] on Macs), you'll be using it a lot in Java development. In
+possible class name collisions, always choose the appropriate class from the
+_com.vaadin.ui_ package if you want to import core Vaadin UI classes like the
+Grid.
+
+To simply list all properties of all Customer objects from the backend service,
+replace the init method with the following snippet:
+
+[source,java]
+----
+@Override
+protected void init(VaadinRequest vaadinRequest) {
+ final VerticalLayout layout = new VerticalLayout();
+
+ // add Grid to the layout
+ layout.addComponents(grid);
+
+ // fetch list of Customers from service and assign it to Grid
+ List<Customer> customers = service.findAll();
+ grid.setContainerDataSource(new BeanItemContainer<>(Customer.class, customers));
+
+ layout.setMargin(true);
+ setContent(layout);
+}
+----
+
+TIP: Again, use the organize imports feature. The List object we use here is
+_java.util.List_.
+
+As we'll want to refresh the listing from various places in our application,
+extract the customer listing part into its own "updateList" method with the
+*public* modifier. The public modifier is handy later when we want to update the
+listing from other classes. You can let Eclipse help here by selecting the
+relevant lines and using the "quick fix" feature (kbd:[Ctrl+1] or kbd:[Cmd+1] on
+Macs). The extracted method call looks like this:
+
+[source,java]
+----
+ public void updateList() {
+ List<Customer> customers = service.findAll();
+ grid.setContainerDataSource(new BeanItemContainer<>(Customer.class, customers));
+ }
+----
+
+If you try the application now, you'll see that quite many properties of the
+customers are shown in the grid. To limit the visible properties, configure
+the Grid using the _setColumns_ method to only show "firstName", "lastName" and
+"email" properties.
+
+[source,java]
+----
+ grid.setColumns("firstName", "lastName", "email");
+----
+
+At this point the body of the MyUI class should look like this (servlet declaration
+omitted):
+
+[source,java]
+----
+private CustomerService service = CustomerService.getInstance();
+private Grid grid = new Grid();
+
+@Override
+protected void init(VaadinRequest vaadinRequest) {
+ final VerticalLayout layout = new VerticalLayout();
+
+ grid.setColumns("firstName", "lastName", "email");
+ // add Grid to the layout
+ layout.addComponent(grid);
+
+ updateList();
+
+ layout.setMargin(true);
+ setContent(layout);
+}
+
+public void updateList() {
+ // fetch list of Customers from service and assign it to Grid
+ List<Customer> customers = service.findAll();
+ grid.setContainerDataSource(new BeanItemContainer<>(Customer.class, customers));
+}
+----
+
+You can now save your changes to the file and verify the changes from your browser.
+You can do this at any point during the rest of the tutorial as well.
+
+[[framework.tutorial.filtering]]
+== Creating live filtering for entities
+
+TIP: Starting from this step directly? https://github.com/vaadin/tutorial/archive/step3.zip[Download the project] for this step, extract the zip file and choose menu:Import...[Maven>Existing Maven project].
+
+A search functionality is expected in every modern application and it is
+also a nice Vaadin development exercise. Let's add a filtering functionality to
+the Customer listing we created in the previous step.
+
+We'll start by introducing a TextField component as a field to our UI class:
+
+[source,java]
+----
+ private TextField filterText = new TextField();
+----
+
+In the _init_ method, configure the text field to contain a helpful input prompt
+and add a text change listener to the field. The exact place of these lines is
+not important, but add them, for example, after you have introduced the _layout_
+object.
+
+[source,java]
+----
+filterText.setInputPrompt("filter by name...");
+filterText.addTextChangeListener(e -> {
+ grid.setContainerDataSource(new BeanItemContainer<>(Customer.class,
+ service.findAll(e.getText())));
+});
+----
+
+TIP: To keep your code more readable, you can use autoformat after you write or
+copy paste code snippets. The default keyboard shortcut in Eclipse is
+kbd:[Ctrl+Shift+F] or kbd:[Cmd+Shift+F]
+
+The text change listener is another listener (in addition to the more commonly
+used ValueChangeListener) you can use with text fields in Vaadin. It is fired
+lazily while the user is typing, but only when there is a small pause in the
+typing. This makes it perfect for this kind of automatic filtering. When the
+user has changed the text, we'll just update the listing like in the updateList
+method, but use the current text as a filter for entries.
+
+To keep the _updateList_ method functional, it should also take into
+consideration the possible value in the filterText field. Change the line for
+fetching the customers into this:
+
+[source,java]
+----
+ List<Customer> customers = service.findAll(filterText.getValue());
+----
+
+Before adding the text field to the UI, let's improve the usability a bit
+and make a short exercise to compose better components from lower level UI
+components. The search field can naturally be cleared with the keyboard, but let's
+add a clear button next to the text field. Start by adding the following lines
+to the init method, for example right after your filterText configuration:
+
+[source,java]
+----
+Button clearFilterTextBtn = new Button(FontAwesome.TIMES);
+clearFilterTextBtn.setDescription("Clear the current filter");
+clearFilterTextBtn.addClickListener(e -> {
+ filterText.clear();
+ updateList();
+});
+----
+
+Vaadin contains a set of built in icons, from which we use the "X" icon,
+_FontAwesome.TIMES_, here, which most users will recognise as a functionality to clear
+the value. If we set the description to a component, it will be shown as a
+tooltip for those users who hover the cursor over the button and wonder what to
+do with it. In the click listener, we simply clear the text from the field and
+refresh the content of the listing.
+
+Vaadin contains lots of different kinds of layouts. The simplest way to align
+the text field and the button next to each other would be to use a
+HorizontalLayout. An alternative way we use here is using a CssLayout, which is
+a lightweight layout that is easy to customize with css. Even if you wouldn't
+want to play with CSS yourself, you can often use one of the existing style
+rules in the default _Valo_ theme. The following snippet will create a nice
+compact "composition" of both the TextField and the clear button. Add these
+lines to the init method right after you configured the _clearFilterTextBtn_:
+
+[source,java]
+----
+CssLayout filtering = new CssLayout();
+filtering.addComponents(filterText, clearFilterTextBtn);
+filtering.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
+----
+
+Finally, *change* the row in the init method that currently adds only the grid,
+to add both _filtering_ composition and the _grid_ to the main _layout_ of the
+application.
+
+[source,java]
+----
+ layout.addComponents(filtering, grid);
+----
+
+Now it is a good place to save your changes and try them in your browser.
+
+[[framework.tutorial.form]]
+== Creating a form to edit Customer objects
+
+To edit and add Customer objects we need to create a form, that edits the
+values in our domain objects. This tutorial has two alternative methods to do
+that. Pick either of them.
+
+[[framework.tutorial.form.designer]]
+=== Creating a form using Vaadin Designer
+
+TIP: Starting from this step directly? https://github.com/vaadin/tutorial/archive/step4.zip[Download the project] for this step, extract the zip file and choose menu:Import...[Maven>Existing Maven project].
+
+The form to edit Customer objects can be built using several methods of which
+the visual composition by drag 'n' drop is the most intuitive. Vaadin
+Designer is an Eclipse plugin that you can install and do WYSIWYG editing of
+your view code. We'll use it to create the form and then hook the editing logic
+to it with Java.
+
+TIP: If you are using another IDE or just prefer to compose your user interface
+with code, take the alternative step, <<Creating a form using plain Java>>,
+where the CustomerForm is composed using plain Java code.
+
+[[framework.tutorial.form.designer.install]]
+==== Installing Vaadin Designer
+
+Vaadin Designer comes as an integrated part of Vaadin Plugin for Eclipse. It can
+be installed easily via Eclipse Marketplace. Choose menu:Help[Eclipse Marketplace]
+
+In the dialog, just search for Vaadin and click _install_ to mark it for
+installation. Clicking _Install Now_ will take you to choose the modules you want
+and accept the license agreement.
+
+[[figure.framework.tutorial.plugin-install]]
+.Selecting Vaadin Plugin for Eclipse for installation in Eclipse Marketplace
+image::img/pluginEclipseMarketPlace2.jpg[]
+
+If you get a security warning about the software containing unsigned content,
+just accept the warning by clicking OK. After installation, Eclipse asks if you
+want to restart. Click Yes.
+
+TIP: When you use Vaadin Designer for the first time in the next
+step, it will ask for a license key. Get a key from
+https://vaadin.com/designer. If you are not willing to buy a license now, just
+acquire a trial license.
+
+[[framework.tutorial.form.designer.create]]
+==== Creating the form design
+
+The following screencast will show you how to produce the
+_CustomerFormDesign.html_, a design file we need in this tutorial. Use pause and
+slow motion to follow better what is being done in the video. Feel free to get creative!
+
+video::B5dN69NSS78[youtube, width="640", height="400"]
+
+TIP: At any point of the process, you can also switch to the markup mode where
+you can edit the raw content of the .html file. If you wish to take a shortcut
+or think you did something wrong when using the designer, you can just
+copy-paste the content of https://github.com/vaadin/tutorial/blob/master/src/main/resources/my/vaadin/app/CustomerFormDesign.html[the final state] to your own .html file.
+
+At this point we only have a static mockup of the actual UI. To implement a
+functional form component, we need some Java code as well. Vaadin Designer
+automatically creates a similarly named Java class, but a good habit is to never touch the auto-generated file, in this case the
+CustomerFormDesign.java file. If you'd introduce a new field to your form,
+your changes to CustomerFormDesign would be overridden by the tooling. Instead,
+we'll create a class called CustomerForm which inherits from the auto-generated
+CustomerFormDesign class.
+
+Start by creating a new Java class with the name CustomerForm. In Eclipse, right
+click on the "my.vaadin.app" package and choose menu:New[Class]. Type in the
+name _CustomerForm_, define the superclass as
+_my.vaadin.app.CustomerFormDesign_ and click _finish_.
+
+From the superclass, we inherit all the UI elements that we named when using
+the designer. E.g. by simply referencing to "save" field in the CustomerForm,
+we'll have access to the save button we previously created.
+
+We will later need a reference to the currently edited Customer object,
+CustomerService and the MyUI that uses this class. Add these fields and a
+basic constructor that accepts MyUI as a parameter to the CustomerForm class:
+
+[source,java]
+----
+CustomerService service = CustomerService.getInstance();
+private Customer customer;
+private MyUI myUI;
+
+public CustomerForm(MyUI myUI) {
+ this.myUI = myUI;
+}
+----
+
+Although the form is not yet fully functional, you might want to see what it
+looks like at this point. Add it as a field to the _MyUI_ class:
+
+[source,java]
+----
+ CustomerForm form = new CustomerForm(this);
+----
+
+Now let's modify the init method in MyUI to show the form. Let's wrap both the
+Grid and the CustomerForm in a horizontal layout and configure the Grid to use
+all of the available space more efficiently. Replace the line
+*layout.addComponents(filtering, grid);* with the following:
+
+[source,java]
+----
+HorizontalLayout main = new HorizontalLayout(grid, form);
+main.setSpacing(true);
+main.setSizeFull();
+grid.setSizeFull();
+main.setExpandRatio(grid, 1);
+
+layout.addComponents(filtering, main);
+----
+
+If you now save your changes and reload your application page in a browser,
+you should see your CustomerForm next to the grid that lists your
+existing entities.
+
+Let's get back to the CustomerForm. The first thing we'll need is to populate
+the options for the select. To add all enum values as valid selections, add the
+following line to the constructor:
+
+[source,java]
+----
+ status.addItems(CustomerStatus.values());
+----
+
+Let's also improve the UX a bit. When building the design, we already
+emphasized the save button with a ValoTheme.BUTTON_PRIMARY style name. Thus, it
+would be natural if the enter-key would do the same action as clicking the
+save button. Assign a keyboard shortcut to the save button with this line in the
+constructor:
+
+[source,java]
+----
+save.setClickShortcut(KeyCode.ENTER);
+----
+
+To finish our form, we need to create a public API that we will use in the next
+part from MyUI, to pass in a Customer object that the form should edit. We
+will also add some logic to actually save the changes. We'll start by creating a
+setter method to the Customer field. Just type _setCus_ in the body of the
+class and hit autocomplete (kbd:[Ctrl+Space]) and Eclipse will create a method
+stub for you. Complete it with the following implementation:
+
+[source,java]
+----
+public void setCustomer(Customer customer) {
+ this.customer = customer;
+ BeanFieldGroup.bindFieldsUnbuffered(customer, this);
+
+ // Show delete button for only customers already in the database
+ delete.setVisible(customer.isPersisted());
+ setVisible(true);
+ firstName.selectAll();
+}
+----
+
+In addition to saving the reference of the currently edited Customer object, we are
+calling the _BeanFieldGroup.bindFieldsUnbuffered_ method. It will initialize all
+similarly named editor fields in this form with the values from their
+counterpart in the given Customer object. Also, it will automatically update the
+values in the domain objects as the corresponding field value changes in the
+user interface.
+
+TIP: If the naming convention based databinding doesn't fit your needs, you
+can use
+https://www.vaadin.com/api/com/vaadin/data/fieldgroup/PropertyId.html[PropertyId]
+annotation on fields to explicitly declare the edited property.
+
+We'll also want to ensure the form is visible and that focus goes to the
+firstName field to improve user experience. As we will be using the form to
+edit both new non-persisted objects and existing customers, we will also show
+the delete button only for customers that are already persisted in the backend.
+
+The last thing we need to do is to handle save and delete button clicks. Add
+the following methods to the CustomerForm class:
+
+[source,java]
+----
+private void delete() {
+ service.delete(customer);
+ myUI.updateList();
+ setVisible(false);
+}
+
+private void save() {
+ service.save(customer);
+ myUI.updateList();
+ setVisible(false);
+}
+----
+
+Finally, we'll add listeners to the buttons to call these methods. Adding these
+simple lambda expressions to the constructor will take care of that:
+
+[source,java]
+----
+save.addClickListener(e->this.save());
+delete.addClickListener(e->this.delete());
+----
+
+TIP: For a truly re-usable form component in a real life project, you'd want to
+introduce an interface to replace the myUI field or, even better, use an event
+system like https://vaadin.com/wiki/-/wiki/main/Events+and+contexts[CDI events]
+to completely decouple the components. We'll leave that out of this tutorial for
+simplicity.
+
+[[framework.tutorial.form.java]]
+=== Creating a form using plain Java
+
+This is an alternative step to the <<Creating a form using Vaadin Designer>>,
+where you'll build the form UI programmatically in plain Java. If you already
+completed the step using Vaadin Designer, you can proceed to
+<<Connecting the form to the application>>.
+
+Start by creating a new Java class with the name CustomerForm. In Eclipse right
+click on the "my.vaadin.app" package and choose menu:New[Class]. Type in the
+name _CustomerForm_, define the superclass as _com.vaadin.ui.FormLayout_ and
+click _finish_.
+
+In the form, we'll need editor fields for each property in our Customer domain
+class. There are different kinds of fields in Vaadin for editing different kinds
+of properties. In this example, we'll use a TextField, a PopupDateField and a
+NativeSelect. Add the following field declarations and action buttons as Java
+fields to the CustomerForm:
+
+[source,java]
+----
+private TextField firstName = new TextField("First name");
+private TextField lastName = new TextField("Last name");
+private TextField email = new TextField("Email");
+private NativeSelect status = new NativeSelect("Status");
+private PopupDateField birthdate = new PopupDateField("Birthday");
+private Button save = new Button("Save");
+private Button delete = new Button("Delete");
+----
+
+Also, we will laterneed a reference to the currently edited Customer object,
+CustomerService and the MyUI that uses this class. Add these fields and a
+basic constructor that accepts MyUI as a parameter to the CustomerForm class:
+
+[source,java]
+----
+private CustomerService service = CustomerService.getInstance();
+private Customer customer;
+private MyUI myUI;
+
+public CustomerForm(MyUI myUI) {
+ this.myUI = myUI;
+
+ setSizeUndefined();
+ HorizontalLayout buttons = new HorizontalLayout(save, delete);
+ buttons.setSpacing(true);
+ addComponents(firstName, lastName, email, status, birthdate, buttons);
+}
+----
+
+In the constructor we make the form size undefined, which practically means it
+will consume the minimum space defined by its content. Then we'll just add all
+the fields to the CustomerForm and add action buttons to the bottom - side-by-side
+using a HorizontalLayout. Although the form is not yet fully functional, you
+might want to see what it looks like at this point. Add it as a field to the MyUI
+class:
+
+[source,java]
+----
+ CustomerForm form = new CustomerForm(this);
+----
+
+Now let's modify the init method in MyUI to show the form. Let's wrap both the
+Grid and the CustomerForm in a horizontal layout and configure the Grid to use
+all of the available space more efficiently. Replace the line
+*layout.addComponents(filtering, grid);* with the following:
+
+[source,java]
+----
+HorizontalLayout main = new HorizontalLayout(grid, form);
+main.setSpacing(true);
+main.setSizeFull();
+grid.setSizeFull();
+main.setExpandRatio(grid, 1);
+
+layout.addComponents(filtering, main);
+----
+
+When you now save your changes and reload your application page in your browser,
+you should see your CustomerForm next to the grid that lists your
+existing entities.
+
+Let's get back to the CustomerForm. The first thing we'll need is to populate
+the options for the select. To add all enum values as valid selections, add the
+following line to the constructor:
+
+[source,java]
+----
+ status.addItems(CustomerStatus.values());
+----
+
+Let's also improve the UX a bit. The most common thing your users will want to
+do with this kind of form is to save it. Let's decorate the button with a style
+name that makes it more prominent in the UI and give it a keyboard shortcut -
+simply an enter hit in this case:
+
+[source,java]
+----
+save.setStyleName(ValoTheme.BUTTON_PRIMARY);
+save.setClickShortcut(KeyCode.ENTER);
+----
+
+To finish our form, we need to create a public API that we will use in the next
+part from the MyUI, to pass in a Customer object that the form should edit. We
+will also add some logic to actually save the changes. We'll start by creating a
+setter method for the Customer field. Just type _setCus_ in the body of the
+class and hit autocomplete (kbd:[Ctrl+Space]) and Eclipse will create a method
+stub for you. Complete it with the following implementation:
+
+[source,java]
+----
+public void setCustomer(Customer customer) {
+ this.customer = customer;
+ BeanFieldGroup.bindFieldsUnbuffered(customer, this);
+
+ // Show delete button for only customers already in the database
+ delete.setVisible(customer.isPersisted());
+ setVisible(true);
+ firstName.selectAll();
+}
+----
+
+In addition to saving the reference of the currently edited Customer object, we are
+calling _BeanFieldGroup.bindFieldsUnbuffered_ method. It will initialise all
+similarly named editor fields in this form with the values from their
+counterpart in the given Customer object. Also, it will automatically update the
+values in the domain objects as the corresponding field value changes in the
+user interface.
+
+TIP: If the naming convention based databinding doesn't fit your needs, you
+can use
+https://www.vaadin.com/api/com/vaadin/data/fieldgroup/PropertyId.html[PropertyId]
+annotation on fields to explicitly declare the edited property.
+
+We'll also want to ensure the form is visible and that the focus goes to the
+firstName field to improve the user experience. As we will be using the form to
+edit both new non-persisted objects and existing customers, we will also show
+the delete button only for customers that are already persisted in the backend.
+
+The last thing we need to do is to handle save and delete button clicks. Add
+the following methods to the CustomerForm class:
+
+[source,java]
+----
+private void delete() {
+ service.delete(customer);
+ myUI.updateList();
+ setVisible(false);
+}
+
+private void save() {
+ service.save(customer);
+ myUI.updateList();
+ setVisible(false);
+}
+----
+
+Finally, we'll add listeners to the buttons to call these methods. Adding these
+simple lambda expressions to the constructor will take care of that:
+
+[source,java]
+----
+save.addClickListener(e->this.save());
+delete.addClickListener(e->this.delete());
+----
+
+TIP: For a truly re-usable form component in a real life project, you'd want to
+introduce an interface to replace the myUI field or, event better, use an event
+system like https://vaadin.com/wiki/-/wiki/main/Events+and+contexts[CDI events]
+to completely decouple the components. We'll leave that out of this tutorial for
+simplicity.
+
+[[framework.tutorial.form-connection]]
+== Connecting the form to the application
+
+TIP: Starting from this step directly? https://github.com/vaadin/tutorial/archive/step5.zip[Download the project] for this step, extract the zip file and choose menu:Import...[Maven>Existing Maven project].
+
+In this part, we'll use the CustomerForm class, which we created in the
+previous step, from the MyUI class. We will use it for both editing the existing
+customers and creating new ones.
+
+In the previous part, we already added the form to the _MyUI_ to see what it looks
+like. By default, we want it to be invisible, so let's first hide it
+by adding this line to the _init_ method of MyUI class:
+
+[source,java]
+----
+form.setVisible(false);
+----
+
+To edit the customer chosen from the Grid, add the following selection listener to
+the end of the _init_ method:
+
+[source,java]
+----
+grid.addSelectionListener(event -> {
+ if (event.getSelected().isEmpty()) {
+ form.setVisible(false);
+ } else {
+ Customer customer = (Customer) event.getSelected().iterator().next();
+ form.setCustomer(customer);
+ }
+});
+----
+
+In the listener, we simply take the Customer object of the selected row and pass it to
+the CustomerForm for editing. In the previous step, we added a side effect to the
+_setCustomer_ method that will bind the domain object to the corresponding fields
+and make it visible. If the selection is empty, we'll hide the form.
+
+To allow users to also create new customer records, we'll create a simple "Add
+customer button" to the top of the UI, right next to the _filtering_ composition
+we have already built from a CssLayout, a TextField and a Button. Introduce the new
+Button with a click listener, by adding the following lines to the _init_ method,
+right after where you introduced the _filtering_ composition:
+
+[source,java]
+----
+Button addCustomerBtn = new Button("Add new customer");
+addCustomerBtn.addClickListener(e -> {
+ grid.select(null);
+ form.setCustomer(new Customer());
+});
+----
+
+In the click listener, we first clear a possible selection from the grid and then
+instantiate a new Customer object and pass that to the form for editing.
+
+To add it beside our _filtering_ composition, we can use a HorizontalLayout to
+create a toolbar where we place both components. First, introduce a toolbar like
+this after the previously created _addCustomerBtn_:
+
+[source,java]
+----
+HorizontalLayout toolbar = new HorizontalLayout(filtering, addCustomerBtn);
+toolbar.setSpacing(true);
+----
+
+And, again, *replace* the line that populates your main layout to add the
+toolbar instead of just the filtering composition, which we just moved to the
+_toolbar_ layout.
+
+[source,java]
+----
+layout.addComponents(toolbar, main);
+----
+
+All planned features are now done. You can save the changes and play around with
+the application. If something went wrong, you can also download an example of
+https://github.com/vaadin/tutorial[the final application] and see what went wrong.
+
+[[framework.tutorial.next]]
+== It works! What next?
+
+Congratulations! Users can now create, read, update and delete customer records
+stored in the demo backend and you have completed creating your first CRUD UI
+with Vaadin.
+
+If you are an experienced Java developer, you are probably already full of ideas of
+how you can use your existing skills and create new shiny web UIs for your
+existing Java apps. If you want more ideas of how to create full stack
+applications, you might, for example, go through the
+http://spring.io/guides/gs/crud-with-vaadin/[Creating CRUD UI with Vaadin] guide
+and create a bit similar UI with a real database backend implemented with Spring
+Data JPA. We have also collected a couple of other resources for an easy
+start in your Vaadin developer career.
+
+ * https://vaadin.com/docs/-/part/framework/introduction/intro-overview.html[Vaadin online documentation]
+ * http://spring.io/guides/gs/crud-with-vaadin/[Creating CRUD UI with Vaadin] - the tutorial for your first Vaadin application using a Spring based backend.
+ * https://github.com/mstahv/jpa-invoicer[Jave EE example app] - a Vaadin app example for creating invoices that uses Java EE backend, Apache DeltaSpike Data for simple JPA layer, OAuth2 based login, PDF generation etc.
+ * http://vaadin.com/directory[Directory] - a vast source of awesome Vaadin add-ons