Fixes vaadin/framework8-issues#580tags/8.0.0.beta2
@@ -7,8 +7,6 @@ layout: page | |||
[[application.architecture]] | |||
= Building the UI | |||
*_This section has not yet been updated to Vaadin Framework 8_* | |||
Vaadin Framework user interfaces are built hierarchically from components, so that the | |||
leaf components are contained within layout components and other component | |||
containers. Building the hierarchy starts from the top (or bottom - whichever |
@@ -7,7 +7,7 @@ layout: page | |||
[[application.environment]] | |||
= Deploying an Application | |||
Vaadin applications are deployed as __Java web applications__, which can contain | |||
Vaadin Framework applications are deployed as __Java web applications__, which can contain | |||
a number of servlets, each of which can be a Vaadin application or some other | |||
servlet, and static resources such as HTML files. Such a web application is | |||
normally packaged as a WAR (Web application ARchive) file, which can be deployed | |||
@@ -27,8 +27,6 @@ Java web application. There exists also other kinds of web applications. To | |||
avoid confusion with the general meaning of "web application", we often refer to | |||
Java web applications with the slight misnomer "WAR" in this book. | |||
// TODO Vaadin 7: What is the relationship between servlet and application? | |||
[[application.environment.war-eclipse]] | |||
== Creating Deployable WAR in Eclipse | |||
@@ -47,13 +45,13 @@ we give the instructions for Eclipse. | |||
The following files are required in a web application in order to run it. | |||
[filename]#WEB-INF/web.xml# (optional with Servlet 3.0):: | |||
his is the web application descriptor that defines how the application is rganized, that is, what servlets and such it has. | |||
his is the web application descriptor that defines how the application is organized, that is, what servlets and such it has. | |||
You can refer to any Java book about the contents of this file. | |||
It is not needed if you define the Vaadin servlet with the [classname]#@WebServlet# annotation in Servlet API 3.0. | |||
[filename]#WEB-INF/lib/*.jar# :: | |||
These are the Vaadin libraries and their dependencies. | |||
They can be found in the installation package or as loaded by a dependency management system such as Maven or Ivy. | |||
They can be found in the installation package or as loaded by a dependency management system such as Maven. | |||
Your UI classes:: | |||
You must include your UI classes either in a JAR file in [filename]#WEB-INF/lib# or as classes in [filename]#WEB-INF/classes# | |||
@@ -110,8 +108,7 @@ web fragments, or programmatically. You can use both a [filename]#web.xml# and | |||
WebServlet in the same application. Settings in the [filename]#web.xml# override | |||
the ones given in annotations. | |||
The following example shows the basic contents of a deployment descriptor for a | |||
Servlet 2.4 application. You simply specify the UI class with the | |||
The following example shows the basic contents of a deployment descriptor. You simply specify the UI class with the | |||
[parameter]#UI# parameter for the [classname]#com.vaadin.server.VaadinServlet#. | |||
The servlet is then mapped to a URL path in a standard way for Java Servlets. | |||
@@ -119,11 +116,11 @@ The servlet is then mapped to a URL path in a standard way for Java Servlets. | |||
---- | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<web-app | |||
id="WebApp_ID" version="2.4" | |||
id="WebApp_ID" version="**3.0**" | |||
xmlns="http://java.sun.com/xml/ns/j2ee" | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee | |||
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> | |||
xsi:schemaLocation="**http://java.sun.com/xml/ns/javaee | |||
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd**"> | |||
<servlet> | |||
<servlet-name>[replaceable]##myservlet##</servlet-name> | |||
@@ -155,23 +152,6 @@ Vaadin framework and is normally the same for all Vaadin projects. For some | |||
purposes, you may need to use a custom servlet class that extends the | |||
[classname]#VaadinServlet#. The class name must include the full package path. | |||
[[application.environment.web-xml.servlet]] | |||
=== Servlet API Version | |||
The descriptor example given above was for Servlet 2.4. For a later version, | |||
such as Servlet 3.0, you should use: | |||
[subs="normal"] | |||
---- | |||
<web-app | |||
id="WebApp_ID" version="**3.0**" | |||
xmlns="http://java.sun.com/xml/ns/j2ee" | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="**http://java.sun.com/xml/ns/javaee | |||
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd**"> | |||
---- | |||
Servlet 3.0 support is useful for at least server push. | |||
[[application.environment.web-xml.widgetset]] | |||
=== Widget Set | |||
@@ -188,15 +168,7 @@ class MyUI extends UI { | |||
... | |||
---- | |||
You can also define it in the [filename]#web.xml# descriptor for the servlet: | |||
[subs="normal"] | |||
---- | |||
<init-param> | |||
<param-name>widgetset</param-name> | |||
<param-value>[replaceable]##com.example.myproject.MyWidgetSet##</param-value> | |||
</init-param> | |||
---- | |||
You can also define it with the [parameter]#widgetset# init parameter for the servlet. | |||
The name of a widget set is technically a Java class name with the same path as the widget set definition file, but without the [filename]#.gwt.xml# extension. | |||
@@ -218,15 +190,7 @@ With [classname]#@WebServlet# annotation for the servlet class: | |||
---- | |||
@WebServlet(value = "**/++*++**", asyncSupported = true) | |||
---- | |||
In a [filename]#web.xml#: | |||
[subs="normal"] | |||
---- | |||
<servlet-mapping> | |||
<servlet-name>**myservlet**</servlet-name> | |||
<url-pattern>/*</url-pattern> | |||
</servlet-mapping> | |||
---- | |||
The URL pattern is defined in the above examples as [literal]#++/*++#. This | |||
matches any URL under the project context. We defined above the project context | |||
as [literal]#++myproject++# so the URL for the page of the UI will be | |||
@@ -252,21 +216,7 @@ multiple mappings as a list enclosed in curly braces as follows: | |||
@WebServlet(value = {"**/myui/++*++**", "/VAADIN/*"}, | |||
asyncSupported = true) | |||
---- | |||
In a [filename]#web.xml#: | |||
[subs="normal"] | |||
---- | |||
... | |||
<servlet-mapping> | |||
<servlet-name>**myservlet**</servlet-name> | |||
<url-pattern>**/myui/++*++**</url-pattern> | |||
</servlet-mapping> | |||
<servlet-mapping> | |||
<servlet-name>**myservlet**</servlet-name> | |||
<url-pattern>/VAADIN/*</url-pattern> | |||
</servlet-mapping> | |||
---- | |||
If you have multiple servlets, you should specify only one | |||
[literal]#++/VAADIN/*++# mapping.It does not matter which servlet you map the | |||
pattern to, as long as it is a Vaadin servlet. | |||
@@ -309,16 +259,7 @@ By default, Vaadin applications run in __debug mode__ (or __development mode__), | |||
which should be used during development. This enables various debugging | |||
features. For production use, you should have the | |||
[literal]#++productionMode=true++# setting in the | |||
[classname]#@VaadinServletConfiguration#, or in [filename]#web.xml#: | |||
---- | |||
<context-param> | |||
<param-name>productionMode</param-name> | |||
<param-value>true</param-value> | |||
<description>Vaadin production mode</description> | |||
</context-param> | |||
---- | |||
[classname]#@VaadinServletConfiguration#. | |||
The parameter and the debug and production modes are described in more detail in | |||
<<dummy/../../../framework/advanced/advanced-debug#advanced.debug,"Debug Mode | |||
@@ -333,17 +274,6 @@ Vaadin normally uses the [classname]#DefaultUIProvider# for creating | |||
can define its class with the [parameter]#UIProvider# parameter. The provider is | |||
registered in the [classname]#VaadinSession#. | |||
In a [filename]#web.xml#: | |||
[subs="normal"] | |||
---- | |||
<servlet> | |||
... | |||
<init-param> | |||
<param-name>UIProvider</param-name> | |||
<param-value>**com.ex.my.MyUIProvider**</param-value> | |||
</init-param> | |||
---- | |||
The parameter is logically associated with a particular servlet, but can be | |||
defined in the context as well. | |||
@@ -363,16 +293,6 @@ The interval of the heartbeat requests can be specified in seconds with the | |||
entire web application or an init parameter for the individual servlet. The | |||
default value is 300 seconds (5 minutes). | |||
In a [filename]#web.xml#: | |||
---- | |||
<context-param> | |||
<param-name>heartbeatInterval</param-name> | |||
<param-value>300</param-value> | |||
</context-param> | |||
---- | |||
[[application.environment.parameters.session-timeout]] | |||
=== Session Timeout After User Inactivity | |||
@@ -380,13 +300,10 @@ In a [filename]#web.xml#: | |||
In normal servlet operation, the session timeout defines the allowed time of | |||
inactivity after which the server should clean up the session. The inactivity is | |||
measured from the last server request. Different servlet containers use varying | |||
defaults for timeouts, such as 30 minutes for Apache Tomcat. You can set the | |||
timeout under [literal]#++<web-app>++# with: | |||
In a [filename]#web.xml#: | |||
defaults for timeouts, such as 30 minutes for Apache Tomcat. There is no way to | |||
programmatically set the global session timeout, but you can set it in the | |||
deployment descriptor with: | |||
((("session-timeout"))) | |||
---- | |||
<session-config> | |||
<session-timeout>30</session-timeout> | |||
@@ -405,21 +322,9 @@ However, having a shorter heartbeat interval than the session timeout, which is | |||
the normal case, prevents the sessions from expiring. If the | |||
[parameter]#closeIdleSessions# parameter for the servlet is enabled (disabled by | |||
default), Vaadin closes the UIs and the session after the time specified in the | |||
[parameter]#session-timeout# parameter expires after the last non-heartbeat | |||
[parameter]#session-timeout# init parameter expires after the last non-heartbeat | |||
request. | |||
In a [filename]#web.xml#: | |||
---- | |||
<servlet> | |||
... | |||
<init-param> | |||
<param-name>closeIdleSessions</param-name> | |||
<param-value>true</param-value> | |||
</init-param> | |||
---- | |||
[[application.environment.parameters.push]] | |||
=== Push Mode | |||
@@ -427,25 +332,12 @@ In a [filename]#web.xml#: | |||
You can enable server push, as described in | |||
<<dummy/../../../framework/advanced/advanced-push#advanced.push,"Server Push">>, | |||
for a UI either with a [classname]#@Push# annotation for the UI or in the | |||
descriptor. The push mode is defined with a [parameter]#pushmode# parameter. The | |||
descriptor. The push mode is defined with a [parameter]#pushmode# init parameter. The | |||
[literal]#++automatic++# mode pushes changes to the browser automatically after | |||
__access()__ finishes. With [literal]#++manual++# mode, you need to do the push | |||
explicitly with [methodname]#push()#. If you use a Servlet 3.0 compatible | |||
server, you also want to enable asynchronous processing with the | |||
[literal]#++async-supported++# parameter. | |||
explicitly with [methodname]#push()#. You can enable asynchronous processing with the | |||
[literal]#++async-supported++# init parameter. | |||
In a [filename]#web.xml#: | |||
[subs="normal"] | |||
---- | |||
<servlet> | |||
... | |||
<init-param> | |||
<param-name>pushmode</param-name> | |||
<param-value>**automatic**</param-value> | |||
</init-param> | |||
<async-supported>**true**</async-supported> | |||
---- | |||
[[application.environment.parameters.xsrf]] | |||
=== Cross-Site Request Forgery Prevention | |||
@@ -455,20 +347,9 @@ forgery (XSRF or CSRF), also called one-click attacks or session riding, which | |||
is a security exploit for executing unauthorized commands in a web server. This | |||
protection is normally enabled. However, it prevents some forms of testing of | |||
Vaadin applications, such as with JMeter. In such cases, you can disable the | |||
protection by setting the [parameter]#disable-xsrf-protection# parameter to | |||
protection by setting the [parameter]#disable-xsrf-protection# context parameter to | |||
[literal]#++true++#. | |||
In a [filename]#web.xml#: | |||
---- | |||
<context-param> | |||
<param-name>disable-xsrf-protection</param-name> | |||
<param-value>true</param-value> | |||
</context-param> | |||
---- | |||
[[application.environment.configuration]] | |||
== Deployment Configuration |
@@ -39,7 +39,6 @@ and tries to restore the connection. After several retries, an error message is | |||
You can customize the messages, timeouts, and the number of reconnect attempts in the [classname]#ReconnectDialogConfiguration# | |||
object, which you can access from your [classname]#UI# with [methodname]#getReconnectDialogConfiguration()#. | |||
ifdef::web[] | |||
[[application.errors.systemmessages]] | |||
== Customizing System Messages | |||
@@ -48,44 +47,10 @@ usually requires restarting the application. Session timeout is perhaps the most | |||
typical such state. | |||
System messages are strings managed in the [classname]#SystemMessages# class. | |||
sessionExpired:: ((("session", | |||
"expiration"))) | |||
((("session", | |||
"timeout"))) | |||
The Vaadin session expired. A session expires if no server requests are made | |||
during the session timeout period. The session timeout can be configured with | |||
the [parameter]#session-timeout# parameter in [filename]#web.xml#, as described | |||
in | |||
<<dummy/../../../framework/application/application-environment#application.environment.web-xml,"Using | |||
a web.xml Deployment Descriptor">>. | |||
communicationError:: An unspecified communication problem between the Vaadin Client-Side Engine and | |||
the application server. The server may be unavailable or there is some other | |||
problem. | |||
authenticationError:: This error occurs if 401 (Unauthorized) response to a request is received from | |||
the server. | |||
internalError:: A serious internal problem, possibly indicating a bug in Vaadin Client-Side | |||
Engine or in some custom client-side code. | |||
outOfSync:: The client-side state is invalid with respect to server-side state. | |||
cookiesDisabled:: Informs the user that cookies are disabled in the browser and the application | |||
does not work without them. | |||
Each message has four properties: a short caption, the actual message, a URL to | |||
which to redirect after displaying the message, and property indicating whether | |||
the notification is enabled. | |||
Additional details may be written (in English) to the debug console window | |||
described in | |||
<<dummy/../../../framework/advanced/advanced-debug#advanced.debug,"Debug Mode | |||
and Window">>. | |||
You can override the default system messages by setting the | |||
[interfacename]#SystemMessagesProvider# in the [classname]#VaadinService#. You | |||
need to implement the [methodname]#getSystemMessages()# method, which should | |||
@@ -120,9 +85,6 @@ See | |||
Servlet, Portlet, and Service">> for information about customizing Vaadin | |||
servlets. | |||
endif::web[] | |||
ifdef::web[] | |||
[[application.errors.unchecked-exceptions]] | |||
== Handling Uncaught Exceptions | |||
@@ -132,12 +94,8 @@ application. Any such exceptions are eventually caught by the framework. It | |||
delegates the exceptions to the [classname]#DefaultErrorHandler#, which displays | |||
the error as a component error, that is, with a small red "!" -sign (depending | |||
on the theme). If the user hovers the mouse pointer over it, the entire | |||
backtrace of the exception is shown in a large tooltip box, as illustrated in | |||
<<figure.application.errors.unchecked-exceptions>>. | |||
backtrace of the exception is shown in a large tooltip box. | |||
[[figure.application.errors.unchecked-exceptions]] | |||
.Uncaught Exception in Component Error Indicator | |||
image::img/errorindicator-exception.png[] | |||
You can customize the default error handling by implementing a custom | |||
[interfacename]#ErrorHandler# and enabling it with | |||
@@ -152,12 +110,8 @@ behavior of the default handler. | |||
---- | |||
// Here's some code that produces an uncaught exception | |||
final VerticalLayout layout = new VerticalLayout(); | |||
final Button button = new Button("Click Me!", | |||
new Button.ClickListener() { | |||
public void buttonClick(ClickEvent event) { | |||
((String)null).length(); // Null-pointer exception | |||
} | |||
}); | |||
final Button button = new Button("Click Me!", event -> | |||
((String)null).length()); // Null-pointer exception | |||
layout.addComponent(button); | |||
// Configure the error handler for the UI | |||
@@ -189,5 +143,3 @@ such as set the component error for the component where the exception was | |||
thrown. See the source code of the implementation for more details. You can call | |||
[methodname]#findAbstractComponent(event)# to find the component that caused the | |||
error. If the error is not associated with a component, it returns null. | |||
endif::web[] |
@@ -9,66 +9,7 @@ layout: page | |||
Let us put into practice what we learned of event handling in | |||
<<dummy/../../../framework/architecture/architecture-events#architecture.events,"Events | |||
and Listeners">>. You can implement listener interfaces in a regular class, but | |||
it brings the problem with differentiating between different event sources. | |||
Using anonymous class for listeners is recommended in most cases. | |||
[[application.events.anonymous]] | |||
== Using Anonymous Classes | |||
By far the easiest and the most common way to handle events in Java 8 lambdas. | |||
It encapsulates the handling of events to where | |||
the component is defined and does not require cumbering the managing class with | |||
interface implementations. The following example defines an anonymous class that | |||
inherits the [classname]#Button.ClickListener# interface. | |||
[source, java] | |||
---- | |||
// Have a component that fires click events | |||
final Button button = new Button("Click Me!"); | |||
// Handle the events with an anonymous class | |||
button.addClickListener(new Button.ClickListener() { | |||
public void buttonClick(ClickEvent event) { | |||
button.setCaption("You made me click!"); | |||
} | |||
}); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#application.eventlistener.anonymous[on-line example, window="_blank"]. | |||
Local objects referenced from within an anonymous class, such as the | |||
[classname]#Button# object in the above example, must be declared | |||
[literal]#++final++#. | |||
Most components allow passing a listener to the constructor, thereby losing a | |||
line or two. However, notice that if accessing the component that is constructed | |||
from an anonymous class, you must use a reference that is declared before the | |||
constructor is executed, for example as a member variable in the outer class. If | |||
it is declared in the same expression where the constructor is called, it | |||
doesn't yet exist. In such cases, you need to get a reference to the component | |||
from the event object. | |||
[source, java] | |||
---- | |||
final Button button = new Button("Click It!", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
event.getButton().setCaption("Done!"); | |||
} | |||
}); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#application.eventlistener.constructor[on-line example, window="_blank"]. | |||
[[application.events.java8]] | |||
== Handling Events in Java 8 | |||
Java 8 introduced lambda expressions, which offer a replacement for listeners. | |||
You can directly use lambda expressions in place of listeners that have only one | |||
method to implement. | |||
and Listeners">>. You can implement listener interfaces by directly using lambda expressions, method references or anonymous classes. | |||
For example, in the following, we use a lambda expression to handle button click | |||
events in the constructor: | |||
@@ -79,113 +20,62 @@ events in the constructor: | |||
layout.addComponent(new Button("Click Me!", | |||
event -> event.getButton().setCaption("You made click!"))); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#application.eventlistener.java8[on-line example, window="_blank"]. | |||
Java 8 is the future that is already here, and as Vaadin API uses event | |||
listeners extensively, using lambda expressions makes UI code much more | |||
readable. | |||
Directing events to handler methods is easy with method references: | |||
[source, java] | |||
---- | |||
public class Java8Buttons extends CustomComponent { | |||
public Java8Buttons() { | |||
public class Buttons extends CustomComponent { | |||
public Buttons() { | |||
setCompositionRoot(new HorizontalLayout( | |||
new Button("OK", this::ok), | |||
new Button("Cancel", this::cancel))); | |||
} | |||
public void ok(ClickEvent event) { | |||
private void ok(ClickEvent event) { | |||
event.getButton().setCaption ("OK!"); | |||
} | |||
public void cancel(ClickEvent event) { | |||
private void cancel(ClickEvent event) { | |||
event.getButton().setCaption ("Not OK!"); | |||
} | |||
} | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#application.eventlistener.java8differentiation[on-line example, window="_blank"]. | |||
[[application.events.classlistener]] | |||
== Implementing a Listener in a Regular Class | |||
[[application.events.anonymous]] | |||
== Using Anonymous Classes | |||
The following example follows a typical pattern where you have a | |||
[classname]#Button# component and a listener that handles user interaction | |||
(clicks) communicated to the application as events. Here we define a class that | |||
listens to click events. | |||
The following example defines an anonymous class that inherits the [classname]#Button.ClickListener# interface. | |||
[source, java] | |||
---- | |||
public class MyComposite extends CustomComponent | |||
implements Button.ClickListener { | |||
Button button; // Defined here for access | |||
public MyComposite() { | |||
Layout layout = new HorizontalLayout(); | |||
// Just a single component in this composition | |||
button = new Button("Do not push this"); | |||
button.addClickListener(this); | |||
layout.addComponent(button); | |||
setCompositionRoot(layout); | |||
} | |||
// Have a component that fires click events | |||
Button button = new Button("Click Me!"); | |||
// The listener method implementation | |||
// Handle the events with an anonymous class | |||
button.addClickListener(new Button.ClickListener() { | |||
public void buttonClick(ClickEvent event) { | |||
button.setCaption("Do not push this again"); | |||
button.setCaption("You made me click!"); | |||
} | |||
} | |||
}); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#application.eventlistener.classlistener[on-line example, window="_blank"]. | |||
[[application.events.differentiation]] | |||
== Differentiating Between Event Sources | |||
If an application receives events of the same type from multiple sources, such | |||
as multiple buttons, it has to be able to distinguish between the sources. If | |||
using a regular class listener, distinguishing between the components can be | |||
done by comparing the source of the event with each of the components. The | |||
method for identifying the source depends on the event type. | |||
Most components allow passing a listener to the constructor. | |||
Note that to be able to access the component from the anonymous listener class, | |||
you must have a reference to the component that is declared before the | |||
constructor is executed, for example as a member variable in the outer class. | |||
You can also to get a reference to the component from the event object: | |||
[source, java] | |||
---- | |||
public class TheButtons extends CustomComponent | |||
implements Button.ClickListener { | |||
Button onebutton; | |||
Button toobutton; | |||
public TheButtons() { | |||
onebutton = new Button("Button One", this); | |||
toobutton = new Button("A Button Too", this); | |||
// Put them in some layout | |||
Layout root = new HorizontalLayout(); | |||
root.addComponent(onebutton); | |||
root.addComponent(toobutton); | |||
setCompositionRoot(root); | |||
} | |||
final Button button = new Button("Click It!", | |||
new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
// Differentiate targets by event source | |||
if (event.getButton() == onebutton) | |||
onebutton.setCaption ("Pushed one"); | |||
else if (event.getButton() == toobutton) | |||
toobutton.setCaption ("Pushed too"); | |||
event.getButton().setCaption("Done!"); | |||
} | |||
} | |||
}); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#application.eventlistener.differentiation[on-line example, window="_blank"]. | |||
Other techniques exist for separating between event sources, such as using | |||
object properties, names, or captions to separate between them. Using captions | |||
or any other visible text is generally discouraged, as it may create problems | |||
for internationalization. Using other symbolic strings can also be dangerous, | |||
because the syntax of such strings is checked only at runtime. |
@@ -94,7 +94,6 @@ public class MyServlet extends VaadinServlet { | |||
protected void servletInitialized() | |||
throws ServletException { | |||
super.servletInitialized(); | |||
... | |||
} | |||
} | |||
@@ -104,7 +103,6 @@ To add custom functionality around request handling, you can override the | |||
[methodname]#service()# method. | |||
ifdef::web[] | |||
[[application.lifecycle.servlet-service.servicecustomization]] | |||
=== Customizing Vaadin Service | |||
@@ -112,8 +110,6 @@ To customize [classname]#VaadinService#, you first need to extend the | |||
[classname]#VaadinServlet# or - [classname]#Portlet# class and override the | |||
[methodname]#createServletService()# to create a custom service object. | |||
endif::web[] | |||
[[application.lifecycle.session]] | |||
== User Session | |||
@@ -346,15 +342,10 @@ when the timeout specified by the [parameter]#session-timeout# parameter of the | |||
servlet expires after the last non-heartbeat request. Once the session is gone, | |||
the browser will show an Out Of Sync error on the next server request. | |||
((("redirection"))) | |||
To avoid the ugly message, you may want to set a redirect URL for the UIs | |||
ifdef::web[] | |||
, as described in | |||
To avoid the ugly message, you may want to set a redirect URL for the UIs, as described in | |||
<<dummy/../../../framework/application/application-errors#application.errors.systemmessages,"Customizing | |||
System | |||
Messages">> | |||
endif::web[] | |||
. | |||
Messages">>. | |||
The related configuration parameters are described in | |||
<<dummy/../../../framework/application/application-environment#application.environment.parameters,"Other | |||
@@ -395,7 +386,7 @@ logout button, which closes the user session. | |||
public class MyUI extends UI { | |||
@Override | |||
protected void init(VaadinRequest request) { | |||
setContent(new Button("Logout", event -> {// Java 8 | |||
setContent(new Button("Logout", event -> { | |||
// Redirect this page immediately | |||
getPage().setLocation("/myapp/logout.html"); | |||
@@ -408,7 +399,6 @@ public class MyUI extends UI { | |||
} | |||
} | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#application.lifecycle.closing[on-line example, window="_blank"]. | |||
This is not enough. When a session is closed from one UI, any other UIs attached | |||
to it are left hanging. When the client-side engine notices that a UI and the | |||
@@ -419,9 +409,7 @@ and, by default, reloads the UI when the message is clicked. | |||
((("system messages"))) | |||
You can customize the message and the redirect URL in the system messages. | |||
ifdef::web[] | |||
It is described in <<dummy/../../../framework/application/application-errors#application.errors.systemmessages,"Customizing System Messages">>. | |||
endif::web[] | |||
((("heartbeat"))) | |||
((("UI", "heartbeat"))) | |||
@@ -441,7 +429,7 @@ synchronized as described in | |||
public class MyPushyUI extends UI { | |||
@Override | |||
protected void init(VaadinRequest request) { | |||
setContent(new Button("Logout", event -> {// Java 8 | |||
setContent(new Button("Logout", event -> { | |||
for (UI ui: VaadinSession.getCurrent().getUIs()) | |||
ui.access(() -> { | |||
// Redirect from the page | |||
@@ -453,7 +441,6 @@ public class MyPushyUI extends UI { | |||
} | |||
} | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#application.lifecycle.closingall[on-line example, window="_blank"]. | |||
In the above example, we assume that all UIs in the session have push enabled | |||
and that they should be redirected; popups you might want to close instead of |
@@ -102,7 +102,6 @@ seconds by default. The user can continue to interact with the application | |||
normally while the tray notification is displayed. | |||
ifdef::web[] | |||
[[application.notifications.customization]] | |||
== Customizing Notifications | |||
@@ -140,7 +139,6 @@ also prevents interaction with other parts of the application window, which is | |||
the default behaviour for error notifications. It does not, however, add a close | |||
box that the error notification has. | |||
endif::web[] | |||
[[application.notifications.css]] | |||
== Styling with CSS |
@@ -10,12 +10,11 @@ layout: page | |||
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. Flash animations can be displayed with | |||
[classname]#Flash#, embedded browser frames with [classname]#BrowserFrame#, and | |||
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#. | |||
[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 | |||
@@ -85,15 +84,8 @@ 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); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#application.resources.fileresource[on-line example, window="_blank"]. | |||
The result, as well as the folder structure where the file is stored under a | |||
regular Eclipse Vaadin project, is shown in | |||
<<figure.application.resources.file>>. | |||
[[figure.application.resources.file]] | |||
.File Resource | |||
image::img/resource-fileresource.png[width=50%, scaledwidth=80%] | |||
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]] | |||
@@ -114,7 +106,6 @@ and displays it in an [classname]#Image# component. | |||
layout.addComponent(new Image(null, | |||
new ClassResource("smiley.jpg"))); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#application.resources.classresource[on-line example, window="_blank"]. | |||
[[application.resources.theme]] | |||
@@ -136,14 +127,6 @@ ThemeResource resource = new ThemeResource("img/themeimage.png"); | |||
// Use the resource | |||
Image image = new Image("My Theme Image", resource); | |||
---- | |||
See the http://demo.vaadin.com/book-examples-vaadin7/book#application.resources.themeresource[on-line example, window="_blank"]. | |||
The result is shown in <<figure.application.resources.theme>>, also illustrating | |||
the folder structure for the theme resource file in an Eclipse project. | |||
[[figure.application.resources.theme]] | |||
.Theme Resources | |||
image::img/resource-themeimage.png[width=40%, scaledwidth=70%] | |||
To use theme resources, you must set the theme for the UI. See | |||
<<dummy/../../../framework/themes/themes-overview.asciidoc#themes.overview,"Themes">> |