You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

application-events.asciidoc 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. ---
  2. title: Handling Events with Listeners
  3. order: 4
  4. layout: page
  5. ---
  6. [[application.events]]
  7. = Handling Events with Listeners
  8. Let us put into practice what we learned of event handling in
  9. <<dummy/../../../framework/architecture/architecture-events#architecture.events,"Events
  10. and Listeners">>. You can implement listener interfaces in a regular class, but
  11. it brings the problem with differentiating between different event sources.
  12. Using anonymous class for listeners is recommended in most cases.
  13. [[application.events.anonymous]]
  14. == Using Anonymous Classes
  15. By far the easiest and the most common way to handle events in Java 6 and 7 is
  16. to use anonymous local classes. It encapsulates the handling of events to where
  17. the component is defined and does not require cumbering the managing class with
  18. interface implementations. The following example defines an anonymous class that
  19. inherits the [classname]#Button.ClickListener# interface.
  20. [source, java]
  21. ----
  22. // Have a component that fires click events
  23. final Button button = new Button("Click Me!");
  24. // Handle the events with an anonymous class
  25. button.addClickListener(new Button.ClickListener() {
  26. public void buttonClick(ClickEvent event) {
  27. button.setCaption("You made me click!");
  28. }
  29. });
  30. ----
  31. See the http://demo.vaadin.com/book-examples-vaadin7/book#application.eventlistener.anonymous[on-line example, window="_blank"].
  32. Local objects referenced from within an anonymous class, such as the
  33. [classname]#Button# object in the above example, must be declared
  34. [literal]#++final++#.
  35. Most components allow passing a listener to the constructor, thereby losing a
  36. line or two. However, notice that if accessing the component that is constructed
  37. from an anonymous class, you must use a reference that is declared before the
  38. constructor is executed, for example as a member variable in the outer class. If
  39. it is declared in the same expression where the constructor is called, it
  40. doesn't yet exist. In such cases, you need to get a reference to the component
  41. from the event object.
  42. [source, java]
  43. ----
  44. final Button button = new Button("Click It!",
  45. new Button.ClickListener() {
  46. @Override
  47. public void buttonClick(ClickEvent event) {
  48. event.getButton().setCaption("Done!");
  49. }
  50. });
  51. ----
  52. See the http://demo.vaadin.com/book-examples-vaadin7/book#application.eventlistener.constructor[on-line example, window="_blank"].
  53. [[application.events.java8]]
  54. == Handling Events in Java 8
  55. Java 8 introduced lambda expressions, which offer a replacement for listeners.
  56. You can directly use lambda expressions in place of listeners that have only one
  57. method to implement.
  58. For example, in the following, we use a lambda expression to handle button click
  59. events in the constructor:
  60. [source, java]
  61. ----
  62. layout.addComponent(new Button("Click Me!",
  63. event -> event.getButton().setCaption("You made click!")));
  64. ----
  65. See the http://demo.vaadin.com/book-examples-vaadin7/book#application.eventlistener.java8[on-line example, window="_blank"].
  66. Java 8 is the future that is already here, and as Vaadin API uses event
  67. listeners extensively, using lambda expressions makes UI code much more
  68. readable.
  69. Directing events to handler methods is easy with method references:
  70. [source, java]
  71. ----
  72. public class Java8Buttons extends CustomComponent {
  73. public Java8Buttons() {
  74. setCompositionRoot(new HorizontalLayout(
  75. new Button("OK", this::ok),
  76. new Button("Cancel", this::cancel)));
  77. }
  78. public void ok(ClickEvent event) {
  79. event.getButton().setCaption ("OK!");
  80. }
  81. public void cancel(ClickEvent event) {
  82. event.getButton().setCaption ("Not OK!");
  83. }
  84. }
  85. ----
  86. See the http://demo.vaadin.com/book-examples-vaadin7/book#application.eventlistener.java8differentiation[on-line example, window="_blank"].
  87. [[application.events.classlistener]]
  88. == Implementing a Listener in a Regular Class
  89. The following example follows a typical pattern where you have a
  90. [classname]#Button# component and a listener that handles user interaction
  91. (clicks) communicated to the application as events. Here we define a class that
  92. listens to click events.
  93. [source, java]
  94. ----
  95. public class MyComposite extends CustomComponent
  96. implements Button.ClickListener {
  97. Button button; // Defined here for access
  98. public MyComposite() {
  99. Layout layout = new HorizontalLayout();
  100. // Just a single component in this composition
  101. button = new Button("Do not push this");
  102. button.addClickListener(this);
  103. layout.addComponent(button);
  104. setCompositionRoot(layout);
  105. }
  106. // The listener method implementation
  107. public void buttonClick(ClickEvent event) {
  108. button.setCaption("Do not push this again");
  109. }
  110. }
  111. ----
  112. See the http://demo.vaadin.com/book-examples-vaadin7/book#application.eventlistener.classlistener[on-line example, window="_blank"].
  113. [[application.events.differentiation]]
  114. == Differentiating Between Event Sources
  115. If an application receives events of the same type from multiple sources, such
  116. as multiple buttons, it has to be able to distinguish between the sources. If
  117. using a regular class listener, distinguishing between the components can be
  118. done by comparing the source of the event with each of the components. The
  119. method for identifying the source depends on the event type.
  120. [source, java]
  121. ----
  122. public class TheButtons extends CustomComponent
  123. implements Button.ClickListener {
  124. Button onebutton;
  125. Button toobutton;
  126. public TheButtons() {
  127. onebutton = new Button("Button One", this);
  128. toobutton = new Button("A Button Too", this);
  129. // Put them in some layout
  130. Layout root = new HorizontalLayout();
  131. root.addComponent(onebutton);
  132. root.addComponent(toobutton);
  133. setCompositionRoot(root);
  134. }
  135. @Override
  136. public void buttonClick(ClickEvent event) {
  137. // Differentiate targets by event source
  138. if (event.getButton() == onebutton)
  139. onebutton.setCaption ("Pushed one");
  140. else if (event.getButton() == toobutton)
  141. toobutton.setCaption ("Pushed too");
  142. }
  143. }
  144. ----
  145. See the http://demo.vaadin.com/book-examples-vaadin7/book#application.eventlistener.differentiation[on-line example, window="_blank"].
  146. Other techniques exist for separating between event sources, such as using
  147. object properties, names, or captions to separate between them. Using captions
  148. or any other visible text is generally discouraged, as it may create problems
  149. for internationalization. Using other symbolic strings can also be dangerous,
  150. because the syntax of such strings is checked only at runtime.