Vaadin – tworzenie frontendu w Spring Boot

Vaadin – tworzenie frontendu w Spring Boot

Vaadin to rozwiązanie/framework które pozwala na tworzenie interfejsu użytkownika w aplikacjach webowych bez konieczności znajomości technologii z rodziny JavaScript takich jak Angular czy React itp. Jeśli jednak jest potrzeba użycia stylów CSS, plików JS to nic nie stoi na przeszkodzie – Vaadin udostępnia programiście taką możliwość. Interfejs graficzny – GUI tworzony jest z użyciem gotowych komponentów dostarczonych przez Vaadina które z kolei za pomocą wybranego layoutu są odpowiednio w nim ustawiane/pozycjonowane. Projektowanie aplikacji przypomina programowanie w bibliotece Swing. Strona projektu Vaadina to http://vaadin.com/. Na stronie producenta Vaadin określany jest w jednym zdaniu jako:

Vaadin is an open source web framework that helps Java developers build great user experiences with minimal effort. Focus on creating apps that your users will

W tym artykule powstanie aplikacja z użyciem Spring Boota i frameworka Vaadin która realizowała będzie zapis na wydarzenie za pomocą przykładowego formularza rejestracyjnego. Ponadto zobaczysz w jaki sposób skonfigurować środowisko Inteliij IDEA, aby bez konieczności restartu całej aplikacji zobaczyć swoje zmiany. Wykorzystamy do tego celu plugin Intellij IDEAHotSwapAgent. Zaczynamy od nowego projektu Spring Boota – wersja 2.1.7.RELEASE i dodajemy zależności do pliku pom.xml.

dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>com.vaadin</groupId>
			<artifactId>vaadin-bom</artifactId>
			<version>14.0.13</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>
 
<dependencies>
	<dependency>
		<groupId>com.vaadin</groupId>
		<!-- Replace artifactId with vaadin-core to use only free components -->
		<artifactId>vaadin</artifactId>
		<exclusions>
			<!-- Webjars are only needed when running in Vaadin 13 compatibility mode -->
			<exclusion>
				<groupId>com.vaadin.webjar</groupId>
				<artifactId>*</artifactId>
			</exclusion>
			<exclusion>
				<groupId>org.webjars.bowergithub.insites</groupId>
				<artifactId>*</artifactId>
			</exclusion>
			<exclusion>
				<groupId>org.webjars.bowergithub.polymer</groupId>
				<artifactId>*</artifactId>
			</exclusion>
			<exclusion>
				<groupId>org.webjars.bowergithub.polymerelements</groupId>
				<artifactId>*</artifactId>
			</exclusion>
			<exclusion>
				<groupId>org.webjars.bowergithub.vaadin</groupId>
				<artifactId>*</artifactId>
			</exclusion>
			<exclusion>
				<groupId>org.webjars.bowergithub.webcomponents</groupId>
				<artifactId>*</artifactId>
			</exclusion>
		</exclusions>
	</dependency>
	<dependency>
		<groupId>com.vaadin</groupId>
		<artifactId>vaadin-spring-boot-starter</artifactId>
		<exclusions>
			<!-- Excluding so that webjars are not included. -->
			<exclusion><groupId>com.vaadin</groupId>
				<artifactId>vaadin-core</artifactId></exclusion>
		</exclusions>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-devtools</artifactId>
		<scope>runtime</scope>
	</dependency>
	<dependency>
		<groupId>com.vaadin</groupId>
		<artifactId>vaadin-testbench</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>
 
<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-compiler-plugin</artifactId>
			<configuration>
				<source>8</source>
				<target>8</target>
			</configuration>
		</plugin>
 
		<plugin>
			<groupId>com.vaadin</groupId>
			<artifactId>vaadin-maven-plugin</artifactId>
			<version>14.0.13</version>
			<executions>
				<execution>
					<goals>
						<goal>prepare-frontend</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
 
	</plugins>
</build>

Tworzymy przykładowy kontroler – należy pamiętać o prawidłowych importach!

import com.vaadin.flow.component.applayout.AppLayout;
import com.vaadin.flow.component.applayout.DrawerToggle;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.html.Image;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.tabs.Tab;
import com.vaadin.flow.component.tabs.Tabs;
import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.router.Route;
 
@Route("app")
public class Home extends AppLayout {
    public Home() {
        Image img = new Image("http://i.imgur.com/GPpnszs.png", "Vaadin Logo");
        img.setHeight("44px");
        addToNavbar(new DrawerToggle(), img);
        Tabs tabs = new Tabs(new Tab("Home"), new Tab("About"));
        tabs.setOrientation(Tabs.Orientation.VERTICAL);
        addToDrawer(tabs);
    }
}

po uruchomieniu aplikacji może zdarzyć się, że wystąpi następujący błąd:

java.lang.runtimeexception: unable to initialize vaadin devmodehandler

wtedy należy:

  • sprawdzić czy zmienna środowiskowa która wskazuje na lokalizację mavena jest prawidłowo ustawiona,
  • w katalogu projektu wykonać komendę która pozwoli na zainstalowanie menadżera pakietów npm.
mvn com.github.eirslett:frontend-maven-plugin:1.7.6:install-node-and-npm -DnodeVersion="v12.13.0

