长操作对于同一个桌面事件是被顺序处理的。换个说法,一个事件的处理程序将可以阻塞所有的后续处
理程序。一个长时间被阻塞的请求可能是不可接受的(the time blocking user’s requests might
not be acceptable),如果一个事件的处理将花费大量的时间。象桌面应用,你需要创建一个专用于工
作这种长时间处理的工作线程来减少阻塞时间。
限制于http协议,我们必须符合以下的规则。
1. 在创建了工作线程后,使用wait方法来挂起事件处理进程本身。
2. 因为工作线程不是一个事件监听器,所以它不能进入任何组件(除非组件不属于任何桌面)。因此
,在开始工作线程前你可能需要手工通过一些必要的信息。
3. 然后,工作线程可以crush the information和创建组件(若必要的话)。只是不把任何组件关联
到任何桌面。
4. 在工作线程结束之后,在工作线程中使用类org.zkoss.zk.ui.Executions notify(Desktop
desktop,Object flag)或者notifyAll(Desktop desktop,Object flag)方法来恢复事件处理进程。
5. 直到从客户另一个事件被发送过来,恢复的事件处理进程才会执行。为了强制发送一个事件,你可
以使用timer组件(org.zkoss.zul.Timer)来触发一个事件a moment later or periodically.这个
timer的时间监听器不做任何事情。
例子:工作线程异步的创建标签
假设我们想异步的创建标签。当然,这有点象用牛刀来杀鸡了,但是我们可以用sophisticated one 来
替换这个任务。
//Working Thread
Package test;
Public class WorkingThread extends Thread
{
private static int _cnt;
private Desktop _desktop;
private Label )label;
private final Object _mutex = new Integer(0);
public static final Label asyncCreate(Desktop desktop)
throws InterruptedException{
final WorkingThread worker = new WorkingThread(desktop);
synchronized(worker._mutex)
{
worker.start();
Executions.wait(worker._mutex);
return worker._label;
}
}
public WorkingThread(Desktop desktop)
{
_desktop = desktop;
}
public void run()
{
_label = new Label("Execute "+ ++_cnt);
synchronized(_mutex)
{
Executions.notify(_desktop,_mutex);
}
}
}
然后,我们有一个ZUML页面在一个事件监听器里来调用这个工作线程,如在onClick中
<window id="main" title="Working Thread">
<button label="Start Working Thread">
<attribute name="onClick">
timer.start();
Label label = test.WorkingThread.asyncCreate(desktop);
main.appendChild(label);
timer.stop();
</attribute>
</button>
<timer id="timer" runing="false" delay="1000" repeats="true"/>
</window>
注意我们需要使用timer来真正恢复被挂起的事件监听器(onclick)。这看起来是多余的,但是归因于
http的限制:为了保持web页面在浏览器中的alive,当事件处理进程被挂起的时候我们必须返回回应。
然后,工作线程完成了工作,唤醒了事件监听器,http的请求已经gone了。因此,我们需要”piggyback
”这个结果,这就是timer被使用的原因。
更准确的来说,当工作进程唤醒了事件监听器,ZK只是把它加到一个等待队列中。当另一个http请求到
达的时候,监听器才真正的恢复。(在上面的例子中,是onTimer事件)
在这个简单里例子中,我们对onTimer事件什么都没做。对于一个sophisticated应用,你可以使用它来
返回处理的状态。
另一个事例:没有挂起和恢复
没有挂起和恢复来执行一个长时间的操作是可能的。当同步代码对于调试来说太复杂的情况下是有用的
。
主意很简单。工作进程在一个临时空间里保存结果,然后onTimer事件监听器将结果弹出到桌面。
//WorkingThread2
package test;
public class WorkingThread2 extends Thread
{
private static int _cnt;
private final Desktop _desktop;
private final List _result;
public WorkThread2(Desktop desktop,List result)
{
_desktop = desktop;
_result=result;
}
public void run(){
_result.add(new Label("Execute "+ ++_cnt));
}
}
然后,在onTimer事件监听器上面追加labels
<window id = "main" title="working thread2">
<zscript>
int numpending = 0;
List result=Collections.synchronizedList(new LinkedList());
</zscript>
<button label="start working thread">
<attribute name="onClick">
++numpending;
timer.start()
new test.workingthread2(desktop,result).start();
</attribute>
</button>
<timer id="timer" running="false" delay="1000" repeats="true">
<attribute name="onTimer">
while(!result.isEmpty())
{
main.appendChild(result.remove(0));
--numpending;
}
if(numpending==0)time.stop();
</attribute>
</timer>
</window>
初始和清除事件处理线程
在处理每个事件之前初始化
一个事件监听器是在一个事件处理线程中执行的。有时,你不得不在处理所有事件之前初始该线程。
一个典型的例子是初始认证所使用的线程。一些j2ee或者web容器在thread local storage中存储着认证
信息,因此它们可以在需要时自动进行重复认证。
为了进行事件处理线程的初始化,你需要在web-inf/zk.xml文件注册一个继承自
org.zkoss.zk.ui.event.EventThreadInit接口的类。
一旦进行了注册,在开始一个事件处理线程之前,在主线程中一个指定类的实例就被创建了。然后在处
理其他事情之前,该实例的init方法在事件处理线程的上下文中被调用了。
注意那个构造体和init方法是在不同的线程中被调用的,因此开发者可以从一个线程获得线程独立的数
据发送到另一个线程。
下面是jboss的认证机制的例子。在这个例子中,我们在构造体中获得储藏在servlet线程中的信息。然
后,我们在init方法调用的时候初始事件处理线程。
import java.security.Principal;
import org.jboss.security.SecurityAssociation;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventThreadInit;
public class JBossEventThreadInit implements EventThreadInit
{
private final Principal _principal;
private final Object _credential;
public JBossEventThreadInit()
{
_principal=SecurityAssociation.getPrincipal();
_credential=SecurityAssociation.getCredential();
}
public void init(Component comp,Event evt)
{
SecurityAssociation.setPrincipal(_principal);
SecurityAssociation.setCredential(_credential);
}
}
然后在web-inf/zk,xml中,如下进行注册:
<zk>
<listener>
<listener-class>JBossEventThreadInit</listener-class>
</listener>
</zk>
在处理完每个事件后清除
同样的,你可能不得不在处理完一个事件后清除一个事件处理进程。
典型的例子是关闭一个transaction,如果它没有被适当的关闭。
为了清除一个事件处理线程,你需要注册一个实现org.zkoss.zk.ui.event.EventThreadCleanup接口的
监听类,然后在web-inf/zk.xml中注册。
<zk>
<listener>
<listener-class>my.MyEventThreadCleanup </listener-class>
</listener>
</zk>
相关推荐
这些动作会触发程序中的特定行为,通常通过事件监听器来实现。本文将深入探讨事件处理监听器的概念,以及如何在Java或类似的面向对象语言中设置和使用它们。 首先,我们来理解“事件”这个概念。在UI编程中,事件是...
而通过JavaScript方法添加事件监听器,可以更灵活地控制事件处理过程,并且可以轻松地添加和移除监听器。 在前端开发中,对this关键字的理解和使用是必要的。在事件处理函数中,this关键字默认指向触发事件的元素,...
`addEventListener`和`removeEventListener`是`cc.EventTarget`接口提供的方法,它们允许我们对任何具有事件处理能力的对象添加或移除事件监听器。 ### 事件类型 Cocos Creator支持多种内置事件类型,包括但不限于...
总之,Windchill的事件监听机制是系统灵活性和可扩展性的重要组成部分,它允许开发者通过自定义代码响应系统内部的各种事件,从而实现业务逻辑的自动化和个性化。理解和掌握这一机制对于深入理解和优化Windchill系统...
* 解耦合:事件监听器机制可以将事件的发送方和事件的处理方解耦合,使得程序更加灵活和可维护。 * 灵活性:事件监听器机制可以使得程序更加灵活和可扩展。 * 耦合度低:事件监听器机制可以降低程序的耦合度,使得...
Java自定义事件监听允许开发者创建自己的事件类型并相应地处理它们,以满足特定应用的需求。下面我们将深入探讨这一主题。 首先,我们需要理解Java AWT(Abstract Window Toolkit)和Swing库中的基础事件监听机制。...
可以使用`addEventListener`方法添加事件监听器,并处理不同的滚轮事件名称。 ```javascript document.addEventListener('DOMContentLoaded', function() { var body = document.body; // 针对大部分浏览器 ...
首先,ScrollView的滚动事件监听主要涉及到两个关键接口:OnScrollChangedListener和ViewTreeObserver.OnGlobalLayoutListener。OnScrollChangedListener提供了当ScrollView滚动时触发的方法,而...
标题提到的“android 外部类作为事件监听器类”是指将一个非匿名类(外部类)作为事件处理的对象,这在某些情况下可能是必要的,比如当监听器需要持有较复杂的成员变量或者实现多个接口时。然而,描述中提到的一个...
本资源介绍了java图形界面开发中的事件监听及事件处理的相关内容,对于学习的相关人员有一定的帮助。
Java监听键盘鼠标全局事件 Java监听键盘鼠标全局事件是指使用Java语言来监听和处理键盘和鼠标...该技术需要深入了解Java Native Interface、Windows Hook机制、线程和同步等技术细节,以便正确地实现事件监听和处理。
本文将详细解析Java事件处理机制中事件监听器的四种实现方式:自身类作为事件监听器、外部类作为事件监听器、匿名内部类作为事件监听器以及内部类作为事件监听器。 1. **自身类作为事件监听器** 在自身类作为事件...
### Java GUI 事件监听知识点详解 #### 一、概述 在Java编程中,图形用户界面(GUI)的设计是一项重要的技能。对于初学者来说,掌握如何创建一个简单的界面,并且能够处理用户交互事件是非常必要的。本篇文章将...
【Qt全局鼠标、键盘事件监听器库】是一个用于在Windows和Linux系统上实现跨平台的全局鼠标和键盘事件捕获的库。这个库基于流行的Qt框架,为开发者提供了一个便捷的方式来监听并处理系统的输入事件,无论是来自应用...
2. 事件监听器的实现应该遵循单一职责原则,避免将多个事件处理方法放在同一个事件监听器中。 3. 事件源应该提供注册事件监听器的方法,以便事件监听器可以被正确地注册。 Java监听器是Java编程中的一种重要设计...
在`EventHandlingTest`这个示例项目中,可能包含了对上述概念的实践代码,你可以通过查看和运行这个项目来更直观地理解libGDX的事件监听机制。通过对输入事件的精确控制,我们可以创建出高度互动的游戏和应用程序,...
2. 尺寸变化:当DIV的尺寸发生变化时,我们可以监听`resize`事件,但这个事件通常是为window对象设计的。对于DOM元素的尺寸变化,需要自定义逻辑或者利用MutationObserver。 3. 动画完成:如果使用jQuery的动画方法...
Java Swing 是一个功能强大的图形用户界面(GUI)工具包,它提供了许多事件和监听器接口,帮助开发者更好地处理用户交互。下面是 Java Swing 中常用的事件和监听器接口。 1. AncestorEvent 和 AncestorListener ...
2. CheckBox的事件监听同样使用`OnCheckedChangeListener`,监听其选中或取消选中的状态变化。 3. Spinner的事件监听使用`OnItemSelectedListener`。当用户选择Spinner的一个条目时,`onItemSelected()`方法会被...
Servlet事件监听器和JSP是Java Web开发中的重要组成部分,它们在构建动态网站时起着核心作用。Servlet事件监听器允许开发者对特定的Servlet容器事件做出反应,而JSP则是用于创建动态网页的简便方式。这里我们将深入...