Skip to content

Commit a76ea85

Browse files
committed
Update quick start with Aura screenshots and improvements from the DX test
1 parent 15e13ea commit a76ea85

File tree

6 files changed

+50
-62
lines changed

6 files changed

+50
-62
lines changed
546 KB
Loading
594 KB
Loading
596 KB
Loading
600 KB
Loading
595 KB
Loading

articles/getting-started/quick-start/index.adoc

Lines changed: 50 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -60,28 +60,17 @@ public class MainView extends VerticalLayout { // <3>
6060

6161
== Run the Application
6262

63-
You can run the application <<../dev-environment/run#,directly from your IDE>> or from the command line. To run it from the command line, open a terminal in the project directory and run the following command:
63+
To get the best development experience, run your application from your IDE with *hotswap* enabled. Hotswap automatically applies your code changes to the running application without restarting it, which saves a lot of time during this tutorial.
6464

65-
[.example]
66-
--
67-
.Terminal
68-
[source,terminal,subs="+attributes"]
69-
----
70-
<source-info group="macOS / Linux"></source-info>
71-
./mvnw
72-
----
65+
To enable hotswap, install the *Vaadin plugin* for your IDE and use it to start the application. You can find IDE-specific instructions here:
7366

74-
.PowerShell
75-
[source,terminal,subs="+attributes"]
76-
----
77-
<source-info group="Windows"></source-info>
78-
mvnw
79-
----
80-
--
67+
* <<../dev-environment/run/intellij#,IntelliJ IDEA>>
68+
* <<../dev-environment/run/vscode#,Visual Studio Code>>
69+
* <<../dev-environment/run/eclipse#,Eclipse IDE>>
70+
* <<../dev-environment/run/netbeans#,NetBeans>>
8171

82-
.Command Line Limitations
83-
[TIP]
84-
When you run the project from the command line, you have to restart the application every time you make a change to the code. If you run the application <<../dev-environment/run#,from your IDE>> you can use *hot swapping*, which automatically applies changes to your running application without restarting.
72+
[IMPORTANT]
73+
Even if you are already familiar with your IDE, follow the instructions above. Running the application with hotswap requires the *Vaadin plugin*, which you may not have installed yet.
8574

8675
The first startup may take a while as Maven and npm download the required dependencies.
8776

@@ -96,7 +85,7 @@ It should look like this:
9685
[.device]
9786
image::images/first-view.png[The first Vaadin view displaying a greeting message]
9887

99-
The [guilabel]*}>* button in the bottom-right corner is the *Copilot menu*, which is visible when running in development mode. You'll learn more about it later.
88+
The toolbar in the bottom-right corner is the *Copilot toolbar*, which is visible when running in development mode. See the <</tools/copilot#,Copilot documentation>> for details.
10089

10190

10291
== Add Functionality
@@ -113,7 +102,7 @@ import com.vaadin.flow.component.button.Button;
113102
// end::snippet[]
114103
import com.vaadin.flow.component.html.H1;
115104
// tag::snippet[]
116-
import com.vaadin.flow.component.html.Span;
105+
import com.vaadin.flow.component.html.Paragraph;
117106
// end::snippet[]
118107
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
119108
import com.vaadin.flow.router.PageTitle;
@@ -125,21 +114,21 @@ public class MainView extends VerticalLayout {
125114
public MainView() {
126115
add(new H1("Hello, Vaadin!"));
127116
// tag::snippet[]
128-
add(new Button("Say Hello", event -> add(new Span("Hello, Vaadin!")))); // <1>
117+
add(new Button("Say Hello", event -> add(new Paragraph("Hello, Vaadin!")))); // <1>
129118
// end::snippet[]
130119
}
131120
}
132121
----
133-
<1> This line creates a new Button with the label "Say Hello". When clicked, it triggers a lambda function that adds a new `Span` with the message "Hello, Vaadin!" to the view. A span corresponds to the HTML `<span>` element, which is an inline container for text.
122+
<1> This line creates a new Button with the label "Say Hello". When clicked, it triggers a lambda function that adds a new `Paragraph` with the message "Hello, Vaadin!" to the view.
134123

135124
This programming model is typical for Vaadin applications. You construct the UI from components, and define behavior using event listeners. If you have used Swing or JavaFX before, this should feel familiar.
136125

137-
If you started the application from your IDE with <<../dev-environment/run#,hotswap (automatic code reload) enabled>>, the changes should be reflected automatically. If not, restart the application and refresh the browser. Click the button to see what happens:
126+
If you set up hotswap as instructed earlier, the changes are applied automatically. Just switch to the browser and click the button to see what happens:
138127

139128
[.device]
140129
image::images/second-view.png[The updated Vaadin view with a button and a text span]
141130

142-
The text is added to the end of the view, below the button. If you click multiple times, new texts are added each time.
131+
The paragraph is added to the end of the view, below the button. If you click multiple times, new paragraphs are added each time.
143132

144133

