有两种方法通过程序添加或移除事件监听器。
当用你自己的类重定义(overriding)一个组件后,你可以声明一个成员函数成为事件监听器。
在一个ZUML页面中,你可以使用use
属性来指定你想使用的类,即用它去替换默认类。如下所示,它使用了MyWindow
来替换默认的org.zkoss.zul.Window
[31]。
<window use="MyWindow"> ... </window>
然后你淂实现MyWindow.java同过继承默认的类,就像下面一样:
public class MyWindow extends org.zkoss.zul.Window { public void onOK() { //add an event listener ...//handles the onOK event (sent when ENTER is pressed) } }
如果你想获得关于事件的更多信息,你可以按如下方式声明:
public void onOK(org.zkoss.zk.ui.event.KeyEvent event) { ... }
或
public void onOK(org.zkoss.zk.ui.event.Event event) { ... }
不同的事件或许与不同的事件对象相关联。参考附录C(Append C)来获取更多的细节。
开发人员可以使用org.zkoss.zk.ui.Component
接口中的addEventListene
和removeEventListener
方法来动态地添加或移除事件监听器。如下所示,动态添加的事件监听器必须实现org.zkoss.zk.ui.event.EventListener
接口。
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 } }
默认情况下,当客户端的事件被触发时就会被送到服务器。但是,许多事件仅用于维持服务器端的现状,而不是向客户端提供视觉响应(visual response)。换句话说,这些监听器的事件并不需要马上被送出。相反,它们应该仅被提交一次,以降低客户端和服务器端的来往,以提高服务器的性能。为求描述方便,我们称它们为延期事件监听器(Deferrable Event Listeners)。
为了使一个事件监听延期,必须实现org.zkoss.zk.ui.event.Deferrable
接口(和 EventListener)并且使用isDeferrable
方法返回true,就像下面一样。
public class DeferrableListener implements EventListener, Deferrable { private boolean _modified; public void onEvent(Event event) { _modified = true; } public boolean isDeferrable() { return true; } }
当客户端的一个事件(例如,选择一个列表项目(list item))被触发时,如果没有为其注册事件监听器或仅有延期(deferrable)的监听器被注册,ZK不会将事件送出。
一方面,如果至少有一个非延期(non-deferrable)监听器,事件会被马上送到服务器端,和所有的队列事件(queued events)一起。没有事件会丢失,到达顺序是保存好的。
[提示]:当有非延期监听器为用户提供视觉响应,可以使用使用延期的(deferrable)事件监听器维持(maintaining)服务器状态。
开发人员可以为页面(org.zkoss.zk.ui.Page
)动态地添加和移除事件监听器。一旦被添加,所有被指定名字的事件会被送到指定页面的任何组件,这些页面将会被送到监听器。
所有的页面级(page-level)事件监听器都是非即时。换言之,isArap
方法被忽略了。
一个典型的例子是使用页面级事件监听器来维护修改标志(modification flag),如下:
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; } }
[注]: 在事例中是否实现Deferrable
接口是可选的,因为页面的事件监听器总是假定为延期的,与是否实现Deferrable
接口无关。
调用事件监听器的顺序如下。假定接收的是onClick
事件。
如果监听器实现了org.zkoss.zk.ui.event.Express
接口,依次为添加到目标组件(targeting component)的onClick
事件调用事件监听器。按照添加的顺序调用。
调用目标组件的onClick
属性指定的脚本语言。
如果监听器没有实现org.zkoss.zk.ui.event.Express
接口,依次为添加到目标组件的onClick
事件调用事件监听器。按照添加的顺序调用。
调用目标组件的onClick
成员方法。
依次为添加到目标组件所属页面的的onClick
事件调用事件监听器。按照添加的顺序调用。
org.zkoss.zk.ui.event.Express
接口是一个装饰器(decorative interface),用来改变调用事件监听器的优先级。注意,如果事件监听器被添加到页面,而不是组件,这个接口是没有意义的。