1. Overview
1.概述
Vaadin is a server-side Java framework for creating web user interfaces. Using it, we can create our front-end using Java features.
Vaadin是一个用于创建Web用户界面的服务器端Java框架。使用它,我们可以使用Java功能创建我们的前端。
2. Maven Dependencies and Setup
2.Maven的依赖性和设置
Let’s start by adding the following dependencies to our pom.xml:
让我们先把以下依赖项添加到我们的pom.xml。
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-server</artifactId>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-client-compiled</artifactId>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-themes</artifactId>
</dependency>
The latest versions of the dependencies can be found here: vaadin-server, vaadin-client-compiled, vaadin-themes.
最新版本的依赖项可以在这里找到。vaadin-server, vaadin-client-compiled, vaadin-themes。
- vaadin-server package – includes classes for handling all server details such as sessions, client communication, etc.
- vaadin-client-compiled – is based on GWT and includes necessary packages to compile the client
- vaadin-themes – includes some pre-made themes and all utilities for making our themes
To compile our Vaadin widgets, we need to configure the maven-war-plugin, vaadin-maven-plugin, and the maven-clean-plugin. For the full pom, make sure to check the pom file in the source code – at the end of the tutorial.
为了编译我们的Vaadin小工具,我们需要配置maven-war-plugin、vaadin-maven-plugin,以及maven-clean-plugin。关于完整的pom,请务必查看源代码中的pom文件–在教程的最后。
Also, we also need to add the Vaadin repository and the dependency management:
另外,我们还需要添加Vaadin资源库和依赖性管理。
<repositories>
<repository>
<id>vaadin-addons</id>
<url>http://maven.vaadin.com/vaadin-addons</url>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<version>13.0.9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
The DependencyManagement tag controls versions of all Vaadin dependencies.
DependencyManagement标签控制所有Vaadin依赖的版本。
To quickly run the application, we’ll use the Jetty plugin:
为了快速运行该应用程序,我们将使用Jetty插件。
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.3.9.v20160517</version>
<configuration>
<scanIntervalSeconds>2</scanIntervalSeconds>
<skipTests>true</skipTests>
</configuration>
</plugin>
The latest version of the plugin can be found here: jetty-maven-plugin.
该插件的最新版本可以在这里找到。jetty-maven-plugin。
With this plugin we can run our project using the command:
有了这个插件,我们可以用命令来运行我们的项目。
mvn jetty:run
3. What Is Vaadin?
3.什么是Vaadin?
Simply put, Vaadin is a Java framework for creating user interfaces, with themes and components, and a lot of extensibility options.
简单地说,Vaadin是一个用于创建用户界面的Java框架,具有主题和组件,以及大量的可扩展性选项。
The framework does cover the server side as well, which means that every change you make to the user interface is immediately sent to the server – so in every moment the backend application knows what is happening in the front-end.
该框架也涵盖了服务器端,这意味着你对用户界面所做的每一个改变都会立即发送到服务器上–因此在每一个时刻,后端应用程序都知道前端正在发生什么。
Vaadin consists of a Client and Server side – with the client side built on top of the well-known Google Widget Toolkit framework, and the server side handled by the VaadinServlet.
Vaadin由客户端和服务器端组成–客户端建立在著名的Google Widget Toolkit框架之上,而服务器端则由VaadinServlet处理。
4. The Servlet
4.Servlet
Usually, a Vaadin application doesn’t use a web.xml file; instead, it defines its servlet using annotations:
通常,一个Vaadin应用程序不使用web.xml文件;相反,它使用注释来定义其servlet。
@WebServlet(urlPatterns = "/VAADIN/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = VaadinUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {}
In this case, this servlet is serving content from the /VAADIN path.
在这种情况下,这个Servlet正在为来自/VAADIN路径的内容服务。
5. The Main Class
5.主体类
The VaadinUI class that is referenced in the servlet must extend the UI class from the framework and must override the init method to complete the bootstrapping of the application with Vaadin enabled.
在servlet中引用的VaadinUI类必须扩展框架中的UI类,并且必须覆盖init方法以完成启用Vaadin的应用程序的引导。
The next step is to create a layout and add it to a main layout of the application:
下一步是创建一个布局并将其添加到应用程序的主布局中。
public class VaadinUI extends UI {
@Override
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout verticalLayout = new VerticalLayout();
verticalLayout.setSpacing(true);
verticalLayout.setMargin(true);
setContent(verticalLayout);
}
6. Vaadin Layout Managers
6.Vaadin布局管理器
The framework comes with a number of predefined layout managers.
该框架配备了一些预定义的布局管理器。
6.1. VerticalLayout
6.1.VerticalLayout
Stack the components on a column where the first added is on the top and the latest is on the bottom:
将组件堆放在一列,第一次添加的组件在顶部,最新的在底部。
VerticalLayout verticalLayout = new VerticalLayout();
verticalLayout.setSpacing(true);
verticalLayout.setMargin(true);
setContent(verticalLayout);
Note how the properties here are loosely borrowed from typical CSS terminology.
注意这里的属性是如何松散地借用典型的CSS术语的。
6.2. HorizontalLayout
6.2.HorizontalLayout
This layout places each component side by side from left to right is similar to the vertical layout:
这种布局将每个组件从左到右并排放置,类似于垂直布局。
HorizontalLayout horizontalLayout = new HorizontalLayout();
6.3. GridLayout
6.3.GridLayout
This layout places each widget in a grid, you need to pass as a parameter the columns and the rows of the grid:
这个布局将每个部件放在一个网格中,你需要将网格的列和行作为一个参数传给它。
GridLayout gridLayout = new GridLayout(3, 2);
6.4. FormLayout
6.4. FormLayout
The form layout puts the caption and the component in two different columns and can have optional indicators for required fields:
表单布局将标题和组件放在两个不同的列中,并且可以为必填字段设置可选的指标。
FormLayout formLayout = new FormLayout();
7. Vaadin Components
7.Vaadin组件
Now that the layout is handled, let’s have a look at some of the more common components for constructing our user interface.
现在布局已经处理好了,让我们来看看一些更常见的构建用户界面的组件。
7.1. Label
7.1.标签
The label is, of course, well known as well – and simply used to display text:
当然,标签也是众所周知的–只是用来显示文本。
Label label = new Label();
label.setId("LabelID");
label.setValue("Label Value");
label.setCaption("Label");
gridLayout.addComponent(label);
After we create the component, notice the critical step of adding it to the layout.
在我们创建了这个组件后,请注意将其添加到布局中这一关键步骤。
7.2. Link
7.2.链接
The link widget is essentially a basic hyperlink:
link小组件本质上是一个基本的超链接。
Link link = new Link("Baeldung",
new ExternalResource("http://www.baeldung.com/"));
link.setTargetName("_blank");
Notice how the typical HTML values of an <a> element are all here.
请注意,<a>元素的典型HTML值都在这里。
7.3. TextField
7.3.TextField
This widget is used to input text:
这个小组件用于输入文本。
TextField textField = new TextField();
textField.setIcon(VaadinIcons.USER);
We can further customize the elements; for example, we can quickly add images to the widgets via the setIcon() API.
我们可以进一步定制这些元素;例如,我们可以通过setIcon() API快速将图片添加到小工具中。
Also, note that Font Awesome is shipped out of the box with the framework; it’s defined as an Enum, and we can easily make use of it.
另外,请注意Font Awesome是随框架一起出厂的;它被定义为一个枚举,我们可以轻松地利用它。
7.4. TextArea
7.4.TextArea
As you’d expect, TextArea is available next to the rest of the traditional HTML elements:
正如你所期望的,TextArea在其他传统HTML元素旁边可用。
TextArea textArea = new TextArea();
7.5. DateField and InlineDateField
7.5.DateField和InlineDateField
This powerful component is used to pick dates; the date parameter is the current date to be selected in the widget:
这个强大的组件用于挑选日期;日期参数是要在小组件中选择的当前日期。
DateField dateField = new DateField("DateField", LocalDate.ofEpochDay(0));
We can go further and nest it inside a combo box control to save space:
我们可以进一步把它嵌套在一个组合框控件内,以节省空间。
InlineDateField inlineDateField = new InlineDateField();
7.6. PasswordField
7.6.PasswordField
This is the standard masked password input:
这是标准的屏蔽式密码输入。
PasswordField passwordField = new PasswordField();
7.7. RichTextArea
7.7.RichTextArea
With this component, we can show formatted text, and it provides an interface to manipulate such text with buttons to control the fonts, size, alignment, etc.are:
有了这个组件,我们可以显示格式化的文本,它提供了一个界面来操作这些文本,用按钮来控制字体、大小、对齐等。
RichTextArea richTextArea = new RichTextArea();
richTextArea.setCaption("Rich Text Area");
richTextArea.setValue("<h1>RichTextArea</h1>");
richTextArea.setSizeFull();
Panel richTextPanel = new Panel();
richTextPanel.setContent(richTextArea);
7.8. Button
7.8.按钮
Buttons are used for capturing user input and come in a variety of sizes and colors.
按钮用于捕捉用户输入,有各种尺寸和颜色。
To create a button we instantiate the widget class as usual:
为了创建一个按钮,我们像往常一样实例化widget类。
Button normalButton = new Button("Normal Button");
Changing the style we can have some different buttons:
改变风格,我们可以有一些不同的按钮。
tinyButton.addStyleName("tiny");
smallButton.addStyleName("small");
largeButton.addStyleName("large");
hugeButton.addStyleName("huge");
dangerButton.addStyleName("danger");
friendlyButton.addStyleName("friendly");
primaryButton.addStyleName("primary");
borderlessButton.addStyleName("borderless");
linkButton.addStyleName("link");
quietButton.addStyleName("quiet");
We can create a disabled button:
我们可以创建一个禁用按钮。
Button disabledButton = new Button("Disabled Button");
disabledButton.setDescription("This button cannot be clicked");
disabledButton.setEnabled(false);
buttonLayout.addComponent(disabledButton);
A native button that uses the browser’s look:
一个使用浏览器外观的本地按钮。
NativeButton nativeButton = new NativeButton("Native Button");
buttonLayout.addComponent(nativeButton);
And a button with an icon:
还有一个带图标的按钮。
Button iconButton = new Button("Icon Button");
iconButton.setIcon(VaadinIcons.ALIGN_LEFT);
buttonLayout.addComponent(iconButton);
7.9. CheckBox
7.9.CheckBox
The check box is a change state element, is checked or is unchecked:
复选框是一个改变状态的元素,被选中或不被选中。
CheckBox checkbox = new CheckBox("CheckBox");
checkbox.setValue(true);
checkbox.addValueChangeListener(e ->
checkbox.setValue(!checkbox.getValue()));
formLayout.addComponent(checkbox);
7.10. Lists
7.10.清单
Vaadin has some useful widgets to handle lists.
Vaadin有一些有用的小工具来处理列表。
First, we create a list of our items to be placed in the widget:
首先,我们创建一个要放在小部件中的项目列表。
List<String> numbers = new ArrayList<>();
numbers.add("One");
numbers.add("Ten");
numbers.add("Eleven");
The ComboBox is a drop down list:
ComboBox是一个下拉列表。
ComboBox comboBox = new ComboBox("ComboBox");
comboBox.addItems(numbers);
formLayout.addComponent(comboBox);
The ListSelect vertically places items and uses a scroll bar in case of overflow:
ListSelect 垂直放置项目,并在溢出的情况下使用滚动条。
ListSelect listSelect = new ListSelect("ListSelect");
listSelect.addItems(numbers);
listSelect.setRows(2);
formLayout.addComponent(listSelect);
The NativeSelect is like the ComboBox but have the browser look and feel:
NativeSelect就像ComboBox,但有浏览器的外观和感觉。
NativeSelect nativeSelect = new NativeSelect("NativeSelect");
nativeSelect.addItems(numbers);
formLayout.addComponent(nativeSelect);
The TwinColSelect is a dual list where we can change the items between these two panes; each item can only live in one of the panes at a time:
TwinColSelect是一个双列表,我们可以在这两个窗格之间改变项目;每个项目一次只能住在一个窗格中。
TwinColSelect twinColSelect = new TwinColSelect("TwinColSelect");
twinColSelect.addItems(numbers);
7.11. Grid
7.11.网格
The grid is used to show data in a rectangular way; you have rows and columns, can define header and foot for the data:
网格是用来以矩形方式显示数据的;你有行和列,可以为数据定义页眉和页脚。
Grid<Row> grid = new Grid(Row.class);
grid.setColumns("column1", "column2", "column3");
Row row1 = new Row("Item1", "Item2", "Item3");
Row row2 = new Row("Item4", "Item5", "Item6");
List<Row> rows = new ArrayList();
rows.add(row1);
rows.add(row2);
grid.setItems(rows);
The Row class above is a simple POJO we’ve added to represent a row:
上面的Row类是我们添加的一个简单的POJO,用来表示一个行。
public class Row {
private String column1;
private String column2;
private String column3;
// constructors, getters, setters
}
8. Server Push
8.服务器推送
Another interesting feature is an ability to send messages from the server to the UI.
另一个有趣的功能是能够从服务器向用户界面发送消息。
To use server push, we need to add the following dependency to our pom.xml:
为了使用服务器推送,我们需要在我们的pom.xml中添加以下依赖关系:</em
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-push</artifactId>
<versionId>8.8.5</versionId>
</dependency>
The latest version of the dependency can be found here: vaadin-push.
最新版本的依赖性可以在这里找到。vaadin-push。
Also, we need to add the @Push annotation to our class representing UI:
另外,我们需要将@Push注解添加到我们代表UI的类中。
@Push
@Theme("mytheme")
public class VaadinUI extends UI {...}
We create a label to capture the server push message:
我们创建一个标签来捕捉服务器的推送信息。
private Label currentTime;
We then create a ScheduledExecutorService that sends the time from the server to the label:
然后我们创建一个ScheduledExecutorService,将时间从服务器发送至label。
ScheduledExecutorService scheduleExecutor = Executors.newScheduledThreadPool(1);
Runnable task = () -> {
currentTime.setValue("Current Time : " + Instant.now());
};
scheduleExecutor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS);
The ScheduledExecutorService is running on the server side of the application and every time it runs, the user interface gets updated.
ScheduledExecutorService在应用程序的服务器端运行,每次运行时,用户界面都会被更新。
9. Data Binding
9.数据绑定
We can bind our user interface to our business classes.
我们可以将我们的用户界面与我们的业务类绑定。
First, we create a Java class:
首先,我们创建一个Java类。
public class BindData {
private String bindName;
public BindData(String bindName){
this.bindName = bindName;
}
// getter & setter
}
Then we bind our class that has a single field to a TextField in our user interface:
然后我们把我们的有一个字段的类绑定到用户界面中的TextField。
Binder<BindData> binder = new Binder<>();
BindData bindData = new BindData("BindData");
binder.readBean(bindData);
TextField bindedTextField = new TextField();
binder.forField(bindedTextField).bind(BindData::getBindName, BindData::setBindName);
First, we create a BindData object using the class we created before, then the Binder binds the field to the TextField.
首先,我们使用之前创建的类创建一个BindData对象,然后Binder将该字段绑定到TextField。
10. Validators
10.验证器
We can create Validators to validate the data in our input fields. To do that, we attach the validator to the field we want to validate:
我们可以创建Validators来验证我们输入字段中的数据。要做到这一点,我们将验证器附加到我们要验证的字段。
BindData stringValidatorBindData = new BindData("");
TextField stringValidator = new TextField();
Binder<BindData> stringValidatorBinder = new Binder<>();
stringValidatorBinder.setBean(stringValidatorBindData);
stringValidatorBinder.forField(stringValidator)
.withValidator(new StringLengthValidator("String must have 2-5 characters lenght", 2, 5))
.bind(BindData::getBindName, BindData::setBindName);
Then we validate our data before we use it:
然后,我们在使用数据之前对其进行验证。
Button buttonStringValidator = new Button("Validate String");
buttonStringValidator.addClickListener(e -> stringValidatorBinder.validate());
In this case, we are using the StringLengthValidator that validates the length of a String but Vaadin provides other useful validators and also allows us to create our custom validators.
在本例中,我们使用的是StringLengthValidator,它可以验证String的长度,但Vaadin提供了其他有用的验证器,也允许我们创建自定义验证器。
11. Summary
11.总结
Of course, this quick writeup barely scratched the surface; the framework is much more than user interface widgets, Vaadin provides all you need for creating modern web applications using Java.
当然,这篇快速写的文章仅仅触及了表面;该框架远不止用户界面部件,Vaadin提供了你使用Java创建现代Web应用程序所需的一切。
And, as always, the code can be found over on Github.
而且,像往常一样,代码可以在Github上找到over。