Add and Remove Event Listeners by Program

From Documentation
Add and Remove Event Listeners by Program


Stop.png This documentation is for an older version of ZK. For the latest one, please click here.


There are two ways to add event listeners by program.

Declare a Member

When overriding a component by use of your own class, you could declare a member function to be an event listener as follows.

In a ZUML page, you declare the use attribute to specify what class you want to use instead of the default one. As illustrated below, it asks ZK to use the MyWindow class instead of Window[1].

<window use="MyWindow">
 ...
</window>

Then, you implement MyWindow.java by extending from the default class as follows.

 public class MyWindow extends org.zkoss.zul.Window {
     public void onOK() { //add an event listener
         ...//handles the onOK event (sent when ENTER is pressed)
     }
 }

If you want to retrieve more information about the event, you could declare as follows.

 public void onOK(org.zkoss.zk.ui.event.KeyEvent event) {
 ...
 }

or

 public void onOK(org.zkoss.zk.ui.event.Event event) {
 ...
 }

Different events might be associated with different event objects.

Add and Remove Event Listeners Dynamically

Developers could use the addEventListener and removeEventListener methods of the Component interface to dynamically add or remove an event listener. As illustrated below, the event listener to be added dynamically must implement the EventListener interface.

 void init(Component comp) {
     ...
     comp.addEventListener("onClick", new MyListener());
     ...
 }
 class MyListener implements org.zkoss.zk.ui.event.EventListener {
     public void onEvent(Event event) throws UiException {
         ...//processing the event
     }
 }

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.

To make an event listener deferrable, you have to implement the Deferrable interface (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 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.

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

Add and Remove Event Listeners to Pages Dynamically

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

All page-level event listeners are non-ASAP. In other words, the isArap method is ignored.

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

 public class ModificationListener implements EventListener, Deferrable {
     private final Window _owner;
     private final Page _page;
     private boolean _modified;

     public ModificationListener(Window owner) {
         //Note: we have to remember the page because unregister might
         //be called after the owner is detached
         _owner = owner;
         _page = owner.getPage();
         _page.addEventListener("onChange", this);
         _page.addEventListener("onSelect", this);
         _page.addEventListener("onCheck", this);
     }
     /** Called to unregister the event listener.
      */
     public void unregister() {
         _page.removeEventListener("onChange", this);
         _page.removeEventListener("onSelect", this);
         _page.removeEventListener("onCheck", this);
     }
     /** Returns whether the modified flag is set.
      */
     public boolean isModified() {
         return _modified;
     }
     //-- EventListener --//
     public void onEvent(Event event) throws UiException {
         _modified = true;
     }
     //-- Deferrable --//
     public boolean isDeferrable() {
         return true;
     }
 }

Note: Whether to implement the Deferrable interface is optional in this example, because the page's event listeners are always assumed to be deferrable, no matter Deferrable is implemented or not.

The Invocation Sequence

The sequence of invoking event listeners is as follows. Let us assume the onClick event is received.

  1. Invoke event listeners for the onClick event one-by-one that are added to the targeting component, if the listeners also implement the Express interface. The first added, the first called.
  2. Invoke the script specified in the onClick attribute of the targeting component, if any.
  3. Invoke event listeners for the onClick event one-by-one that are added to the targeting component, if the listeners don't implement the Express interface. The first added, the first called.
  4. Invoke the onClick member method of the targeting component, if any.
  5. Invoke event listeners for the onClick event one-by-one that are added to the page that the targeting component belongs. The first added, the first called.

The Express interface is a decorative interface used to alter the invocation priority of an event listener. Notice that it is meaningless if the event listener is added to pages, instead of components.

Abort the Invocation Sequence

You could abort the calling sequence by calling the stopPropagation method in the Event class. Once one of the event listeners invokes this method, all following event listeners are ignored.

Notes

  1. The default class is defined in lang.xml embedded in zul.jar.



Last Update : 2022/01/19

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