org.zkoss.zk.ui.event
Interface EventQueue

All Known Subinterfaces:
EventQueue
All Known Implementing Classes:
DesktopEventQueue, ServerPushEventQueue

public interface EventQueue

An event queue. An event queue is a many-to-many 'channel' to publish events and to subscribe event listeners (EventListener).

Asynchronous and Synchronous Event Listeners

There are two kinds of event listeners: synchronous and asynchronous. A synchronous listener works the same as a normal event listener (listeners registered to a component (Component.addEventListener(java.lang.String, org.zkoss.zk.ui.event.EventListener)). It is executed one-by-one (no two even listener will be executed at the same time) and under an execution (i.e., Executions.getCurrent() never null). In additions, it is allowed to manipulate the components belonging to the current execution.

On the other hand, an asynchronous listener is executed asynchronously (in a working thread). It can not access the components belonging to any desktop. There is no current execution (Executions.getCurrent() is null}. However, it is useful to make the application more responsive when executing a long operation. A typical use is to execute the long operation in an asynchronous listener, and then all other events can be processed concurrently.

Since:
5.0.0
Author:
tomyeh

Method Summary
 void close()
          Closes the event queue.
 boolean isSubscribed(EventListener listener)
          Returns if an event listener is subscribed.
 void publish(Event event)
          Publishes an event the queue.
 void subscribe(EventListener listener)
          Subscribes a listener to this queue.
 void subscribe(EventListener listener, boolean async)
          Subscribes a synchronous or asynchronous listener to this event queue.
 void subscribe(EventListener listener, EventListener callback)
          Subscribes a synchronous or asynchronous listener to this event queue.
 boolean unsubscribe(EventListener listener)
          Unsubscribes a listener from the queue.
 

Method Detail

publish

void publish(Event event)
Publishes an event the queue.

If this is a desktop-level event queue, this method must be called within an activated exection, i.e., Executions.getCurrent() not null.

On the other hand, if this is an application-level event queue, it is OK to be called without the current execution.

Throws:
java.lang.IllegalStateException - if this method is called not within an activated execution (such as a working thread), and this is a desktop-level event queue.

subscribe

void subscribe(EventListener listener)
Subscribes a listener to this queue. It is the same as subscribe(listener, false) (subscribe(EventListener,boolean). In other words, it subscribes a synchronous listener.

Note: this method must be called within an activated exection, i.e., Executions.getCurrent() not null.

Note: if this is an application-level event queue, the listener shall not access the component associated with the event Event.getTarget().

An event listener can be subscribed multiple times, and it will be invoked multiple times if an event is published.

Even if this is an application-level or session-level event queue, the listener is subscribed for the current desktop only. If you want to use the same listener for multiple desktops, you have to subscribe them separately when the corresponding execution is available.

See Also:
subscribe(EventListener,EventListener), subscribe(EventListener,boolean)

subscribe

void subscribe(EventListener listener,
               EventListener callback)
Subscribes a synchronous or asynchronous listener to this event queue. A synchronous listener works the same as a normal event listener, while an asynchronous listener is executed asynchrously (in an working thread). Refer here for details.

Here is an example,


<window title="long operation" border="true">
        <zscript>
        void print(String msg) {
                new Label(msg).setParent(inf);
        }
        </zscript>
        <button label="async long op">
                <attribute name="onClick"><![CDATA[
   if (EventQueues.exists("longop")) {
     print("It is busy. Please wait");
     return; //busy
   }

   EventQueue eq = EventQueues.lookup("longop"); //create a queue
   String result;

   //subscribe async listener to handle long operation
   eq.subscribe(new EventListener() {
     public void onEvent(Event evt) { //asynchronous
       org.zkoss.lang.Threads.sleep(3000); //simulate a long operation
       result = "done"; //store the result
     }
   }, new EventListener() { //callback
     public void onEvent(Event evt) {
       print(result); //show the result to the browser
           EventQueues.remove("longop");
         }
   });

   print("Wait for 3 seconds");
   eq.publish(new Event("whatever")); //kick off the long operation
                ]]></attribute>
        </button>
        <vbox id="inf"/>
</window>

Notice that, though an asynchronous listener cannot access the desktop and has no current execution, it can invoke publish(org.zkoss.zk.ui.event.Event) to publish the events. Refer to another example in subscribe(EventListener,boolean).

Parameters:
listener - the asynchronous listener to invoke when an event is received
callback - the callback listener, which will be invoked if the asynchronous listen has been invoked. Unlike the asynchronous listener, the callback listener works like a normal listener. You can access the current execution, and update the desktop. Notice that the event argument is null when the callback listener is called.
See Also:
subscribe(EventListener), subscribe(EventListener,boolean)

subscribe

void subscribe(EventListener listener,
               boolean async)
Subscribes a synchronous or asynchronous listener to this event queue. A synchronous listener works the same as a normal event listener, while an asynchronous listener is executed asynchrously (in an working thread). Refer here for details.

The use of synchronous listeners is straightforward -- they are just the same a normal event listener. Here is an example of using an asynchronous listener. In this example, we use an asynchronous listener to execute a long operation, a synchronous listener to update the desktop, and they communicate with each other with events.

There is another way to do the same job, callback, refer to subscribe(EventListener,EventListener) for example.


<window title="long operation" border="true">
  <zscript>
  void print(String msg) {
    new Label(msg).setParent(inf);
  }
  </zscript>
  <button label="async long op">
    <attribute name="onClick"><![CDATA[
   if (EventQueues.exists("longop")) {
     print("It is busy. Please wait");
     return; //busy
   }

   EventQueue eq = EventQueues.lookup("longop"); //create a queue
   String result;

   //subscribe async listener to handle long operation
   eq.subscribe(new EventListener() {
     public void onEvent(Event evt) {
       if ("doLongOp".equals(evt.getName())) {
         org.zkoss.lang.Threads.sleep(3000); //simulate a long operation
         result = "done"; //store the result
         eq.publish(new Event("endLongOp")); //notify it is done
       }
     }
   }, true); //asynchronous

   //subscribe a normal listener to show the resul to the browser
   eq.subscribe(new EventListener() {
     public void onEvent(Event evt) {
       if ("endLongOp".equals(evt.getName())) {
             print(result); //show the result to the browser
             EventQueues.remove("longop");
           }
         }
   }); //synchronous

   print("Wait for 3 seconds");
   eq.publish(new Event("doLongOp")); //kick off the long operation
    ]]></attribute>
  </button>
  <vbox id="inf"/>
</window>

The asynchornous event listener requires Server Push which is available in ZK PE or EE, or you have to configure your own implementation.

If you want to show a busy message to cover a portion of the desktop, use Clients.showBusy(org.zkoss.zk.ui.Component,String)

Note: this method must be called within an activated exection, i.e., Executions.getCurrent() not null.

An event listener can be subscribed multiple times, and it will be invoked multiple times if an event is published.

Even if this is an application-level or session-level event queue, the listener is subscribed for the current desktop only. If you want to use the same listener for multiple desktops, you have to subscribe them separately when the corresponding execution is available.

Parameters:
listener - the listener
async - whether the listener is asynchronous
See Also:
subscribe(EventListener), subscribe(EventListener, EventListener)

unsubscribe

boolean unsubscribe(EventListener listener)
Unsubscribes a listener from the queue.

Note: this method must be called within an activated exection, i.e., Executions.getCurrent() not null.

Notice that this method only unsubscribes the listener subscribed for this desktop. It doesn't check the listeners for other desktops even if this is an application-level or session-level event queue.

Returns:
true if the listener was subscribed.

isSubscribed

boolean isSubscribed(EventListener listener)
Returns if an event listener is subscribed.

Notice that this method only checks the listeners subscribed for this desktop. It doesn't check the listeners for other desktops even if this is an application-level or session-level event queue.


close

void close()
Closes the event queue. After closed, application cannot access any of its method.

Don't call this method directly. It is called only internally. Rather, use EventQueues.remove(java.lang.String) instead.



Copyright © 2005-2009 Potix Corporation. All Rights Reserved. SourceForge.net Logo