diff --git a/vaadin/.gitignore b/vaadin/.gitignore new file mode 100644 index 0000000000..1ef3efefbd --- /dev/null +++ b/vaadin/.gitignore @@ -0,0 +1 @@ +frontend/generated \ No newline at end of file diff --git a/vaadin/frontend/index.html b/vaadin/frontend/index.html new file mode 100644 index 0000000000..d36e593475 --- /dev/null +++ b/vaadin/frontend/index.html @@ -0,0 +1,23 @@ + + + + + + + + + + + + +
+ + diff --git a/vaadin/pom.xml b/vaadin/pom.xml index aa37a2392a..ea9a3ed75a 100644 --- a/vaadin/pom.xml +++ b/vaadin/pom.xml @@ -1,21 +1,25 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.test vaadin 1.0-SNAPSHOT vaadin - war com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../parent-boot-2 + ../parent-boot-3 + + 17 + 24.3.3 + + @@ -30,38 +34,24 @@ - javax.servlet - javax.servlet-api - provided + com.vaadin + vaadin-core com.vaadin - vaadin-server - ${vaadin-server.version} - - - com.vaadin - vaadin-push - ${vaadin-push.version} - - - com.vaadin - vaadin-client-compiled - ${vaadin-client-compiled.version} - - - com.vaadin - vaadin-themes - ${vaadin-themes.version} + vaadin-spring-boot-starter org.springframework.boot spring-boot-starter-data-jpa - com.vaadin - vaadin-spring-boot-starter - ${vaadin-spring-boot-starter.version} + org.springframework.boot + spring-boot-starter-validation + + + io.projectreactor + reactor-core com.h2database @@ -76,47 +66,17 @@ - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - - false - - WEB-INF/classes/VAADIN/widgetsets/WEB-INF/** - - com.vaadin vaadin-maven-plugin - ${vaadin.plugin.version} - - - org.apache.maven.plugins - maven-clean-plugin - ${maven-clean-plugin.version} - - - - - src/main/webapp/VAADIN/themes - - **/styles.css - **/styles.scss.cache - - - - - - - - - org.eclipse.jetty - jetty-maven-plugin - ${jetty.plugin.version} - - 2 - + ${vaadin.version} + + + + prepare-frontend + + + org.springframework.boot @@ -125,68 +85,41 @@ - - - vaadin-addons - https://maven.vaadin.com/vaadin-addons - - - - vaadin-prerelease - - false - - - - - vaadin-prereleases - https://maven.vaadin.com/vaadin-prereleases - - - vaadin-snapshots - https://oss.sonatype.org/content/repositories/vaadin-snapshots/ - - false - - - true - - - - - - vaadin-prereleases - https://maven.vaadin.com/vaadin-prereleases - - - vaadin-snapshots - https://oss.sonatype.org/content/repositories/vaadin-snapshots/ - - false - - - true - - - + + production + + + + com.vaadin + vaadin-core + + + com.vaadin + vaadin-dev + + + + + + + + com.vaadin + vaadin-maven-plugin + ${vaadin.version} + + + + build-frontend + + compile + + + + + - - - 13.0.9 - 13.0.9 - 13.0.9 - 8.8.5 - 8.8.5 - 8.8.5 - 8.8.5 - 9.3.9.v20160517 - local - mytheme - 3.0.0 - - \ No newline at end of file diff --git a/vaadin/src/main/java/com/baeldung/Application.java b/vaadin/src/main/java/com/baeldung/Application.java index 1d3084723a..b62dd79158 100644 --- a/vaadin/src/main/java/com/baeldung/Application.java +++ b/vaadin/src/main/java/com/baeldung/Application.java @@ -1,15 +1,19 @@ package com.baeldung; +import com.baeldung.data.Employee; +import com.baeldung.data.EmployeeRepository; +import com.vaadin.flow.component.page.AppShellConfigurator; +import com.vaadin.flow.component.page.Push; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; +@Push @SpringBootApplication -public class Application { +public class Application implements AppShellConfigurator { private static final Logger log = LoggerFactory.getLogger(Application.class); diff --git a/vaadin/src/main/java/com/baeldung/IndexView.java b/vaadin/src/main/java/com/baeldung/IndexView.java new file mode 100644 index 0000000000..c69b160895 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/IndexView.java @@ -0,0 +1,25 @@ +package com.baeldung; + +import com.baeldung.introduction.PushView; +import com.baeldung.introduction.basics.VaadinFlowBasics; +import com.baeldung.introduction.FormView; +import com.baeldung.introduction.GridView; +import com.baeldung.spring.CrudView; +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.router.RouterLink; + +@Route("") +public class IndexView extends VerticalLayout { + + public IndexView() { + add(new H1("Vaadin Flow examples")); + + add(new RouterLink("Basics", VaadinFlowBasics.class)); + add(new RouterLink("Grid", GridView.class)); + add(new RouterLink("Form", FormView.class)); + add(new RouterLink("Push", PushView.class)); + add(new RouterLink("CRUD", CrudView.class)); + } +} diff --git a/vaadin/src/main/java/com/baeldung/data/Contact.java b/vaadin/src/main/java/com/baeldung/data/Contact.java new file mode 100644 index 0000000000..8e534d5bb0 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/data/Contact.java @@ -0,0 +1,73 @@ +package com.baeldung.data; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; + +@Entity +public class Contact { + + @Id + @GeneratedValue + private Long id; + @NotBlank + private String name; + @Email + private String email; + @Pattern(regexp = "\\d{3}-\\d{3}-\\d{4}") + private String phone; + + public Contact() { + } + + public Contact(String name, String email, String phone) { + this.name = name; + this.email = email; + this.phone = phone; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + @Override + public String toString() { + return "Contact {" + + "id=" + id + + ", name='" + name + "'" + + ", email='" + email + "'" + + ", phone='" + phone + "'" + + " }"; + } +} diff --git a/vaadin/src/main/java/com/baeldung/data/ContactRepository.java b/vaadin/src/main/java/com/baeldung/data/ContactRepository.java new file mode 100644 index 0000000000..15c4adaaa9 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/data/ContactRepository.java @@ -0,0 +1,6 @@ +package com.baeldung.data; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ContactRepository extends JpaRepository { +} diff --git a/vaadin/src/main/java/com/baeldung/data/DataInitializer.java b/vaadin/src/main/java/com/baeldung/data/DataInitializer.java new file mode 100644 index 0000000000..dba162d4e4 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/data/DataInitializer.java @@ -0,0 +1,46 @@ +package com.baeldung.data; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +@Component +public class DataInitializer implements CommandLineRunner { + + private final ContactRepository contactRepository; + + public DataInitializer(ContactRepository contactRepository) { + this.contactRepository = contactRepository; + } + + private final List firstNames = List.of( + "John", "Jane", "Emily", "Michael", "Sarah", "James", "Mary", "Robert", + "Patricia", "William", "Linda", "David", "Barbara", "Richard", "Susan", + "Joseph", "Jessica", "Thomas", "Karen", "Charles" + ); + private final List lastNames = List.of( + "Doe", "Smith", "Johnson", "Brown", "Davis", "Miller", "Wilson", "Moore", + "Taylor", "Anderson", "Thomas", "Jackson", "White", "Harris", "Martin", + "Thompson", "Garcia", "Martinez", "Robinson", "Clark" + ); + + @Override + public void run(String... args) throws Exception { + var contacts = new ArrayList(); + Random random = new Random(); + + for (int i = 0; i < 100; i++) { + String firstName = firstNames.get(random.nextInt(firstNames.size())); + String lastName = lastNames.get(random.nextInt(lastNames.size())); + String email = String.format("%s.%s@example.com", firstName.toLowerCase(), lastName.toLowerCase()); + String phone = String.format("555-%03d-%04d", random.nextInt(1000), random.nextInt(10000)); + + contacts.add(new Contact(firstName + " " + lastName, email, phone)); + } + + contactRepository.saveAll(contacts); + } +} diff --git a/vaadin/src/main/java/com/baeldung/Employee.java b/vaadin/src/main/java/com/baeldung/data/Employee.java similarity index 85% rename from vaadin/src/main/java/com/baeldung/Employee.java rename to vaadin/src/main/java/com/baeldung/data/Employee.java index 726f0838b6..2685e38286 100644 --- a/vaadin/src/main/java/com/baeldung/Employee.java +++ b/vaadin/src/main/java/com/baeldung/data/Employee.java @@ -1,8 +1,9 @@ -package com.baeldung; +package com.baeldung.data; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; @Entity public class Employee { diff --git a/vaadin/src/main/java/com/baeldung/EmployeeRepository.java b/vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java similarity index 89% rename from vaadin/src/main/java/com/baeldung/EmployeeRepository.java rename to vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java index 044160da78..0d54148c85 100644 --- a/vaadin/src/main/java/com/baeldung/EmployeeRepository.java +++ b/vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.data; import java.util.List; diff --git a/vaadin/src/main/java/com/baeldung/introduction/BindData.java b/vaadin/src/main/java/com/baeldung/introduction/BindData.java deleted file mode 100644 index 299554c039..0000000000 --- a/vaadin/src/main/java/com/baeldung/introduction/BindData.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.baeldung.introduction; - -public class BindData { - - private String bindName; - - public BindData(String bindName){ - this.bindName = bindName; - } - - public String getBindName() { - return bindName; - } - - public void setBindName(String bindName) { - this.bindName = bindName; - } - - -} diff --git a/vaadin/src/main/java/com/baeldung/introduction/FormView.java b/vaadin/src/main/java/com/baeldung/introduction/FormView.java new file mode 100644 index 0000000000..34bc334b27 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/FormView.java @@ -0,0 +1,88 @@ +package com.baeldung.introduction; + +import com.baeldung.data.Contact; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.html.H2; +import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; +import com.vaadin.flow.router.Route; + +@Route("form") +public class FormView extends HorizontalLayout { + + public FormView() { + addBeanValidationExample(); + addCustomValidationExample(); + } + + private void addBeanValidationExample() { + var nameField = new TextField("Name"); + var emailField = new TextField("Email"); + var phoneField = new TextField("Phone"); + var saveButton = new Button("Save"); + + var binder = new BeanValidationBinder<>(Contact.class); + + binder.forField(nameField).bind(Contact::getName, Contact::setName); + binder.forField(emailField).bind(Contact::getEmail, Contact::setEmail); + binder.forField(phoneField).bind(Contact::getPhone, Contact::setPhone); + + var contact = new Contact("John Doe", "john@doe.com", "123-456-7890"); + binder.setBean(contact); + + saveButton.addClickListener(e -> { + if (binder.validate().isOk()) { + Notification.show("Saved " + contact); + } + }); + + add(new VerticalLayout( + new H2("Bean Validation Example"), + nameField, + emailField, + phoneField, + saveButton + )); + } + + private void addCustomValidationExample() { + + var nameField = new TextField("Name"); + var emailField = new TextField("Email"); + var phoneField = new TextField("Phone"); + var saveButton = new Button("Save"); + + var binder = new Binder<>(Contact.class); + + binder.forField(nameField) + .asRequired() + .bind(Contact::getName, Contact::setName); + binder.forField(emailField) + .withValidator(email -> email.contains("@"), "Not a valid email address") + .bind(Contact::getEmail, Contact::setEmail); + binder.forField(phoneField) + .withValidator(phone -> phone.matches("\\d{3}-\\d{3}-\\d{4}"), "Not a valid phone number") + .bind(Contact::getPhone, Contact::setPhone); + + var contact = new Contact("John Doe", "john@doe.com", "123-456-7890"); + binder.setBean(contact); + + saveButton.addClickListener(e -> { + if (binder.validate().isOk()) { + Notification.show("Saved " + contact); + } + }); + + add(new VerticalLayout( + new H2("Custom Validation Example"), + nameField, + emailField, + phoneField, + saveButton + )); + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/GridView.java b/vaadin/src/main/java/com/baeldung/introduction/GridView.java new file mode 100644 index 0000000000..3d9500d7d8 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/GridView.java @@ -0,0 +1,40 @@ +package com.baeldung.introduction; + +import com.baeldung.data.Contact; +import com.baeldung.data.ContactRepository; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.data.VaadinSpringDataHelpers; + +@Route("grid") +public class GridView extends VerticalLayout { + + public GridView(ContactRepository contactRepository) { + + add(new H1("Using data grids")); + + // Define a grid for a Contact entity + var grid = new Grid(); + grid.addColumn(Contact::getName).setHeader("Name"); + grid.addColumn(Contact::getEmail).setHeader("Email"); + grid.addColumn(Contact::getPhone).setHeader("Phone"); + + // There are two ways to populate the grid with data: + + // 1) In-memory with a list of items + var contacts = contactRepository.findAll(); + grid.setItems(contacts); + + // 2) with a callback to lazily load items from a data source. + grid.setItems(query -> { + // Turn the page, offset, filter, sort and other info in query into a Spring Data PageRequest + var pageRequest = VaadinSpringDataHelpers.toSpringPageRequest(query); + return contactRepository.findAll(pageRequest).stream(); + }); + + add(grid); + + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/PushView.java b/vaadin/src/main/java/com/baeldung/introduction/PushView.java new file mode 100644 index 0000000000..28d8162003 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/PushView.java @@ -0,0 +1,27 @@ +package com.baeldung.introduction; + +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.html.Span; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.Route; +import reactor.core.publisher.Flux; + +import java.time.Duration; +import java.time.Instant; + +// Ensure you have @Push annotation in your Application class +@Route("push") +public class PushView extends VerticalLayout { + + public PushView() { + var output = new Span(); + + add(new H1("Server Push"), output); + + Flux.interval(Duration.ofSeconds(1)) + .map(o -> "Server time: " + Instant.now()) + .subscribe(time -> getUI().ifPresent(ui -> ui.access(() -> { + output.setText(time); + }))); + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/Row.java b/vaadin/src/main/java/com/baeldung/introduction/Row.java deleted file mode 100644 index 412a286376..0000000000 --- a/vaadin/src/main/java/com/baeldung/introduction/Row.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.baeldung.introduction; - -public class Row { - - private String column1; - - private String column2; - - private String column3; - - public Row() { - - } - - public Row(String column1, String column2, String column3) { - super(); - this.column1 = column1; - this.column2 = column2; - this.column3 = column3; - } - - public String getColumn1() { - return column1; - } - - public void setColumn1(String column1) { - this.column1 = column1; - } - - public String getColumn2() { - return column2; - } - - public void setColumn2(String column2) { - this.column2 = column2; - } - - public String getColumn3() { - return column3; - } - - public void setColumn3(String column3) { - this.column3 = column3; - } -} \ No newline at end of file diff --git a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java b/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java deleted file mode 100644 index 22ce19f5e0..0000000000 --- a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java +++ /dev/null @@ -1,282 +0,0 @@ -package com.baeldung.introduction; - -import java.time.Instant; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.servlet.annotation.WebServlet; - -import com.vaadin.annotations.Push; -import com.vaadin.annotations.Theme; -import com.vaadin.annotations.VaadinServletConfiguration; -import com.vaadin.data.Binder; -import com.vaadin.data.validator.StringLengthValidator; -import com.vaadin.icons.VaadinIcons; -import com.vaadin.server.ExternalResource; -import com.vaadin.server.VaadinRequest; -import com.vaadin.server.VaadinServlet; -import com.vaadin.ui.Button; -import com.vaadin.ui.CheckBox; -import com.vaadin.ui.ComboBox; -import com.vaadin.ui.DateField; -import com.vaadin.ui.FormLayout; -import com.vaadin.ui.Grid; -import com.vaadin.ui.GridLayout; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.InlineDateField; -import com.vaadin.ui.Label; -import com.vaadin.ui.Link; -import com.vaadin.ui.ListSelect; -import com.vaadin.ui.NativeButton; -import com.vaadin.ui.NativeSelect; -import com.vaadin.ui.Panel; -import com.vaadin.ui.PasswordField; -import com.vaadin.ui.RichTextArea; -import com.vaadin.ui.TextArea; -import com.vaadin.ui.TextField; -import com.vaadin.ui.TwinColSelect; -import com.vaadin.ui.UI; -import com.vaadin.ui.VerticalLayout; - -@SuppressWarnings("serial") -@Push -@Theme("mytheme") -public class VaadinUI extends UI { - - private Label currentTime; - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - protected void init(VaadinRequest vaadinRequest) { - final VerticalLayout verticalLayout = new VerticalLayout(); - verticalLayout.setSpacing(true); - verticalLayout.setMargin(true); - final GridLayout gridLayout = new GridLayout(3, 2); - gridLayout.setSpacing(true); - gridLayout.setMargin(true); - final HorizontalLayout horizontalLayout = new HorizontalLayout(); - horizontalLayout.setSpacing(true); - horizontalLayout.setMargin(true); - final FormLayout formLayout = new FormLayout(); - formLayout.setSpacing(true); - formLayout.setMargin(true); - final GridLayout buttonLayout = new GridLayout(3, 5); - buttonLayout.setMargin(true); - buttonLayout.setSpacing(true); - - final Label label = new Label(); - label.setId("Label"); - label.setValue("Label Value"); - label.setCaption("Label"); - gridLayout.addComponent(label); - - final Link link = new Link("Baeldung", new ExternalResource("http://www.baeldung.com/")); - link.setId("Link"); - link.setTargetName("_blank"); - gridLayout.addComponent(link); - - final TextField textField = new TextField(); - textField.setId("TextField"); - textField.setCaption("TextField:"); - textField.setValue("TextField Value"); - textField.setIcon(VaadinIcons.USER); - gridLayout.addComponent(textField); - - final TextArea textArea = new TextArea(); - textArea.setCaption("TextArea"); - textArea.setId("TextArea"); - textArea.setValue("TextArea Value"); - gridLayout.addComponent(textArea); - - final DateField dateField = new DateField("DateField", LocalDate.ofEpochDay(0)); - dateField.setId("DateField"); - gridLayout.addComponent(dateField); - - final PasswordField passwordField = new PasswordField(); - passwordField.setId("PasswordField"); - passwordField.setCaption("PasswordField:"); - passwordField.setValue("password"); - gridLayout.addComponent(passwordField); - - final RichTextArea richTextArea = new RichTextArea(); - richTextArea.setCaption("Rich Text Area"); - richTextArea.setValue("

