Introdução ao Vaadin
*1. Visão geral *
Vaadin é uma estrutura Java do lado do servidor para criar interfaces com o usuário da web. Utilizando-o, podemos criar nosso front-end usando os recursos Java.
===* 2. Dependências e configuração do Maven *
Vamos começar adicionando as seguintes dependências ao nosso 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>
As versões mais recentes das dependências podem ser encontradas aqui: https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22com.vaadin%22%20AND%20a%3A%22vaadin-server% 22 [vaadin-server], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22com.vaadin%22%20AND%20a%3A%22vaadin-client-compiled%22 [ vaadin-client-compiled], vaadin- temas.
-
vaadin-server package - inclui classes para lidar com todos os detalhes do servidor, como sessões, comunicação com o cliente etc.
-
vaadin-client-compiled - é baseado no GWT e inclui pacotes necessários para compilar o cliente *vaadin-themes - inclui alguns temas pré-criados e todos os utilitários para criar nossos temas
Para compilar nossos widgets Vaadin, precisamos configurar o https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.apache.maven.plugins%22%20AND%20a%3A% 22maven-war-plugin% 22 [maven-war-plugin], https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22com.vaadin%22%20AND%20a%3A% 22vaadin-maven-plugin% 22 [vaadin-maven-plugin] e o https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.apache.maven.plugins%22% 20AND% 20a% 3A% 22maven-clean-plugin% 22 [maven-clean-plugin]. Para o pom completo, verifique o arquivo pom no código-fonte - no final do tutorial.
Além disso, também precisamos adicionar o repositório Vaadin e o gerenciamento de dependências:
<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>
A tag DependencyManagement controla as versões de todas as dependências do Vaadin.
Para executar o aplicativo rapidamente, usaremos o 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>
A versão mais recente do plug-in pode ser encontrada aqui: https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.eclipse.jetty%22%20AND%20a%3A%22jetty- maven-plugin% 22 [jetty-maven-plugin].
Com este plugin, podemos executar nosso projeto usando o comando:
mvn jetty:run
===* 3. O que é o Vaadin? *
Simplificando, o Vaadin é uma estrutura Java para criar interfaces de usuário* , com temas e componentes, e muitas opções de extensibilidade.
*A estrutura também abrange o lado do servidor* , o que significa que todas as alterações feitas na interface do usuário são enviadas imediatamente para o servidor - assim, a todo momento, o aplicativo de back-end sabe o que está acontecendo no front-end.
*O Vaadin consiste no lado do cliente e do servidor* - com o lado do cliente construído sobre a estrutura bem conhecida do Google Widget Toolkit e o lado do servidor tratado pelo _VaadinServlet_.
*4. O servlet *
Geralmente, um aplicativo Vaadin não usa um arquivo web.xml; em vez disso, define seu servlet usando anotações:
@WebServlet(urlPatterns = "/VAADIN/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = VaadinUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {}
Nesse caso, este servlet está servindo conteúdo do caminho /VAADIN.
*5. A classe principal *
A classe VaadinUI mencionada no servlet deve estender a classe da UI da estrutura e deve substituir o método init para concluir a inicialização do aplicativo com o Vaadin ativado.
O próximo passo é criar um layout e adicioná-lo ao layout principal do aplicativo:
public class VaadinUI extends UI {
@Override
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout verticalLayout = new VerticalLayout();
verticalLayout.setSpacing(true);
verticalLayout.setMargin(true);
setContent(verticalLayout);
}
===* 6. Gerentes de layout Vaadin *
A estrutura vem com vários gerenciadores de layout predefinidos.
====* 6.1 VerticalLayout *
Empilhe os componentes em uma coluna onde a primeira adicionada está na parte superior e a mais recente na parte inferior:
VerticalLayout verticalLayout = new VerticalLayout();
verticalLayout.setSpacing(true);
verticalLayout.setMargin(true);
setContent(verticalLayout);
Observe como as propriedades aqui são emprestadas livremente da terminologia CSS típica.
====* 6.2 HorizontalLayout *
Esse layout coloca cada componente lado a lado da esquerda para a direita é semelhante ao layout vertical:
HorizontalLayout horizontalLayout = new HorizontalLayout();
====* 6.3. GridLayout *
Esse layout coloca cada widget em uma grade, você precisa passar como parâmetro as colunas e as linhas da grade:
GridLayout gridLayout = new GridLayout(3, 2);
====* 6.4. FormLayout *
O layout do formulário coloca a legenda e o componente em duas colunas diferentes e pode ter indicadores opcionais para os campos obrigatórios:
FormLayout formLayout = new FormLayout();
===* 7. Componentes Vaadin *
Agora que o layout foi tratado, vamos dar uma olhada em alguns dos componentes mais comuns para construir nossa interface com o usuário.
====* 7.1 Rótulo *
link:/wp-content/uploads/2017/07/label.png [imagem:/wp-content/uploads/2017/07/label.png [imagem]]
O rótulo é, é claro, bem conhecido também - e simplesmente usado para exibir texto:
Label label = new Label();
label.setId("LabelID");
label.setValue("Label Value");
label.setCaption("Label");
gridLayout.addComponent(label);
Depois de criar o componente, observe a etapa crítica de adicioná-lo ao layout.
====* 7.2 Ligação *
link:/wp-content/uploads/2017/07/link.png [imagem:/wp-content/uploads/2017/07/link.png [imagem]]
O widget link é essencialmente um hiperlink básico:
Link link = new Link("Baeldung",
new ExternalResource("http://www..com/"));
link.setTargetName("_blank");
Observe como os valores HTML típicos de um elemento _ <a> _ estão todos aqui.
====* 7.3. Campo de texto *
link:/wp-content/uploads/2017/07/textfield.png [imagem:/wp-content/uploads/2017/07/textfield.png [imagem]]
Este widget é usado para inserir texto:
TextField textField = new TextField();
textField.setIcon(VaadinIcons.USER);
Podemos personalizar ainda mais os elementos; por exemplo, podemos adicionar rapidamente imagens aos widgets por meio da API _setIcon () _.
Além disso, observe que o* Font Awesome é enviado imediatamente com a estrutura *; é definido como um Enum, e podemos usá-lo facilmente.
7.4. TextArea
link:/wp-content/uploads/2017/07/textarea.png [imagem:/wp-content/uploads/2017/07/textarea.png [imagem]]
Como seria de esperar, TextArea está disponível ao lado do restante dos elementos HTML tradicionais:
TextArea textArea = new TextArea();
7,5. DateField e InlineDateField
link:/wp-content/uploads/2017/07/datefield.png [imagem:/wp-content/uploads/2017/07/datefield.png [imagem]]
Este componente poderoso é usado para escolher datas; o parâmetro date é a data atual a ser selecionada no widget:
DateField dateField = new DateField("DateField", LocalDate.ofEpochDay(0));
link:/wp-content/uploads/2017/07/inlinedatefield.png [imagem:/wp-content/uploads/2017/07/inlinedatefield.png [imagem]]
Podemos ir além e aninhar dentro de um controle combo box para economizar espaço:
InlineDateField inlineDateField = new InlineDateField();
7.6. PasswordField
link:/wp-content/uploads/2017/07/passwordfield.png [imagem:/wp-content/uploads/2017/07/passwordfield.png [imagem]]
Esta é a entrada de senha mascarada padrão:
PasswordField passwordField = new PasswordField();
7.7 RichTextArea
link:/wp-content/uploads/2017/07/richtextarea.png [imagem:/wp-content/uploads/2017/07/richtextarea.png [imagem]]
Com esse componente, podemos mostrar texto formatado e fornece uma interface para manipular esse texto com botões para controlar as fontes, tamanho, alinhamento etc.
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. Botão *
link:/wp-content/uploads/2017/07/buttons.png [imagem:/wp-content/uploads/2017/07/buttons.png [imagem]]
Os botões são usados para capturar a entrada do usuário e vêm em vários tamanhos e cores.
Para criar um botão, instanciamos a classe do widget como de costume:
Button normalButton = new Button("Normal Button");
Mudando o estilo, podemos ter alguns botões diferentes:
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");
Podemos criar um botão desativado:
Button disabledButton = new Button("Disabled Button");
disabledButton.setDescription("This button cannot be clicked");
disabledButton.setEnabled(false);
buttonLayout.addComponent(disabledButton);
Um botão nativo que usa a aparência do navegador:
NativeButton nativeButton = new NativeButton("Native Button");
buttonLayout.addComponent(nativeButton);
E um botão com um ícone:
Button iconButton = new Button("Icon Button");
iconButton.setIcon(VaadinIcons.ALIGN_LEFT);
buttonLayout.addComponent(iconButton);
====* 7,9. CheckBox *
link:/wp-content/uploads/2017/07/checkbox.png [imagem:/wp-content/uploads/2017/07/checkbox.png [imagem]]
A caixa de seleção é um elemento de mudança de estado, está marcada ou desmarcada:
CheckBox checkbox = new CheckBox("CheckBox");
checkbox.setValue(true);
checkbox.addValueChangeListener(e ->
checkbox.setValue(!checkbox.getValue()));
formLayout.addComponent(checkbox);
====* 7.10 Listas *
Vaadin tem alguns widgets úteis para lidar com listas.
Primeiro, criamos uma lista de nossos itens para serem colocados no widget:
List<String> numbers = new ArrayList<>();
numbers.add("One");
numbers.add("Ten");
numbers.add("Eleven");
O ComboBox é uma lista suspensa:
link:/wp-content/uploads/2017/07/combobox.png [imagem:/wp-content/uploads/2017/07/combobox.png [imagem]]
ComboBox comboBox = new ComboBox("ComboBox");
comboBox.addItems(numbers);
formLayout.addComponent(comboBox);
O ListSelect coloca verticalmente itens e usa uma barra de rolagem em caso de estouro:
link:/wp-content/uploads/2017/07/listselect.png [imagem:/wp-content/uploads/2017/07/listselect.png [imagem]]
ListSelect listSelect = new ListSelect("ListSelect");
listSelect.addItems(numbers);
listSelect.setRows(2);
formLayout.addComponent(listSelect);
O NativeSelect é como o ComboBox, mas tem a aparência do navegador:
link:/wp-content/uploads/2017/07/nativeselect.png [imagem:/wp-content/uploads/2017/07/nativeselect.png [imagem]]
NativeSelect nativeSelect = new NativeSelect("NativeSelect");
nativeSelect.addItems(numbers);
formLayout.addComponent(nativeSelect);
O TwinColSelect é uma lista dupla na qual podemos alterar os itens entre esses dois painéis; cada item pode viver apenas em um dos painéis de cada vez:
link:/wp-content/uploads/2017/07/twincolselect.png [imagem:/wp-content/uploads/2017/07/twincolselect.png [imagem]]
TwinColSelect twinColSelect = new TwinColSelect("TwinColSelect");
twinColSelect.addItems(numbers);
====* 7.11. Rede *
A grade é usada para mostrar dados de maneira retangular; você tem linhas e colunas, pode definir cabeçalho e pé para os dados:
link:/wp-content/uploads/2017/07/grid.png [imagem:/wp-content/uploads/2017/07/grid.png [imagem]]
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);
A classe Row acima é um POJO simples que adicionamos para representar uma linha:
public class Row {
private String column1;
private String column2;
private String column3;
//constructors, getters, setters
}
===* 8. Envio do servidor *
Outro recurso interessante é a capacidade de enviar mensagens do servidor para a interface do usuário.
Para usar o envio por servidor, precisamos adicionar a seguinte dependência ao nosso _pom.xml: _
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-push</artifactId>
<versionId>8.8.5</versionId>
</dependency>
A versão mais recente da dependência pode ser encontrada aqui: https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22com.vaadin%22%20AND%20a%3A%22vaadin-push% 22 [vaadin-push].
Além disso, precisamos adicionar a anotação _ @ Push_ à nossa classe que representa a interface do usuário:
@Push
@Theme("mytheme")
public class VaadinUI extends UI {...}
Criamos um rótulo para capturar a mensagem de envio do servidor:
private Label currentTime;
Em seguida, criamos um ScheduledExecutorService que envia a hora do servidor para o label:
ScheduledExecutorService scheduleExecutor = Executors.newScheduledThreadPool(1);
Runnable task = () -> {
currentTime.setValue("Current Time : " + Instant.now());
};
scheduleExecutor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS);
O ScheduledExecutorService está sendo executado no lado do servidor do aplicativo e toda vez que é executado, a interface do usuário é atualizada.
===* 9. Ligação de dados *
Podemos vincular nossa interface de usuário a nossas classes de negócios.
Primeiro, criamos uma classe Java:
public class BindData {
private String bindName;
public BindData(String bindName){
this.bindName = bindName;
}
//getter & setter
}
Em seguida, vinculamos nossa classe que possui um único campo a um TextField em nossa interface do usuário:
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);
Primeiro, criamos um objeto BindData usando a classe que criamos anteriormente, depois o Binder vincula o campo ao TextField.
===* 10. Validadores *
Podemos criar Validators para validar os dados em nossos campos de entrada. Para fazer isso, anexamos o validador ao campo que queremos validar:
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);
Em seguida, validamos nossos dados antes de usá-los:
Button buttonStringValidator = new Button("Validate String");
buttonStringValidator.addClickListener(e -> stringValidatorBinder.validate());
Nesse caso, estamos usando o StringLengthValidator que valida o comprimento de um String, mas o Vaadin fornece outros validadores úteis e também nos permite criar nossos validadores personalizados.
===* 11. Resumo *
Obviamente, essa rápida redação mal arranhou a superfície; Como a estrutura é muito mais que os widgets da interface do usuário, o Vaadin fornece tudo o que você precisa para criar aplicativos da Web modernos usando Java.
E, como sempre, o código pode ser encontrado over no Github.