145134
== Add Input
@@ -153,7 +142,7 @@ package com.example;
153142
154143
import com.vaadin.flow.component.button.Button;
155144
import com.vaadin.flow.component.html.H1;
156-
import com.vaadin.flow.component.html.Span;
145+
import com.vaadin.flow.component.html.Paragraph;
157146
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
158147
// tag::snippet[]
159148
import com.vaadin.flow.component.textfield.TextField;
@@ -172,14 +161,14 @@ public class MainView extends VerticalLayout {
172161
// end::snippet[]
173162
add(new Button("Say Hello", event ->
174163
// tag::snippet[]
175-
add(new Span("Hello, %s!".formatted(nameField.getValue()))) // <2>
164+
add(new Paragraph("Hello, %s!".formatted(nameField.getValue()))) // <2>
176165
// end::snippet[]
177166
));
178167
}
179168
}
180169
----
181170
<1> Creates a `TextField` component with a label prompting the user for their name.
182-
<2> Adds a new `Span` with a personalized greeting message to the view.
171+
<2> Adds a new `Paragraph` with a personalized greeting message to the view.
183172

184173
Now the browser view should look like this:
185174

@@ -195,7 +184,7 @@ Vaadin takes care of input sanitization and escaping to prevent security vulnera
195184

196185
== Update a Component
197186

198-
The problem with the current implementation is that each time you click the button, a new text is added. Instead, you want to add a single `Span` and update its content on every click. Modify the `MainView` class as follows:
187+
The problem with the current implementation is that each time you click the button, a new paragraph is added. Instead, you want to add a single `Paragraph` and update its content on every click. Modify the `MainView` class as follows:
199188

