ZK的创意起源于用户希望web应用程序有C/S架构系统一般的互动性效果,然而各家浏览器支持的语法不一,web应用程序开发不但麻烦,出错机率也高。加上使用接口每家需求不一,程序代码重复利用性低,形成开发上相当大的成本。于是ZK团队(中国台湾地区陈志恒、叶明宪、叶明政、何政达等人)想到:既然问题出在客户端,如果让服务器端来处理会如何?由服务器接手使用者接口,由特定组件处理浏览器的语法差异,解决开发者容易出错的地方,并产生丰富的互动效果,这样一来,过去的问题就能迎刃而解。基于用户的需求、开发者的困境,以及灵光一现的各种想法,ZK的雏形于是诞生。
ZK是一套开放源代码的、符合XUL/HTML标准、用Java实现的,以 AJAX/XUL/Java为基础的富客户端B/S应用系统开发框架。它为B/S系统开发带来了C/S系统开发一样体验。ZK包含了一个以AJAX为基础、事件驱动(event-driven)、高互动性的引擎,同时还提供了多种丰富、可重复使用的XUL和HTML组件,以及以 XML为基础的介面设计语言 ZK User-interfaces Markup Language (ZUML)。
ZK 提供超过70个XUL组件及80个XHMTL组件。包括提供 FCKeditor, Dojo, Google Maps, 和 SIMILE Timeline等组件,使用者直接以Java控制,无需使用 JavaScript。
ZK原理
ZK loader: 由一系列Java servlets组成,复杂接受URL request生成相应的HTML页面(包括css,javascript,ZK组件).
ZK AU(asynchronous update): 即ZK异步更新引擎,负责接收Ajax requests,更新ZK组件属性,并将response返回客户端.
ZK client engine: ZK客户端引擎,由一些列javascript组成,负责监控浏览器javascript事件队列,如果有事件触发就将事件以Ajax requests的方式发送到服务器端的ZK异步更新引擎,然后接收ZK异步更新引擎返回的应答更新页面。
三元素
组件:Component (of interface org.zkoss.zk.ui.Component)
user interface (UI) object, such as a label, a button, or a tree. It defines the visual representation and behaviors of a particular user interface element. By modifying the component itself or manipulating the component structure, you can control to the visual representation of an application in the client
页面:Page (of class org.zkoss.zk.ui. Page)
a collection of components.
桌面:Desktop (of class org.zkoss.zk.ui.Desktop)
a collection of pages for serving the same URL request.
组件的生命周期
加载一个zul的页面会做以下操作
1. Page initialization
2. Component creation
3. Event processing
4. Rendering
ZK AU engine收到来自客户端的ZK requests会做如下三步处理:
1. Request processing
2. Event processing
3. Rendering
开发环境搭建
JDK6.0 + Eclipse 3.4
ZK Studio 0.9.1
(http://studioupdate.zkoss.org/studio/update)
ZK3.5.2(目前的最新版,见http://www.zkoss.org)
增加XML扩张文件名
1.打开eclipse的菜单 Window ➤ Preferences. 在对话框中General ➤Content Types
在Content Types 面板Text ➤ XML
“Content type” 填写 *.zul,
2.创建动态web工程
File ➤ New ➤ Project.
Web ➤ Dynamic Web Project
3.导入ZK的库到$PRJ/WebContent/WEB-INF/lib。
self指组件本身
Do you like ZK?
支持EL表达式${}
For each支持
contacts = new String[] {"Monday", "Tuesday", "Wednesday"};
Use属性
不需要继承:
onOK="MyClass.save(main)" onCancel="MyClass.cancel(main)"/>
import org.zkoss.zul.Window;
public class MyClass {
public static void init(Window main) {
//does initialization
}
public static void save(Window main) {
//saves the result
}
public static void cancel(Window main) {
//cancel any changes
}
}
需要继承:
import org.zkoss.zul.Window;
public class MyWindow extends Window {
public void onCreate() {
//does initialization
}
public void onOK() {
//save the result
}
public void onCancel() {
//cancel any changes
}
}
命名空间
getFellow("winC").getFellow("labelB")
Path.getComponent("/winC/labelB")
跨业面引用:
引用第1个页面的winA下的labelB:
labelI.getDesktop().getPage("page1").getFellow("winA").getFellow("labelB")
斜杠“/”表示页根
双斜杠“//”表示桌面根
三种注册组件事件listener的方法
(1)作为已定义的属性
(2)作为已定义的方法
class MyButton extends Button {
public void onClick(MouseEvent event) {
Messagebox.show("Hello World!");
}
}
(3)作为新的事件Listener
hellobtn.addEventListener("onClick", new EventListener() {
public void onEvent(Event event) {
Messagebox.show("Hello World!");
}
});
事件除了被浏览器触发外,也可以自己在程序中用org.zkoss.zk.ui.event.Events触发:
Events.postEvent(new Event( . . . )).
支持多种标签混合使用,注意引入命名空间以区别
xmlns:h="http://www.w3.org/1999/xhtml"
xmlns:x="http://www.zkoss.org/2005/zul"
xmlns:zk="http://www.zkoss.org/2005/zk">
zk:onClick="addItem()"/>
MessageBox
if (Messagebox.show("Remove this file?",
"Remove?", Messagebox.YES | Messagebox.NO,
Messagebox.QUESTION) == Messagebox.YES) {
...//remove the file
}
alert("Wrong"); 等同于 Messagebox.show("Wrong");
文件上传Fileupload
Object media = Fileupload.get(); //the upload dialog appear
if (media instanceof org.zkoss.image.Image)
image.setContent(media);
else if (media != null)
Messagebox.show("Not an image: "+media,
"Error", Messagebox.OK, Messagebox.ERROR);
}
宏组件(Macro Components)
1. Define a macro component using a ZUML page:
2. Declare the macro component in the page that is going to use it:
3. Use the macro components, which is no different from using other components:
使用宏组件要注意命名冲突问题。
GoogleMap
使用google map要先注册(http://www.google.com/apis/maps/),将key替换下列代码中的key.
FCKeditor
Fisheyebar
<fisheyebar id="fish" style="position: absolute; top: 20px; left:100px;margin:10px;" attachEdge="top">
<fisheye image="/img/icon_browser.png" label="Web浏览" onClick="alert(self.label)">fisheye>
<fisheye image="/img/icon_calendar.png" label="日历" onClick="alert(self.label)">fisheye>
<fisheye image="/img/icon_email.png"
label="Email" onClick="alert(self.label)"/>
<fisheye image="/img/icon_texteditor.png"
label="文本编辑器" onClick="alert(self.label)"/>
<fisheye image="/img/icon_update.png"
label="软件更新" onClick="alert(self.label)"/>
<fisheye image="/img/icon_users.png"
label="用户" onClick="alert(self.label)"/>
fisheyebar>
<div height="100px" width="100%" style="border:1px solid black;"/>
使用Javascript
<script type="text/javascript">
function setZoom(value){
var maps=document.getElementsByTagName('gmaps');
var j = 0;
for (; j < maps.length; ++j) {
maps[j].setZoom(value);
}
}
]]>
script>
参考:
ZK-devguide.pdf
Apress.ZK Ajax without the Javascript Framework.pdf
Packt.Publishing.ZK.Developers.Guide.Dec.2007.pdf