RichTextArea

"); - richTextArea.setSizeFull(); - - Panel richTextPanel = new Panel(); - richTextPanel.setContent(richTextArea); - - final InlineDateField inlineDateField = new InlineDateField(); - inlineDateField.setValue(LocalDate.ofEpochDay(0)); - inlineDateField.setCaption("Inline Date Field"); - horizontalLayout.addComponent(inlineDateField); - - Button normalButton = new Button("Normal Button"); - normalButton.setId("NormalButton"); - normalButton.addClickListener(e -> { - label.setValue("CLICK"); - }); - buttonLayout.addComponent(normalButton); - - Button tinyButton = new Button("Tiny Button"); - tinyButton.addStyleName("tiny"); - buttonLayout.addComponent(tinyButton); - - Button smallButton = new Button("Small Button"); - smallButton.addStyleName("small"); - buttonLayout.addComponent(smallButton); - - Button largeButton = new Button("Large Button"); - largeButton.addStyleName("large"); - buttonLayout.addComponent(largeButton); - - Button hugeButton = new Button("Huge Button"); - hugeButton.addStyleName("huge"); - buttonLayout.addComponent(hugeButton); - - Button disabledButton = new Button("Disabled Button"); - disabledButton.setDescription("This button cannot be clicked"); - disabledButton.setEnabled(false); - buttonLayout.addComponent(disabledButton); - - Button dangerButton = new Button("Danger Button"); - dangerButton.addStyleName("danger"); - buttonLayout.addComponent(dangerButton); - - Button friendlyButton = new Button("Friendly Button"); - friendlyButton.addStyleName("friendly"); - buttonLayout.addComponent(friendlyButton); - - Button primaryButton = new Button("Primary Button"); - primaryButton.addStyleName("primary"); - buttonLayout.addComponent(primaryButton); - - NativeButton nativeButton = new NativeButton("Native Button"); - buttonLayout.addComponent(nativeButton); - - Button iconButton = new Button("Icon Button"); - iconButton.setIcon(VaadinIcons.ALIGN_LEFT); - buttonLayout.addComponent(iconButton); - - Button borderlessButton = new Button("BorderLess Button"); - borderlessButton.addStyleName("borderless"); - buttonLayout.addComponent(borderlessButton); - - Button linkButton = new Button("Link Button"); - linkButton.addStyleName("link"); - buttonLayout.addComponent(linkButton); - - Button quietButton = new Button("Quiet Button"); - quietButton.addStyleName("quiet"); - buttonLayout.addComponent(quietButton); - - horizontalLayout.addComponent(buttonLayout); - - final CheckBox checkbox = new CheckBox("CheckBox"); - checkbox.setValue(true); - checkbox.addValueChangeListener(e -> checkbox.setValue(!checkbox.getValue())); - formLayout.addComponent(checkbox); - - List numbers = new ArrayList(); - numbers.add("One"); - numbers.add("Ten"); - numbers.add("Eleven"); - ComboBox comboBox = new ComboBox("ComboBox"); - comboBox.setItems(numbers); - formLayout.addComponent(comboBox); - - ListSelect listSelect = new ListSelect("ListSelect"); - listSelect.setItems(numbers); - listSelect.setRows(2); - formLayout.addComponent(listSelect); - - NativeSelect nativeSelect = new NativeSelect("NativeSelect"); - nativeSelect.setItems(numbers); - formLayout.addComponent(nativeSelect); - - TwinColSelect twinColSelect = new TwinColSelect("TwinColSelect"); - twinColSelect.setItems(numbers); - - Grid 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 rows = new ArrayList(); - rows.add(row1); - rows.add(row2); - grid.setItems(rows); - - Panel panel = new Panel("Panel"); - panel.setContent(grid); - panel.setSizeUndefined(); - - Panel serverPushPanel = new Panel("Server Push"); - FormLayout timeLayout = new FormLayout(); - timeLayout.setSpacing(true); - timeLayout.setMargin(true); - currentTime = new Label("No TIME..."); - timeLayout.addComponent(currentTime); - serverPushPanel.setContent(timeLayout); - serverPushPanel.setSizeUndefined(); - ScheduledExecutorService scheduleExecutor = Executors.newScheduledThreadPool(1); - Runnable task = () -> { - currentTime.setValue("Current Time : " + Instant.now()); - }; - scheduleExecutor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS); - - FormLayout dataBindingLayout = new FormLayout(); - dataBindingLayout.setSpacing(true); - dataBindingLayout.setMargin(true); - - Binder binder = new Binder<>(); - BindData bindData = new BindData("BindData"); - binder.readBean(bindData); - TextField bindedTextField = new TextField(); - bindedTextField.setWidth("250px"); - binder.forField(bindedTextField).bind(BindData::getBindName, BindData::setBindName); - dataBindingLayout.addComponent(bindedTextField); - - FormLayout validatorLayout = new FormLayout(); - validatorLayout.setSpacing(true); - validatorLayout.setMargin(true); - - HorizontalLayout textValidatorLayout = new HorizontalLayout(); - textValidatorLayout.setSpacing(true); - textValidatorLayout.setMargin(true); - - - BindData stringValidatorBindData = new BindData(""); - TextField stringValidator = new TextField(); - Binder 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); - - textValidatorLayout.addComponent(stringValidator); - Button buttonStringValidator = new Button("Validate String"); - buttonStringValidator.addClickListener(e -> stringValidatorBinder.validate()); - textValidatorLayout.addComponent(buttonStringValidator); - - validatorLayout.addComponent(textValidatorLayout); - verticalLayout.addComponent(gridLayout); - verticalLayout.addComponent(richTextPanel); - verticalLayout.addComponent(horizontalLayout); - verticalLayout.addComponent(formLayout); - verticalLayout.addComponent(twinColSelect); - verticalLayout.addComponent(panel); - verticalLayout.addComponent(serverPushPanel); - verticalLayout.addComponent(dataBindingLayout); - verticalLayout.addComponent(validatorLayout); - setContent(verticalLayout); - } - - @WebServlet(urlPatterns = "/VAADIN/*", name = "MyUIServlet", asyncSupported = true) - @VaadinServletConfiguration(ui = VaadinUI.class, productionMode = false) - public static class MyUIServlet extends VaadinServlet { - } -} \ No newline at end of file diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java b/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java new file mode 100644 index 0000000000..477cf378c6 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java @@ -0,0 +1,13 @@ +package com.baeldung.introduction.basics; + +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.Route; + +@Route("hello-world") +public class HelloWorldView extends VerticalLayout { + + public HelloWorldView() { + add(new H1("Hello, World!")); + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java b/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java new file mode 100644 index 0000000000..cd028dcd1d --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java @@ -0,0 +1,61 @@ +package com.baeldung.introduction.basics; + +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.checkbox.Checkbox; +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.router.RouterLink; + +// The @Route annotation defines the URL path for the view +// Any component, most commonly a layout, can be used as a view +@Route("basics") +public class VaadinFlowBasics extends VerticalLayout { + public VaadinFlowBasics() { + + // Add components to the layout with the add method + add(new H1("Vaadin Flow Basics")); + + // Components are Java objects + var textField = new TextField("Name"); + var button = new Button("Click me"); + + // Layouts define the structure of the UI + var verticalLayout = new VerticalLayout( + new Button("Top"), + new Button("Middle"), + new Button("Bottom") + ); + add(verticalLayout); + + var horizontalLayout = new HorizontalLayout( + new Button("Left"), + new Button("Center"), + new Button("Right") + ); + add(horizontalLayout); + + // Layouts can be nested for more complex structures + var nestedLayout = new VerticalLayout( + new HorizontalLayout(new Button("Top Left"), new Button("Top Right")), + new HorizontalLayout(new Button("Bottom Left"), new Button("Bottom Right")) + ); + add(nestedLayout); + + // Use RouterLink to navigate to other views + var link = new RouterLink("Hello world view", HelloWorldView.class); + add(link); + + // Use events to react to user input + var nameField = new TextField("Your name"); + var helloButton = new Button("Say hello"); + helloButton.addClickListener(e -> { + Notification.show("Hello, " + nameField.getValue()); + }); + add(nameField, helloButton); + + } +} diff --git a/vaadin/src/main/java/com/baeldung/MainView.java b/vaadin/src/main/java/com/baeldung/spring/CrudView.java similarity index 89% rename from vaadin/src/main/java/com/baeldung/MainView.java rename to vaadin/src/main/java/com/baeldung/spring/CrudView.java index 6d4c0aaa88..a77e32e965 100644 --- a/vaadin/src/main/java/com/baeldung/MainView.java +++ b/vaadin/src/main/java/com/baeldung/spring/CrudView.java @@ -1,5 +1,7 @@ -package com.baeldung; +package com.baeldung.spring; +import com.baeldung.data.Employee; +import com.baeldung.data.EmployeeRepository; import org.springframework.util.StringUtils; import com.vaadin.flow.component.button.Button; @@ -11,8 +13,8 @@ import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.data.value.ValueChangeMode; import com.vaadin.flow.router.Route; -@Route -public class MainView extends VerticalLayout { +@Route("crud") +public class CrudView extends VerticalLayout { private final EmployeeRepository employeeRepository; @@ -24,7 +26,7 @@ public class MainView extends VerticalLayout { private final Button addNewBtn; - public MainView(EmployeeRepository repo, EmployeeEditor editor) { + public CrudView(EmployeeRepository repo, EmployeeEditor editor) { this.employeeRepository = repo; this.editor = editor; this.grid = new Grid<>(Employee.class); diff --git a/vaadin/src/main/java/com/baeldung/EmployeeEditor.java b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java similarity index 96% rename from vaadin/src/main/java/com/baeldung/EmployeeEditor.java rename to vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java index ee312786d1..25e447102c 100644 --- a/vaadin/src/main/java/com/baeldung/EmployeeEditor.java +++ b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java @@ -1,5 +1,7 @@ -package com.baeldung; +package com.baeldung.spring; +import com.baeldung.data.Employee; +import com.baeldung.data.EmployeeRepository; import com.vaadin.flow.component.Key; import com.vaadin.flow.component.KeyNotifier; import com.vaadin.flow.component.button.Button; diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss b/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss deleted file mode 100644 index a5670b70c7..0000000000 --- a/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss +++ /dev/null @@ -1,7 +0,0 @@ -/* This file is automatically managed and will be overwritten from time to time. */ -/* Do not manually edit this file. */ - -/* Import and include this mixin into your project theme to include the addon themes */ -@mixin addons { -} - diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico b/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico deleted file mode 100644 index ffb34a65c7..0000000000 Binary files a/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico and /dev/null differ diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss b/vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss deleted file mode 100644 index 2c5fb8b944..0000000000 --- a/vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss +++ /dev/null @@ -1,38 +0,0 @@ -// If you edit this file you need to compile the theme. See README.md for details. - -// Global variable overrides. Must be declared before importing Valo. - -// Defines the plaintext font size, weight and family. Font size affects general component sizing. -//$v-font-size: 16px; -//$v-font-weight: 300; -//$v-font-family: "Open Sans", sans-serif; - -// Defines the border used by all components. -//$v-border: 1px solid (v-shade 0.7); -//$v-border-radius: 4px; - -// Affects the color of some component elements, e.g Button, Panel title, etc -//$v-background-color: hsl(210, 0%, 98%); -// Affects the color of content areas, e.g Panel and Window content, TextField input etc -//$v-app-background-color: $v-background-color; - -// Affects the visual appearance of all components -//$v-gradient: v-linear 8%; -//$v-bevel-depth: 30%; -//$v-shadow-opacity: 5%; - -// Defines colors for indicating status (focus, success, failure) -//$v-focus-color: valo-focus-color(); // Calculates a suitable color automatically -//$v-friendly-color: #2c9720; -//$v-error-indicator-color: #ed473b; - -// For more information, see: https://vaadin.com/book/-/page/themes.valo.html -// Example variants can be copy/pasted from https://vaadin.com/wiki/-/wiki/Main/Valo+Examples - -@import "../valo/valo.scss"; - -@mixin mytheme { - @include valo; - - // Insert your own theme rules here -} diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss b/vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss deleted file mode 100644 index bba1d493c0..0000000000 --- a/vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss +++ /dev/null @@ -1,11 +0,0 @@ -@import "mytheme.scss"; -@import "addons.scss"; - -// This file prefixes all rules with the theme name to avoid causing conflicts with other themes. -// The actual styles should be defined in mytheme.scss - -.mytheme { - @include addons; - @include mytheme; - -}