200189
.MainView.java
201190
[source,java]
@@ -204,7 +193,7 @@ package com.example;
204193
205194
import com.vaadin.flow.component.button.Button;
206195
import com.vaadin.flow.component.html.H1;
207-
import com.vaadin.flow.component.html.Span;
196+
import com.vaadin.flow.component.html.Paragraph;
208197
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
209198
import com.vaadin.flow.component.textfield.TextField;
210199
import com.vaadin.flow.router.PageTitle;
@@ -218,7 +207,7 @@ public class MainView extends VerticalLayout {
218207
var nameField = new TextField("What is your name?");
219208
add(nameField);
220209
// tag::snippet[]
221-
var greeting = new Span(); // <1>
210+
var greeting = new Paragraph(); // <1>
222211
add(greeting);
223212
// end::snippet[]
224213
add(new Button("Say Hello", event ->
@@ -229,15 +218,15 @@ public class MainView extends VerticalLayout {
229218
}
230219
}
231220
----
232-
<1> Creates a `Span` component to hold the greeting message and adds it to the view above the button.
233-
<2> Updates the text of the existing `Span` instead of adding a new one.
221+
<1> Creates a `Paragraph` component to hold the greeting message and adds it to the view above the button.
222+
<2> Updates the text of the existing `Paragraph` instead of adding a new one.
234223

235224
If you now try the application again, you'll see that there is some extra space between the text field and the button:
236225

237226
[.device]
238227
image::images/fourth-view.png[The Vaadin view with a button to generate a QR code]
239228

240-
This is because the `Span` component is initially empty but still occupies space in the layout. You can fix that by hiding the `Span` when it has no content. Update the code as follows:
229+
This is because the `Paragraph` component is initially empty but still occupies space in the layout. You can fix that by hiding the `Paragraph` when it has no content. Update the code as follows:
241230

242231
.MainView.java
243232
[source,java]
@@ -246,7 +235,7 @@ package com.example;
246235
247236
import com.vaadin.flow.component.button.Button;
248237
import com.vaadin.flow.component.html.H1;
249-
import com.vaadin.flow.component.html.Span;
238+
import com.vaadin.flow.component.html.Paragraph;
250239
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
251240
import com.vaadin.flow.component.textfield.TextField;
252241
import com.vaadin.flow.router.PageTitle;
@@ -259,7 +248,7 @@ public class MainView extends VerticalLayout {
259248
add(new H1("Hello, Vaadin!"));
260249
var nameField = new TextField("What is your name?");
261250
add(nameField);
262-
var greeting = new Span();
251+
var greeting = new Paragraph();
263252
// tag::snippet[]
264253
greeting.setVisible(false); // <1>
265254
// end::snippet[]
@@ -273,8 +262,8 @@ public class MainView extends VerticalLayout {
273262
}
274263
}
275264
----
276-
<1> Hides the `Span` component initially since it has no content.
277-
<2> Sets the visibility of the `Span` based on whether the `TextField` is empty or not.
265+
<1> Hides the `Paragraph` component initially since it has no content.
266+
<2> Sets the visibility of the `Paragraph` based on whether the `TextField` is empty or not. By default, a text field is empty if its value is an empty string.
278267

279268
If you now enter your name and click the button, you'll see that the greeting message updates in place each time you click the button. If you clear the text field and click the button, the greeting message disappears and no extra space is occupied.
280269

@@ -312,7 +301,7 @@ import com.vaadin.flow.component.html.H1;
312301
// tag::snippet[]
313302
import com.vaadin.flow.component.html.Image;
314303
// end::snippet[]
315-
import com.vaadin.flow.component.html.Span;
304+
import com.vaadin.flow.component.html.Paragraph;
316305
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
317306
import com.vaadin.flow.component.textfield.TextField;
318307
import com.vaadin.flow.router.PageTitle;
@@ -329,7 +318,7 @@ public class MainView extends VerticalLayout {
329318
add(new H1("Hello, Vaadin!"));
330319
var nameField = new TextField("What is your name?");
331320
add(nameField);
332-
var greeting = new Span();
321+
var greeting = new Paragraph();
333322
greeting.setVisible(false);
334323
add(greeting);
335324
add(new Button("Say Hello", event -> {
@@ -338,9 +327,15 @@ public class MainView extends VerticalLayout {
338327
}));
339328
// tag::snippet[]
340329
var qrImage = new Image();
341-
add(new Button("Generate QR Code", event ->
342-
qrImage.setSrc(generateQrCode(nameField.getValue())) // <1>
343-
));
330+
add(new Button("Generate QR Code", event -> {
331+
if (nameField.isEmpty()) {
332+
nameField.setErrorMessage("Enter a name"); // <1>
333+
nameField.setInvalid(true);
334+
} else {
335+
nameField.setInvalid(false);
336+
qrImage.setSrc(generateQrCode(nameField.getValue())); // <2>
337+
}
338+
}));
344339
add(qrImage);
345340
// end::snippet[]
346341
}
@@ -352,7 +347,7 @@ public class MainView extends VerticalLayout {
352347
var qrWriter = new QRCodeWriter();
353348
var bitMatrix = qrWriter.encode(text, BarcodeFormat.QR_CODE, 300, 300);
354349
downloadEvent.setContentType("image/png");
355-
MatrixToImageWriter.writeToStream(bitMatrix, "PNG", out); // <2>
350+
MatrixToImageWriter.writeToStream(bitMatrix, "PNG", out); // <3>
356351
} catch (WriterException e) {
357352
throw new IOException(e);
358353
}
@@ -361,39 +356,32 @@ public class MainView extends VerticalLayout {
361356
// end::snippet[]
362357
}
363358
----
364-
<1> The image source can be either a URL or a `DownloadHandler`. Vaadin serves server-generated content using the `DownloadHandler` interface.
365-
<2> The QR code is generated and written to the output stream as a PNG image.
359+
<1> Sets an error message on the text field and marks it as invalid, which displays the error to the user.
360+
<2> The image source can be either a URL or a `DownloadHandler`. Vaadin serves server-generated content using the `DownloadHandler` interface.
361+
<3> The QR code is generated and written to the output stream as a PNG image.
366362

367-
Because you have added new dependencies to the project, you have to restart the application for the changes to take effect. After restarting, enter a name and click the [guibutton]*Generate QR Code* button. A QR code representing the entered name will be displayed below the button:
363+
Because you have added new dependencies to the project, you have to stop and restart the application from your IDE for the changes to take effect. After restarting, enter a name and click the [guibutton]*Generate QR Code* button. A QR code representing the entered name is displayed below the button:
368364

369365
[.device]
370366
image::images/fifth-view.png[The Vaadin view with a button to generate a QR code]
371367

368+
If you click the button with an empty text field, an error message is shown instead.
369+
372370
Having access to the entire Java ecosystem allows you to leverage existing libraries and tools in your Vaadin applications, making development faster and easier.
373371

374372

375373
== Make a Production Build
376374

377375
Up to this point, you have been running the application in development mode, which is optimized for fast feedback during development. Before deploying your application to production, you should create a production build that is optimized for performance.
378376

379-
Execute the Maven `package` goal to create a production build. You can do it from the command line like this:
377+
Execute the Maven `package` goal to create a production build. Stop the application in your IDE, then run the following command from the project directory:
380378

381-
[.example]
382-
--
383-
.Terminal
384-
[source,bash,subs="+attributes"]
379+
[source,terminal]
385380
----
386-
<source-info group="macOS / Linux"></source-info>
387-
./mvnw clean package
381+
mvn clean package
388382
----
389383

390-
.PowerShell
391-
[source,powershell,subs="+attributes"]
392-
----
393-
<source-info group="Windows"></source-info>
394-
mvnw clean package
395-
----
396-
--
384+
TIP: If you don't have Maven installed, you can use the Maven Wrapper included in the project instead: `./mvnw clean package`.
397385

398386
After the build completes, check the `target` directory in your project. You should find a JAR file named `app-1.0-SNAPSHOT.jar` (assuming your project is named `app`).
399387
You can run the production build using the following command:
@@ -404,7 +392,7 @@ You can run the production build using the following command:
404392
java -jar target/app-1.0-SNAPSHOT.jar
405393
----
406394

407-
Open your browser and navigate to http://localhost:8080 to see your application running in production mode. You'll notice that the [guilabel]*}>* button is no longer visible.
395+
Open your browser and navigate to http://localhost:8080 to see your application running in production mode. You'll notice that the Copilot toolbar is no longer visible.
408396

409397

410398
== Next Steps

0 commit comments

Comments
 (0)