diff options
author | Markus Koivisto <markus@vaadin.com> | 2016-01-22 14:55:18 +0200 |
---|---|---|
committer | Markus Koivisto <markus@vaadin.com> | 2016-01-22 14:55:18 +0200 |
commit | 99d6de546c74f0eed230ea8253dda6b85109d2e7 (patch) | |
tree | 10fc21c557566fe3241e6e13499df18d80f8dcb2 /documentation/application/application-events.asciidoc | |
parent | 610736d9f373d4b37fd39ff8f90aabd13eab7926 (diff) | |
download | vaadin-framework-99d6de546c74f0eed230ea8253dda6b85109d2e7.tar.gz vaadin-framework-99d6de546c74f0eed230ea8253dda6b85109d2e7.zip |
Add documentation to master branch
Change-Id: I2504bb10f1ae73ec0cbc08b7ba5a88925caa1674
Diffstat (limited to 'documentation/application/application-events.asciidoc')
-rw-r--r-- | documentation/application/application-events.asciidoc | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/documentation/application/application-events.asciidoc b/documentation/application/application-events.asciidoc new file mode 100644 index 0000000000..94175d88e7 --- /dev/null +++ b/documentation/application/application-events.asciidoc @@ -0,0 +1,195 @@ +--- +title: Handling Events with Listeners +order: 4 +layout: page +--- + +[[application.events]] += Handling Events with Listeners + +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 6 and 7 is +to use anonymous local classes. 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. + +For example, in the following, we use a lambda expression to handle button click +events in the constructor: + + +[source, java] +---- +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() { + setCompositionRoot(new HorizontalLayout( + new Button("OK", this::ok), + new Button("Cancel", this::cancel))); + } + + public void ok(ClickEvent event) { + event.getButton().setCaption ("OK!"); + } + + public 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 + +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. + + +[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); + } + + // The listener method implementation + public void buttonClick(ClickEvent event) { + button.setCaption("Do not push this again"); + } +} +---- +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. + + +[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); + } + + @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"); + } +} +---- +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. + + + + |