Introdução ao Vaadin

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>
  • 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.

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.