1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
|
---
title: Images and Other Resources
order: 5
layout: page
---
[[application.resources]]
= Images and Other Resources
Web applications can display various __resources__, such as images, other
embedded content, or downloadable files, that the browser has to load from the
server. Image resources are typically displayed with the [classname]#Image#
component or as component icons. Embedded browser frames can be displayed with [classname]#BrowserFrame#, and
other content with the [classname]#Embedded# component, as described in
<<dummy/../../../framework/components/components-embedded#components.embedded,"Embedded
Resources">>. Downloadable files are usually provided by clicking a
[classname]#Link# or using the [classname]#FileDownloader# extension.
There are several ways to how such resources can be provided by the web server.
Static resources can be provided without having to ask for them from the
application. For dynamic resources, the user application must be able to create
them dynamically. The resource request interfaces in Vaadin allow applications
to both refer to static resources as well as dynamically create them. The
dynamic creation includes the [classname]#StreamResource# class and the
[interfacename]#RequestHandler# described in
<<dummy/../../../framework/advanced/advanced-requesthandler#advanced.requesthandler,"Request
Handlers">>.
Vaadin also provides low-level facilities for retrieving the URI and other
parameters of a HTTP request. We will first look into how applications can
provide various kinds of resources and then look into low-level interfaces for
handling URIs and parameters to provide resources and functionalities.
Notice that using request handlers to create "pages" is not normally meaningful
in Vaadin or in AJAX applications generally. Please see
<<dummy/../../../framework/architecture/architecture-technology#architecture.technology.ajax,"AJAX">>
for a detailed explanation.
[[application.resources.api]]
== Resource Interfaces and Classes
The resource classes in Vaadin are grouped under two interfaces: a generic
[classname]#Resource# interface and a more specific
[classname]#ConnectorResource# interface for resources provided by the servlet.
[[figure.resource.classdiagram]]
.Resource Interface and Class Diagram
image::img/resource_classdiagram-hi.png[width=80%, scaledwidth=100%]
[[application.resources.file]]
== File Resources
File resources are files stored anywhere in the file system. As such, they can
not be retrieved by a regular URL from the server, but need to be requested
through the Vaadin servlet. The use of file resources is typically necessary for
persistent user data that is not packaged in the web application, which would
not be persistent over redeployments.
A file object that can be accessed as a file resource is defined with the
standard [classname]#java.io.File# class. You can create the file either with an
absolute or relative path, but the base path of the relative path depends on the
installation of the web server. For example, with Apache Tomcat, the default
current directory would be the installation path of Tomcat.
In the following example, we provide an image resource from a file stored in the
web application. Notice that the image is stored under the [filename]#WEB-INF#
folder, which is a special folder that is never accessible using an URL, unlike
the other folders of a web application. This is a security solution - another
would be to store the resource elsewhere in the file system.
[source, java]
----
// Find the application directory
String basepath = VaadinService.getCurrent()
.getBaseDirectory().getAbsolutePath();
// Image as a file resource
FileResource resource = new FileResource(new File(basepath +
"/WEB-INF/images/image.png"));
// Show the image in the application
Image image = new Image("Image from file", resource);
// Let the user view the file in browser or download it
Link link = new Link("Link to the image file", resource);
----
In a Maven based Vaadin project the image file should be located inside [filename]#src/main/webapp/WEB-INF/images/image.png#.
[[application.resources.class]]
== Class Loader Resources
The [classname]#ClassResource# allows resources to be loaded from the class path
using Java Class Loader. Normally, the relevant class path entry is the
[filename]#WEB-INF/classes# folder under the web application, where the Java
compilation should compile the Java classes and copy other files from the source
tree.
The one-line example below loads an image resource from the application package
and displays it in an [classname]#Image# component.
[source, java]
----
layout.addComponent(new Image(null,
new ClassResource("smiley.jpg")));
----
[[application.resources.theme]]
== Theme Resources
Theme resources of [classname]#ThemeResource# class are files, typically images,
included in a theme. A theme is located with the path
[filename]#VAADIN/themes/themename# in a web application. The name of a theme
resource is given as the parameter for the constructor, with a path relative to
the theme folder.
[source, java]
----
// A theme resource in the current theme ("mytheme")
// Located in: VAADIN/themes/mytheme/img/themeimage.png
ThemeResource resource = new ThemeResource("img/themeimage.png");
// Use the resource
Image image = new Image("My Theme Image", resource);
----
To use theme resources, you must set the theme for the UI. See
<<dummy/../../../framework/themes/themes-overview.asciidoc#themes.overview,"Themes">>
for more information regarding themes.
[[application.resources.stream]]
== Stream Resources
Stream resources allow creating dynamic resource content. Charts are typical
examples of dynamic images. To define a stream resource, you need to implement
the [classname]#StreamResource.StreamSource# interface and its
[methodname]#getStream()# method. The method needs to return an
[classname]#InputStream# from which the stream can be read.
The following example demonstrates the creation of a simple image in PNG image
format.
[source, java]
----
import java.awt.image.*;
public class MyImageSource implements StreamSource {
ByteArrayOutputStream imagebuffer = null;
int reloads = 0;
// This method generates the stream contents
public InputStream getStream () {
// Create an image
BufferedImage image = new BufferedImage (400, 400,
BufferedImage.TYPE_INT_RGB);
Graphics2D drawable = image.createGraphics();
// Draw something static
drawable.setStroke(new BasicStroke(5));
drawable.setColor(Color.WHITE);
drawable.fillRect(0, 0, 400, 400);
drawable.setColor(Color.BLACK);
drawable.drawOval(50, 50, 300, 300);
// Draw something dynamic
drawable.setFont(new Font("Montserrat",
Font.PLAIN, 48));
drawable.drawString("Reloads=" + reloads, 75, 216);
reloads++;
drawable.setColor(new Color(0, 165, 235));
int x= (int) (200-10 + 150*Math.sin(reloads * 0.3));
int y= (int) (200-10 + 150*Math.cos(reloads * 0.3));
drawable.fillOval(x, y, 20, 20);
try {
// Write the image to a buffer
imagebuffer = new ByteArrayOutputStream();
ImageIO.write(image, "png", imagebuffer);
// Return a stream from the buffer
return new ByteArrayInputStream(
imagebuffer.toByteArray());
} catch (IOException e) {
return null;
}
}
}
----
The content of the generated image is dynamic, as it updates the reloads counter
with every call. The [classname]#ImageIO#. [methodname]#write()# method writes
the image to an output stream, while we had to return an input stream, so we
stored the image contents to a temporary buffer.
Below we display the image with the [classname]#Image# component.
[source, java]
----
// Create an instance of our stream source.
StreamSource imagesource = new MyImageSource();
// Create a resource that uses the stream source and give it
// a name. The constructor will automatically register the
// resource in the application.
StreamResource resource =
new StreamResource(imagesource, "myimage.png");
// Create an image component that gets its contents
// from the resource.
layout.addComponent(new Image("Image title", resource));
----
The resulting image is shown in <<figure.application.resource.stream>>.
[[figure.application.resource.stream]]
.A stream resource
image::img/application_streamresource.png[width=25%, scaledwidth=25%]
Another way to create dynamic content is a request handler, described in
<<dummy/../../../framework/advanced/advanced-requesthandler#advanced.requesthandler,"Request
Handlers">>.
|