po prawidłowym uruchomieniu aplikacji i po wejściu na adres:

http://localhost:8080/

otrzymamy wynik:

Przechodzimy zatem na jedyny dostępny adres:

http://localhost:8080/app

w wyniku otrzymujemy:

Zanim zaczniemy projektować formularz rejestracyjny warto skonfigurować sobie środowisko Intellij IDEA w taki sposób, aby nie trzeba było za każdym razem po wprowadzeniu zmiany restartować Spring Boota. Znacznie przyspieszy to pracę nad aplikacją. Konfigurację przeprowadzimy w trzech prostych krokach:

krok 1

  • Instalacja pluginu HotSwapAgent:

Z poziomu Intellij IDEA należy zainstalować plugin HotSwapAgent:

krok 2

  • Konfiguracja pluginu HotSwapAgent:

pobranie pliku hotswap-agent-1.0.jar ze strony:

http://github.com/HotswapProjects/HotswapAgent/releases

wskazanie lokalizacji do pobranego pliku w konfiguracji pluginu:

pobranie pliku DCEVM-8u181-installer-build2.jar ze strony:

http://github.com/dcevm/dcevm/releases

należy wybrać katalog z JDK – wersja 8 i zainstalować narzędzie.

krok 3

  • Autoprzeładowanie klas po kompilacji:

Utwórzmy kontroler który wykorzystuje następujące kontrolki Vaadina:

  • TextField,
  • ComboBox,
  • Button,
  • Dialog.

więcej kontrolek znajdziesz na stronie: http://vaadin.com/components

import com.vaadin.flow.component.applayout.AppLayout;
import com.vaadin.flow.component.applayout.DrawerToggle;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.html.Image;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.tabs.Tab;
import com.vaadin.flow.component.tabs.Tabs;
import com.vaadin.flow.component.textfield.TextField;
 
import com.vaadin.flow.router.Route;
 
@Route("app")
public class Home extends AppLayout {
 
    TextField textArea        = new TextField("Rejestracja na wydarzenie");
    ComboBox<String> comboBox = new ComboBox<>("Wydarzenia");
 
    public Home() {
 
        Image img = new Image("http://i.imgur.com/GPpnszs.png", "Vaadin Logo");
        img.setHeight("44px");
        addToNavbar(new DrawerToggle(), img);
        Tabs tabs = new Tabs(new Tab("Home"), new Tab("About"));
        tabs.setOrientation(Tabs.Orientation.VERTICAL);
        addToDrawer(tabs);
 
        HorizontalLayout horizontalLayout = new HorizontalLayout();
        horizontalLayout.add(getLayoutTextBoxComboBox());
 
        setContent(horizontalLayout);
    }
 
    private HorizontalLayout getLayoutTextBoxComboBox() {
        HorizontalLayout horizontalLayout = new HorizontalLayout();
        horizontalLayout.add(getTextBoxLayout());
        horizontalLayout.add(getComboBoxLayout());
        return horizontalLayout;
    }
 
    private VerticalLayout getTextBoxLayout() {
        VerticalLayout vertical = new VerticalLayout();
        Label label = new Label();
 
        textArea.setPlaceholder("adres email");
 
        textArea.addValueChangeListener(event -> {
            if (event.getSource().isEmpty()) {
                label.setText(" nic nie wybrano");
            } else {
                label.setText("[wybrano] " + event.getValue());
            }
        });
 
        vertical.add(textArea);
        vertical.add(label);
        vertical.add(getSaveButton());
        return vertical;
    }
 
    private VerticalLayout getComboBoxLayout() {
        VerticalLayout vertical = new VerticalLayout();
        Label label = new Label();
 
        comboBox.setWidthFull();
        comboBox.setItems("Spring Boot", "konferencja GIT", "webinar Java 8");
 
        comboBox.addValueChangeListener(event -> {
            if (event.getSource().isEmpty()) {
                label.setText(" nic nie wybrano");
 
            } else {
                label.setText("[wybrano] " + event.getValue());
            }
        });
 
        vertical.add(comboBox);
        vertical.add(label);
 
        return vertical;
    }
 
    private Button getSaveButton() {
        final Button button = new Button("zapisz się!", event -> {
            Dialog dialog = new Dialog();
            dialog.add(new Label("podsumowanie zapisu na wydarzenie"));
 
            VerticalLayout verticalLayout = new VerticalLayout();
            verticalLayout.add(new Label("[email] " + textArea.getValue()));
            verticalLayout.add(new Label("[wydarzenie] " + comboBox.getValue()));
 
            dialog.add(verticalLayout);
 
            dialog.setWidth("400px");
            dialog.setHeight("150px");
            dialog.open();
        });
        return button;
    }
}

po wejściu na adres:

http://localhost:8088/app

otrzymamy wynikową aplikację!

Aby przetestować czy aktualizacja projektu bez konieczności restartu Spring Boota działa prawidłowo należy uruchomić aplikację w trybie Debuggera:

następnie wprowadzić zmiany do przykładowej klasy i przekompilować klasę:

aplikacja powinna się odświerzyć oraz powinien wyskoczyć komunikat, że klasa została przeładowana:

Zobacz kod na GitHubie i zapisz się na bezpłatny newsletter!

.

 

 

Leave a comment

Your email address will not be published.


*