Event Listening"

From Documentation
m ((via JWB))
 
(29 intermediate revisions by 7 users not shown)
Line 1: Line 1:
 
{{ZKDevelopersReferencePageHeader}}
 
{{ZKDevelopersReferencePageHeader}}
  
There are two ways to listen an event: an event handler and an event listener.
 
  
= Listen by use of an Event Handler =
 
 
An event handler is a method specified as an event attribute of a ZK page or as a member of a component class.
 
 
== Declare an Event Handler in ZUML ==
 
An event handler can be declared in a ZUL page by specifying an event attribute<ref>An event attribute is an attribute starting with <tt>on</tt></ref>. For example,
 
 
<source lang="xml">
 
<button label="hi" onClick='alert("Hello")'/>
 
</source>
 
 
where the content of the event handler is the code snippet in Java. The event handler will be interpreted at the run time (by use of BeanShell). If you prefer to use other language, you could specify the language name in front of it. For example, the following uses Groovy as the interpreter:
 
 
<source lang="xml">
 
<button label="hi" onClick="groovy:alert('Hi, Groovy')"/>
 
</source>
 
 
Important Builtin Variables
 
* self - the component receiving the event. In the previous example, it is the button itself.
 
* event - the event being received. In the previous example, it is an instance of <javadoc>org.zkoss.zk.ui.event.MouseEvent</javadoc>.
 
 
Notice that the event handler declared in this way is interpreted at the run time, so it inherits all advantages and disadvantage of interpreter-based execution.
 
 
Advantange:
 
 
* It can be changed on the fly without recompiling and reloading the application.
 
* Easy to maintain if the code snippet is small.
 
 
Disadvantage:
 
 
* Slower to run.
 
* Compilation error can not be known in advance.
 
* Hard to maintain if mixing business logic with user interface.
 
 
Suggestion:
 
 
* It is generally suggested to use this approach for 1) prototyping, or 2) simple event handling.
 
 
== Declare an Event Handler in Java ==
 
The other way to have an event listener is to declare it as a member of a component class. For example,
 
 
<source lang="java">
 
public class MyButton extends Button {
 
    public void onClick() {
 
        Messagebox.show("Hello");
 
    }
 
}
 
</source>
 
 
If the event handler needs to handle the event, it can declare the event as the argument as follows.
 
 
<source lang="java">
 
public class MyButton extends Button {
 
    public void onClick(MouseEvent event) {
 
        Messagebox.show("Hello, "+event.getName());
 
    }
 
}
 
</source>
 
 
Suggestions:
 
 
* It is suggested to use this approach for component development, since it is subtle for application developers to notice its existence. In additions, it requires to extend the component class.
 
 
<blockquote>
 
----
 
<references/>
 
</blockquote>
 
  
 
= Listen by Use of an Event Listener =
 
= Listen by Use of an Event Listener =
Line 80: Line 12:
 
public class MyListener implements EventListener {
 
public class MyListener implements EventListener {
 
     public void onEvent(Event event) {
 
     public void onEvent(Event event) {
         Messages.show("Hello");
+
         Messagebox.show("Hello");
 
     }
 
     }
 
}
 
}
 
</source>
 
</source>
  
Then, you can register an event listener to the component that might receive the event by use of <javadoc method="addEventListener(java.lang.String, org.zkoss.zk.ui.event.EventListener)">org.zkoss.zk.ui.Component</javadoc>. For example,
+
Then, you can register an event listener to the component that might receive the event by the use of <javadoc method="addEventListener(java.lang.String, org.zkoss.zk.ui.event.EventListener)">org.zkoss.zk.ui.Component</javadoc>. For example,
  
 
<source lang="java">
 
<source lang="java">
Line 95: Line 27:
 
== Composer and Event Listener Autowiring ==
 
== Composer and Event Listener Autowiring ==
  
With [[ZK Developer's Reference/MVC]], you generally don't need to register event listeners manually. Rather, they could be registered automatically by use of the [[ZK Developer's Reference/MVC/Controller/Wire Event Listeners|auto-wiring]] feature of [[ZK Developer's Reference/MVC/Controller|a composer]]. For example,
+
With [[ZK Developer's Reference/MVC]], you generally do not need to register event listeners manually. Rather, they can be registered automatically by the use of the [[ZK Developer's Reference/MVC/Controller/Wire Event Listeners|auto-wiring]] feature of [[ZK Developer's Reference/MVC/Controller|a composer]]. For example,
  
 
<source lang="java">
 
<source lang="java">
public class MyComposer extends GenericForwardComposer {
+
public class MyComposer extends SelectorComposer {
     public void onClick$hi() {
+
    @Listen("onClick = button#hi")
 +
     public void showHi() {
 
         Messsagebox.show("Hello");
 
         Messsagebox.show("Hello");
 
     }
 
     }
     public void onClick$bye() {
+
    @Listen("onClick = button#bye")
 +
     public void showBye() {
 
         Messsagebox.show("Bye");
 
         Messsagebox.show("Bye");
 
     }
 
     }
 +
    @Listen("onOK = window#mywin")
 
     public void onOK() {
 
     public void onOK() {
 
         Messsagebox.show("OK pressed");
 
         Messsagebox.show("OK pressed");
Line 111: Line 46:
 
</source>
 
</source>
  
As shown above, the method for lsitening an event shall be named by starting with the event name, separating with <tt>$</tt>, and ending with the component's ID. The composer will search all matched methods and register the event listener automatically. Then, in the ZUL page, you can specify the <tt>apply</tt> attribute to associate the composer with a component.
+
As shown above, the method to listen is annotated with the <javadoc>org.zkoss.zk.ui.select.annotation.Listen</javadoc> annotation using the event name followed by a selector string identifying the component(s) (for more selector syntax examples see <javadoc>org.zkoss.zk.ui.select.SelectorComposer</javadoc>). The composer will register each annotated method as an event listener to the selected component automatically '''in the same [[ZK%20Developer's%20Reference/UI%20Composing/ID%20Space | ID space]]'''. Then, in the ZUL page, you can specify the <code>apply</code> attribute to associate the composer with a component.
  
 
<source lang="xml">
 
<source lang="xml">
<window apply="MyComposer">
+
<window id="mywin" apply="MyComposer">
 
     <textbox/>
 
     <textbox/>
 
     <button id="hi"/>
 
     <button id="hi"/>
Line 124: Line 59:
  
 
<source lang="java">
 
<source lang="java">
     public void onClick$hi(MouseEvent event) {
+
    @Listen("onClick = button#hi")
 +
     public void showHi(MouseEvent event) {
 
       Messsagebox.show("Hello, " + event.getName());
 
       Messsagebox.show("Hello, " + event.getName());
 
     }
 
     }
Line 135: Line 71:
 
== Deferrable Event Listeners ==
 
== Deferrable Event Listeners ==
  
By default, events are sent to the server when it is fired at the client. However, many event listeners are just used to maintain the status at the server, rather than providing visual response to the user. In other words, the events for these listeners have no need to be sent immediately. Rather, they shall be sent at once to minimize the traffic between the client and the server, and then to improve the server's performance. For the sake of the description convenience, we call them the deferrable event listeners.
+
By default, events are sent to the server when it is fired at the client. However, many event listeners are just used to maintain the status on the server, rather than providing visual response to the user. In other words, there is no need to send the events for these listeners immediately. Rather, they shall be sent at once at a time to minimize the traffic between the client and the server so as to improve the server's performance. For the sake of the convenience, we call them the deferrable event listeners.
  
To make an event listener deferrable, you have to implement the <tt>org.zkoss.zk.ui.event.Deferrable</tt> interface (with <tt>EventListener</tt>) and return true for the <tt>isDeferrable</tt> method as follows.
+
To make an event listener deferrable, you have to implement <javadoc type="interface">org.zkoss.zk.ui.event.Deferrable</javadoc> (with <code>EventListener</code>) and return true for the <code>isDeferrable</code> method as follows.
  
 
<source lang="java" >
 
<source lang="java" >
Line 153: Line 89:
 
When an event is fired at the client (e.g., the user selects a list item), ZK won't send the event if no event listener is registered for it or only deferrable listeners are registered. instead, the event is queued at the client.
 
When an event is fired at the client (e.g., the user selects a list item), ZK won't send the event if no event listener is registered for it or only deferrable listeners are registered. instead, the event is queued at the client.
  
On the hand, if at least one non-deferrable listener is registered, the event are sent immediately with all queued events to the server at once. No event is lost and the arriving order is preserved.
+
On the other hand, if at least one non-deferrable listener is registered, the event will be sent immediately with all queued events to the server at once. No event is lost and the arriving order is preserved.
  
 
<blockquote>
 
<blockquote>
Line 159: Line 95:
 
'''Tip''': Use the deferrable listeners for maintaining the server status, while the non-deferrable listeners for providing the visual responses for the user.
 
'''Tip''': Use the deferrable listeners for maintaining the server status, while the non-deferrable listeners for providing the visual responses for the user.
 
</blockquote>
 
</blockquote>
 +
 +
== Page-level Event Listener ==
 +
Developers could add event listeners to a page (<javadoc type="interface">org.zkoss.zk.ui.Page</javadoc>) dynamically by <javadoc type="interface" method="addEventListener(java.lang.String, org.zkoss.zk.ui.event.EventListener)">org.zkoss.zk.ui.Page</javadoc>. Once added, all events of the specified name sent to any components of the specified page will be sent to the listener.
 +
 +
All event listeners added to a page (so-called page-level event listeners) are assumed to be deferrable, no matter if <javadoc type="interface">org.zkoss.zk.ui.event.Deferrable</javadoc> is implemented or not.
 +
 +
A typical example is to use a page-level event listener to maintain the modification flag as follows (pseudo code).
 +
 +
<source lang="java">
 +
page.addEventListener("onChange", new EventListener() {
 +
    public void onEvent(Event event) {
 +
        modified = true;
 +
    }
 +
});
 +
</source>
 +
 +
 +
= Listen by the use of an Event Handler =
 +
 +
An event handler is a method specified as an event attribute of a ZK page or as a member of a component class.
 +
 +
== Declare an Event Handler in ZUML ==
 +
An event handler can be declared in a ZUL page by specifying an event attribute<ref>An event attribute is an attribute starting with <code>on</code></ref>. For example,
 +
 +
<source lang="xml">
 +
<button label="hi" onClick='alert("Hello")'/>
 +
</source>
 +
 +
where the content of the event handler is the code snippet in Java. The event handler will be interpreted at the run time (by use of BeanShell). If you prefer to use other language, you could specify the language name in front of it. For example, the following uses Groovy as the interpreter:
 +
 +
<source lang="xml">
 +
<button label="hi" onClick="groovy:alert('Hi, Groovy')"/>
 +
</source>
 +
 +
Important Builtin Variables
 +
* self - the component receiving the event. In the previous example, it is the button itself.
 +
* event - the event being received. In the previous example, it is an instance of <javadoc>org.zkoss.zk.ui.event.MouseEvent</javadoc>.
 +
 +
Notice that the event handler declared in this way is interpreted at the run time, so it inherits all advantages and disadvantage of interpreter-based execution.
 +
 +
Advantange:
 +
 +
* It can be changed on the fly without recompiling and reloading the application.
 +
* Easy to maintain if the code snippet is small.
 +
 +
Disadvantage:
 +
 +
* Slower to run.
 +
* Compilation error can not be known in advance.
 +
* Hard to maintain if mixing business logic with user interface.
 +
 +
Suggestion:
 +
 +
* It is generally suggested to use this approach for 1) prototyping, or 2) simple event handling.
 +
 +
== Declare an Event Handler in Java ==
 +
The other way to have an event handler is to declare it as a member of a component class. For example,
 +
 +
<source lang="java">
 +
public class MyButton extends Button {
 +
    public void onClick() {
 +
        Messagebox.show("Hello");
 +
    }
 +
}
 +
</source>
 +
 +
If the event handler needs to handle the event, it can declare the event as the argument as follows.
 +
 +
<source lang="java">
 +
public class MyButton extends Button {
 +
    public void onClick(MouseEvent event) {
 +
        Messagebox.show("Hello, "+event.getName());
 +
    }
 +
}
 +
</source>
 +
 +
Suggestions:
 +
 +
* It is suggested to use this approach for component development, since it is subtle for application developers to notice its existence. In addition, it requires to extend the component class.
 +
 +
<blockquote>
 +
----
 +
<references/>
 +
</blockquote>
 +
  
 
=Precedence of Listeners=
 
=Precedence of Listeners=
  
The precedence of listeners highest to lowest is as follows.
+
The order of precedence for listeners from the highest to the lowest is as follows.
  
* Event listeners implemented with <javadoc type="interface">org.zkoss.zk.ui.event.Express</javadoc>, and registered by <javadoc type="interface" method="addEventListener(java.lang.String, org.zkoss.zk.ui.event.EventListener)">org.zkoss.zk.ui.Component</javadoc>
+
# Event listeners implemented with <javadoc type="interface">org.zkoss.zk.ui.event.Express</javadoc>, and registered by <javadoc type="interface" method="addEventListener(java.lang.String, org.zkoss.zk.ui.event.EventListener)">org.zkoss.zk.ui.Component</javadoc>
* Event handlers defined in a ZUML document
+
# Event handlers defined in a ZUML document
* Event listeners registered by <javadoc type="interface" method="addEventListener(java.lang.String, org.zkoss.zk.ui.event.EventListener)">org.zkoss.zk.ui.Component</javadoc> (and without <javadoc type="interface">org.zkoss.zk.ui.event.Express</javadoc>)
+
# Event listeners registered by <javadoc type="interface" method="addEventListener(java.lang.String, org.zkoss.zk.ui.event.EventListener)">org.zkoss.zk.ui.Component</javadoc> (and without <javadoc type="interface">org.zkoss.zk.ui.event.Express</javadoc>)
** It includes the method of a composer wired by <javadoc>org.zkoss.zk.ui.util.GenericForwardComposer</javadoc> because the event listener is used.
+
#* It includes the method of a composer wired by <javadoc>org.zkoss.zk.ui.util.GenericForwardComposer</javadoc> because the event listener is used.
* Event handlers defined as a class's method
+
# Event handlers defined as a class's method
* Event listeners registered to a page by <javadoc type="interface" method="addEventListener(java.lang.String, org.zkoss.zk.ui.event.EventListener)">org.zkoss.zk.ui.Page</javadoc>
+
# Event listeners registered to a page by <javadoc type="interface" method="addEventListener(java.lang.String, org.zkoss.zk.ui.event.EventListener)">org.zkoss.zk.ui.Page</javadoc>
  
 
== Abort the Invocation Sequence ==
 
== Abort the Invocation Sequence ==
You could abort the calling sequence by calling <javadoc method="stopPropagation()">org.zkoss.zk.ui.event.Event</javadoc>. Once one of the event listeners invokes this method, all following event handlers and listeners are ignored.
+
You could abort the calling sequence by calling <javadoc method="stopPropagation()">org.zkoss.zk.ui.event.Event</javadoc>. Once one of the event listeners invokes this method, all the following event handlers and listeners are ignored.
  
 
=Version History=
 
=Version History=
  
{| border='1px' | width="100%"
+
{| class='wikitable' | width="100%"
 
! Version !! Date !! Content
 
! Version !! Date !! Content
 
|-
 
|-
 
| 5.0.6
 
| 5.0.6
 
| November 2010
 
| November 2010
| <javadoc type="interface">org.zkoss.zk.ui.event.SerializableEventListener</javadoc> was introduced to simply the instantiation of a serializable anonymous class
+
| <javadoc type="interface">org.zkoss.zk.ui.event.SerializableEventListener</javadoc> was introduced to simplify the instantiation of a serializable anonymous class
 
|}
 
|}
  
 
{{ZKDevelopersReferencePageFooter}}
 
{{ZKDevelopersReferencePageFooter}}

Latest revision as of 14:11, 12 January 2022


Listen by Use of an Event Listener

Event Listener

An event listener is a class implementing EventListener. For example,

public class MyListener implements EventListener {
    public void onEvent(Event event) {
        Messagebox.show("Hello");
    }
}

Then, you can register an event listener to the component that might receive the event by the use of Component.addEventListener(String, EventListener). For example,

button.addEventListener("onClick", new MyListener());

This is a typical approach to handle events. However, it is a bit tedious to register event listeners one-by-one if there are a lot of listeners. Rather, it is suggested to use a composer as described in the following section.

Composer and Event Listener Autowiring

With ZK Developer's Reference/MVC, you generally do not need to register event listeners manually. Rather, they can be registered automatically by the use of the auto-wiring feature of a composer. For example,

public class MyComposer extends SelectorComposer {
    @Listen("onClick = button#hi")
    public void showHi() {
        Messsagebox.show("Hello");
    }
    @Listen("onClick = button#bye")
    public void showBye() {
        Messsagebox.show("Bye");
    }
    @Listen("onOK = window#mywin")
    public void onOK() {
        Messsagebox.show("OK pressed");
    }
}

As shown above, the method to listen is annotated with the Listen annotation using the event name followed by a selector string identifying the component(s) (for more selector syntax examples see SelectorComposer). The composer will register each annotated method as an event listener to the selected component automatically in the same ID space. Then, in the ZUL page, you can specify the apply attribute to associate the composer with a component.

<window id="mywin" apply="MyComposer">
    <textbox/>
    <button id="hi"/>
    <button id="bye"/>
</window>

If the listener needs to access the event, just declare it as the argument:

    @Listen("onClick = button#hi")
    public void showHi(MouseEvent event) {
      Messsagebox.show("Hello, " + event.getName());
    }

Though not limited, a composer is usually associated with an ID space (such as Window) to handle events and component within the give ID space. You could associate any component that properly represents a scope of your application to manage.

For more information please refer to the Wire Event Listeners section.

Deferrable Event Listeners

By default, events are sent to the server when it is fired at the client. However, many event listeners are just used to maintain the status on the server, rather than providing visual response to the user. In other words, there is no need to send the events for these listeners immediately. Rather, they shall be sent at once at a time to minimize the traffic between the client and the server so as to improve the server's performance. For the sake of the convenience, we call them the deferrable event listeners.

To make an event listener deferrable, you have to implement Deferrable (with EventListener) and return true for the isDeferrable method as follows.

 public class DeferrableListener implements EventListener, Deferrable {
     private boolean _modified;
     public void onEvent(Event event) {
         _modified = true;
     }
     public boolean isDeferrable() {
         return true;
     }
 }

When an event is fired at the client (e.g., the user selects a list item), ZK won't send the event if no event listener is registered for it or only deferrable listeners are registered. instead, the event is queued at the client.

On the other hand, if at least one non-deferrable listener is registered, the event will be sent immediately with all queued events to the server at once. No event is lost and the arriving order is preserved.


Tip: Use the deferrable listeners for maintaining the server status, while the non-deferrable listeners for providing the visual responses for the user.

Page-level Event Listener

Developers could add event listeners to a page (Page) dynamically by Page.addEventListener(String, EventListener). Once added, all events of the specified name sent to any components of the specified page will be sent to the listener.

All event listeners added to a page (so-called page-level event listeners) are assumed to be deferrable, no matter if Deferrable is implemented or not.

A typical example is to use a page-level event listener to maintain the modification flag as follows (pseudo code).

page.addEventListener("onChange", new EventListener() {
    public void onEvent(Event event) {
        modified = true;
    }
});


Listen by the use of an Event Handler

An event handler is a method specified as an event attribute of a ZK page or as a member of a component class.

Declare an Event Handler in ZUML

An event handler can be declared in a ZUL page by specifying an event attribute[1]. For example,

<button label="hi" onClick='alert("Hello")'/>

where the content of the event handler is the code snippet in Java. The event handler will be interpreted at the run time (by use of BeanShell). If you prefer to use other language, you could specify the language name in front of it. For example, the following uses Groovy as the interpreter:

<button label="hi" onClick="groovy:alert('Hi, Groovy')"/>

Important Builtin Variables

  • self - the component receiving the event. In the previous example, it is the button itself.
  • event - the event being received. In the previous example, it is an instance of MouseEvent.

Notice that the event handler declared in this way is interpreted at the run time, so it inherits all advantages and disadvantage of interpreter-based execution.

Advantange:

  • It can be changed on the fly without recompiling and reloading the application.
  • Easy to maintain if the code snippet is small.

Disadvantage:

  • Slower to run.
  • Compilation error can not be known in advance.
  • Hard to maintain if mixing business logic with user interface.

Suggestion:

  • It is generally suggested to use this approach for 1) prototyping, or 2) simple event handling.

Declare an Event Handler in Java

The other way to have an event handler is to declare it as a member of a component class. For example,

public class MyButton extends Button {
    public void onClick() {
        Messagebox.show("Hello");
    }
}

If the event handler needs to handle the event, it can declare the event as the argument as follows.

public class MyButton extends Button {
    public void onClick(MouseEvent event) {
        Messagebox.show("Hello, "+event.getName());
    }
}

Suggestions:

  • It is suggested to use this approach for component development, since it is subtle for application developers to notice its existence. In addition, it requires to extend the component class.

  1. An event attribute is an attribute starting with on


Precedence of Listeners

The order of precedence for listeners from the highest to the lowest is as follows.

  1. Event listeners implemented with Express, and registered by Component.addEventListener(String, EventListener)
  2. Event handlers defined in a ZUML document
  3. Event listeners registered by Component.addEventListener(String, EventListener) (and without Express)
  4. Event handlers defined as a class's method
  5. Event listeners registered to a page by Page.addEventListener(String, EventListener)

Abort the Invocation Sequence

You could abort the calling sequence by calling Event.stopPropagation(). Once one of the event listeners invokes this method, all the following event handlers and listeners are ignored.

Version History

Version Date Content
5.0.6 November 2010 SerializableEventListener was introduced to simplify the instantiation of a serializable anonymous class


Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.