ZK框架的分析与应用

ZK框架的分析与应用

1 ZK框架的引入

1.1 概述

ZK是一套以 AJAX/XUL/Java 为基础的网页应用程序开发框架,用于丰富网页应用程序的使用界面。最大的好处是,在设计AJAX网络应用程序时,轻松简便的操作就像设计桌面程序一样。 ZK包含了一个以AJAX为基础、事件驱动(event-driven)、高互动性的引擎,同时还提供了丰富多样、可重复使用的XUL与HTML组件,以及以 XML 为基础的使用界面设计语言 ZK User-interfaces Markup Language (ZUML)。

通过ZK这个框架,软件开发者基本可以脱离美工,由开发人员自己来布局页面,这样能够大大提高软件开发的效率。

 

1.2 构建一个简单的ZK应用

 

 

2  如何组建UI

组建UI即创建我们展示给Client端的View层页面。

2.1  使用基于xml的方式

2.2  使用纯Java代码的方式

 

2.3  xml与java代码混用的方式

 

2.4  zk中组建UI时需要了解的xml基础

通常情况下,我们都是使用XML的方式来组建UI,XML文件有严格的语法。如:必需要有结束标签;标签之间的嵌套要合理;等等。

XML文件中的表示的是处理命令。它位于xml文件的第一行,它和根元素是一个级别的。

在XML文件中是不能使用特殊字符的,如果我们一定要用那么就要将它替换掉:

特殊字符

替换成

<

>

&

&

"

'

\t(Tab)

     当属性值中要使用时才需要替换

\n

     当属性值中要使用时才需要替换

 

 

 

 

3  ZK页面中的基本概念:桌面、页面、组件

我们通过浏览器去访问ZK应用的时候,浏览器展示给我们的是ZK的一个Desktop,而在一个Desktop中可以包含多个Page。组成一个Page的基本元素就是ZK Component(ZK组件)。

3.1  Desktop、Page和Component之间的关系

桌面(Desktop)

它是zul页面的集合,即一个Desktop可以包含多个zul页面。

页面(Page)

zul页面是组件的集合。

组件(component)

ZK组件是组成zul页面的最小单位。

组件是一种用户接口(UI),比如一个标签、一个按钮。所有的ZK组件都实现了org.zkoss.zk.ui.Component接口

 

下面我们通过一幅图来看它们之间的关系:

 

注:使用Include组件包含一个页面时,如果我们设置它的mode(模式)为defer(延迟),那么,将有两个页面在这个Desktop上被创建

 

 

3.2  将Component附加到Page上

一个组件只有附加到一个page时才能在client端得到显现。要使一个组件属于一个page的话有两种方式:

1、  将组件添加到一个已经附加到page的组件上。相应的api:Component.appendChild(org.zkoss.zk.ui.Component)、Component.insertBefore(org.zkoss.zk.ui.Component, org.zkoss.zk.ui.Component)、Component.setParent(org.zkoss.zk.ui.Component)

2、  使用Component.setPage(org.zkoss.zk.ui.Page)直接将组件添加到一个page上,这个组件就成为了该页面的根组件。

 

3.3  销毁Page上的Component

ZK的组件之间是树状结构的,每一组件都只有一个根。

 

从页面上销毁一个组件可以通过下面两种方式来实现:

1、  组件不是根组件时:Component.setParent(null)

组件是根组件时:Component.setPage(null)

2、  Component.detach()

很显然第二种方式要简便。

 

销毁一个组件下面的所有组件可以通过如下代码来实现:

Component.getChildren().clear();

它等同于

for (Iterator it = comp.getChildren().iterator(); it.hasNext();) {

    it.next();

    it.remove();

}

 

 

3.4  使用ZK Studio来编辑zul页面

建议使用ZK Studio来编辑zuml页面,它里面有很好的content assist和visual editor功能。我们只需要在eclipse上安装一个ZK Studio插件就可以了。

你也可以直接使用XML Editor来编辑zuml页面,不过最好是在window组件中加上schema,再在eclipse中配置好对应的xsd文件,一样可以实现content assist的功能。

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xsi:schemaLocation="http://www.zkoss.org/2005/zul

http://www.zkoss.org/2005/zul/zul.xsd">

 

 

4  ZK常用基本组件

4.1  输入框组件汇总

在ZK中,输入框被细分成了很多种:textbox、intbox、decimalbox、doublebox、datebox、timebox、spinner、combobox、bandbox

组件的常用属性有(属性是可选的):constraint、disabled、maxlength、readonly

 

组件名

用途

textbox

用于输入文本。

例1:"Jerry" width="150px" />

效果图:

例2:"password" value="foo" width="150px" />

效果图:

intbox

用于输入整数,其他的按键都会被屏蔽。比如输入字母时不会有任何反应

例:"no negative,no zero" width="150px" value="12345678" />

效果图:

decimalbox

用于输入小数,其他的按键都会被屏蔽。

例:"###.##" value="154.326" width="150px" />

效果图:

doublebox

用于输入双精度数,其他的按键都会被屏蔽

datebox

用于输入日期,它自带一个日历控件,且可以对日期进行格式化。

例:"db" width="150px" format="yyyy/MM/dd" />

效果图:

未点击时:

点击后:

timebox

用于输入日期,注意:它的value是Date类型的。

例:

Date now = new Date();

"${now}"/>

效果图:

spinner

用于输入整数,其他的按键都会被屏蔽,组件上的箭头用于增加或减小输入框中的值。它的value只能是int类型的整数。step属性用于控制增长的歩长

例:"123345" step="2"/>

效果图:

combobox

下拉框。默认情况下是可以输入值的,设置了disabled=”true”之后,就只能通过鼠标选择而不能输入值。

例:

    "湖南" />

    "北京" />

    "上海" />

效果图:

未点击时:

点击后:

bandbox

一般用作搜索框。可以使用buttonVisible="false"将组件上的按钮隐藏

例:"123" />

效果图:

 

 

4.1.1 对输入框输入内容的约束和验证

输入框通常都有一个constraint属性,它是用来约束用户输入的,使用constraint属性可以控制输入控件接受什么值。

当失去光标的焦点时,如果不符合约束条件,就会弹出出错信息。

 

在ZK中提供了两种约束用户输入的方式:第一是使用ZK自定义的约束条件;第二是使用正则表达式。

constraint属性可以使用的值有:no positive、no negative、 no zero、no empty、no future、no past、no today 和一个正则表达式的集合。

no positive、no negative、 no zero适用于intbox。

no future、no past和no today 约束仅适用于datebox。

no empty适用于任何组件。

正则表达式约束仅适用于字符串类型组件,例如textbox、combobox和bandbox。

 

①  ZK自定义的约束条件

constraint中可以使用的约束条件表

约束条件

解析

no empty

输入不能为空

no future

不能是以后的时间。用于datebox

no negtive

不能输入负数。用于intbox

no past

不能是过去的时间。用于datebox

no positive

不能是正数。用于intbox

no today

不能是今天。用于datebox

no zero

不能是0。用于intbox

between yyyyMMdd and yyyyMMdd

控制时间在一个范围内。

例:"between 20071225 and 20071203"/>

after yyyyMMdd

例:"after 20071225"/>

before yyyyMMdd

 

end_before

end_after

after_start

after_end

指定弹出的错误提示框的位置。

例:"no empty, start_before"/>

效果图:

 

 

②  使用正则表达式

例:"/.+@.+\.[a-z]+/:邮箱地址不正确" />

效果图:

也可以不指定出错信息,这时会使用默认的出错信息。

例:"/.+@.+\.[a-z]+/" />

效果图:

如果是在java代码中,我们可以这样指定控件的constraint:

new Textbox().setContraint("/.+@.+\\.[a-z]+/");

 

 

4.2  容器组件

容器组件可以用来包含其他组件。

4.2.1  Window组件

Window组件是我们在ZK中使用最多的一个组件。

一个Window组件,就像HTML中的div标签一样,用来将组件组合在一起。

和其他组件不同,Window组件具有如下特点:

◆ Window组件是ID空间宿主。Window组件下的任何组件(包括它自身)都可以通过这个Window组件的id来进行检索。使用:id.getFellow(java.lang.String)

◆ Window组件可以设置成overlapped(重叠)、popup(弹出)、embeded(嵌入)

◆ Window可以作为一个模态窗口(modal dialog)

 

①  Window组件的模式(mode)

zul页面中,使用mode属性来设置Window的模式。

Window组件有5种不同的模式:overlapped、popup、modal、hightlighted、embeded

默认的是embeded模式。

我们可以通过Window.setMode(java.lang.String)来改变Window的模式。

我们也可以通过调用Window.doOverlapped()、Window.doPopup()、Window.doModal()、Window.doHightlighted()、Window.doEmbeded()来改变Window的模式。

 

例:

       "Hello, Wolrd!" />

      

    "win" title="Hi!" border="normal" width="200px">

      

           "Help" />

      

效果图:

embeded:这是默认的模式。这种模式下,我们不能改变Window的位置。

 

 

overlapped:overlapped模式下的Window与其他的组件是层叠的。用户可以使用鼠标拖拽它。开发人员可以通过Window.setLeft(java.lang.String)和Window.setTop(java.lang.String)来设置它的位置。

 

 

popup:popup模式和overlapped模式相似。它们之间不同是:在popup模式下,我们只要点击其他组件的话,这个弹出的Window就会自动消失。

 

 

modal:modal与hightlighted模式基本上是相同的。modal模式下,Window之外的组件是不能够操作的(如下图)。

 

 

hightlighted:

 

 

4.1.2  Window组件的常用属性

window属性表

属性名

说明

border

取值有:normal、none(默认为none)

例:

"border为none" border="none" width="200px">

       border为none的Window

"border为none" border="normal" width="200px">

       border为normal的Window

 

 

closable

一旦我们关闭了这个Window,那么这个页面上将不会有这个Window存在,也不能对它进行引用,否则会报错,这是也隐藏最大的不同。我们也可以通过Window.detach()来实现相同的效果。

Window关闭的时候会触发onClose事件。

 

我们可以重写onClose方法来实现我们自己想要的操作。比如,我们想在点击关闭按钮的时候将Window隐藏,而不是detach

例:

"myWin" closable="true" title="Demo" border="normal"width="200px"

 onClose="self.visible = false; event.stopPropagation();">

     点击关闭按钮,Window将会被隐藏,而非detach

效果图:

 

 

contentStyle

通过这个属性,我们可以为Window定制样式。

例1:

"My Window" border="normal" width="200px"contentStyle="background:yellow">

            Hello, World!

效果图:

 

例2:

"win" title="Hi" width="150px" height="100px"contentStyle="overflow:auto" border="normal">

      当我们设置了overflow:auto之后,当内容超过了可显示的区域之后,就会出现滚动条

效果图:

 

position

我们可以为mode为overlapped、pupup和modal的Window设置位置。

如:"300px" mode="overlapped" position="right,bottom">

可供选择的position有:center、left、right、top、bottom

sizable

用于设置Window是否可以改变大小。

当用户改变Window的大小时会触发onSize事件

title AND caption

用来设置标题。(注:caption是一个组件,而非属性)

例:

"My Window" border="normal" width="200px">

   

"/imgs/sml4.gif" label="Hi there!"/>

    "Hello, World!"/>

效果图:

 

 

4.2  Grid组件

Grid组件是处理与展现大量数据的组件。与它功能类似的组件有:Grid、Listbox、Tree。

 

4.2.1  Grid、Listbox、Tree的比较

◆  Grid和Listbox都是用来展现列表数据的。而Tree主要用来展示分层数据。

◆  Listbox和Tree允许用户选中它所展现的一条或多条数据(可以通过ZK提供的方法来获取选中的数据),而Grid则不行。

◆  Grid、Listbox和Tree都支持分页,具体请查阅Paging组件。

 

4.2.2  Grid概观

相关子组件:grid、columns、colum、rows、row

组件名

说明

grid

使用它来定义一个grid

columns

用来设置grid的标题头。

column

位于columns里面,用来设置列的相关属性

rows

用来展现数据

row

位于rows里面,用来展现一行数据

 

例1:

    "500px">

      

           "Column 1"/>

           "Column 2"/>

           "Column 3"/>

      

      

          

             

             

             

          

          

             

             

             

          

          

             

             

             

          

      

   

效果图:

 

4.2.3  Grid展现大批量数据

在grid中,我们有两种方式来展现大批量数据:一是使用滚动条;二是使用分页。

① 使用滚动条

只需要为grid的hight属性设置一个值,当数据展现超过这个hight时,滚动条会自动出现。

例:

我们在上面的例子中的grid标签上加个属性height=”100px”,即"500px" height="100px">。得到的效果图如下:

 

 

② 使用分页

在grid中添加属性:mold=”paging”  pageSize=”n”即可。当展现的数据量超过n条时,分页控件会自动出现。

(注意:这里的分页只是页面上的分页,而不是后台的分页。有人叫这种分页为假分页)

例:

我们将上面代码中的height去掉,加上属性:mold="paging" pageSize="3"

效果图:

pageSize的默认值为:20

 

除此指定mold=”paging”之外,我们还可以使用Paging组件来实现分页。详情请参照后续Paging分页的介绍。

 

 

4.2.4  使用Paging组件来为Grid分页

使用Paging组件,我们可以自定义的放置paging组件的位置。还可以使用一个Paging组件来控制多个grid,这时需要指定Grid组件的paginal属性为同一个Paging。

例:

    "pg" pageSize="3" />

   

       "300px" mold="paging" paginal="${pg}">

          

              "Left" />

              "Right" />

          

          

             

                 

                 

             

             

                 

                 

             

             

                 

                 

             

             

                 

                 

             

          

      

       "300px" mold="paging" paginal="${pg}">

          

              "Left" />

              "Right" />

          

          

             

                 

                 

             

             

                 

                 

             

             

                 

                 

             

             

                 

                 

             

             

                 

                 

             

          

      

   

效果图:

 

 

 

4.2.5  Paging组件的onPaging事件

当用户点击paging组件的时候,会触发onPaging事件。如果想实现后台自动分页,我们就可以通过这个事件来实现。

例:

"win" title="分页" border="normal" width="400px">

 

"paging" onCreate="init()">

   

       "编号" />

       "名字" />

   

    "rowsId">

   

"myPaging" pageSize="3" onPaging="nextPage(event)"/>

 

import org.zkoss.zul.event.PagingEvent;

        

class Student{

    private int id;

    private String name;

   

    public Student(){}

    public Student(int id, String name){

       this.id = id;

       this.name = name;

    }

    public int getId() {

       return id;

    }

    public void setId(int id) {

       this.id = id;

    }

    public String getName() {

       return name;

    }

    public void setName(String name) {

       this.name = name;

    }

}

 

List stuList = new ArrayList();

Student stu1 = new Student(1, "张三");

Student stu2 = new Student(2, "李四");

Student stu3 = new Student(3, "王五");

Student stu4 = new Student(4, "朱红");

stuList.add(stu1);

stuList.add(stu2);

stuList.add(stu3);

stuList.add(stu4);

 

final int PAGE_SIZE = myPaging.getPageSize();

 

public void nextPage(Event event){

    PagingEvent pe = (PagingEvent) event;

    int pgno = pe.getActivePage();//页数(从零计算)  

    int start = pgno * PAGE_SIZE;

    int end = start + PAGE_SIZE;

    end = end>stuList.size()?stuList.size():end;

    System.out.println(start+","+end);

   

    rowsId.getChildren().clear();//清空数据

    createData2View(start, end);

}

 

private void createData2View(int start, int end){//显示数据

    for(int i=start; i

     Student stu = (Student)stuList.get(i);

    Row row = new Row();

    Label lab1 = new Label();

    lab1.setValue(stu.getId()+"");

    Label lab2 = new Label();

    lab2.setValue(stu.getName());

    lab1.setParent(row);

    lab2.setParent(row);

    rowsId.appendChild(row);

    }

}

 

public void init(){

    createData2View(0, 3);

    myPaging.setTotalSize(stuList.size());//总数据量

}

 

]]>

 

效果图:

 

除了可以在onPaging事件上写函数之外,我们还可以使用下面的代码来为Paging组件添加事件监听器:

pagingId.addEventListener("onPaging", new EventListener() {

public void onEvent(Event event) {

……

……

……

}

};

 

 

4.2.6  Grid的排序功能

通过在column上设置属性sort,即可实现排序功能。详情请参见Listbox的排序。

 

 

4.2.7  使用grid的Model来动态展现数据

例:

"Live Grid" border="normal" width="150px">

   

       String[] data = new String[10];

       for (int j = 0; j < data.length; ++j) {

           data[j] = "option " + j;

       }

       ListModel strset = new SimpleListModel(data);

    ]]>

    "100px" model="${strset}">

      

           "options" />

      

   

效果图:

 

 

4.2.8  Grid的辅助标题(Auxiliary Headers)

除了使用columns来添加表头以外,我们还可以使用辅助表头auxhead来添加表头。

auxhead支持rowspan和colspan属性,这是column所不支持的。

columns和column只能用在grid组件里面,而auxheader、auxhead可以用在Listbox、Grid和Tree组件里面。

例:

   

      

           "H1'07" colspan="6" />

           "H2'07" colspan="6" />

      

      

           "Q1" colspan="3" />

           "Q2" colspan="3" />

           "Q3" colspan="3" />

           "Q4" colspan="3" />

      

      

           "Jan" />

           "Feb" />

           "Mar" />

           "Apr" />

           "May" />

           "Jun" />

           "Jul" />

           "Aug" />

           "Sep" />

           "Oct" />

           "Nov" />

           "Dec" />

      

      

          

             

             

             

             

             

             

             

             

             

             

             

             

          

      

   

效果图:

 

 

4.2.9  使用span属性来合并单元格

例:

    "500px">

      

           "Left" align="left" width="150px"/>

           "Center" align="center" width="150px"/>

           "Right" align="right" />

           "Column 4" />

       

      

          

             

             

             

             

          

           "1,2,1">

             

             

             

          

           "3">

             

             

          

           ",,2">

             

             

             

          

          

             

                 

                 

[微软用户1] 

             

                 

                 

效果图:

 

 

4.2.10  Grid组件的常用属性

属性名

说明

sizedByContent

根据内容改变大小。取值:true、false

一般与span=”true”连用。例如:

"true" span="true" width="800px">

span

当设置了sizeByContent后,每一列都只会占用它需要的宽度。如果我们想每一列都看起来宽松一点的话,就可以设置span=”true”

emptyMessage

当展现的内容为空时,就会显示我们设置的emptyMessage中的内容。

例如:"test1" emptyMessage="没有相关数据">

sizable

columns组件的属性,设置sizable=”true”后,用户就可以使用鼠标来更改列宽。例如:"true">

 

 

4.2.11  Grid表头上的弹出菜单:Menuepopup

默认情况下menuepopup被设置成none,我们可以在columns组件上设置menuepopup=”auto”来显示一个默认的弹出菜单。你也可以为组件设置自己定义的弹出菜单。

①  默认的Menuepopup:

例:

    "300px">

       "auto">

           "第一列" />

           "第二列" />

      

      

          

             

             

          

          

             

             

          

          

             

             

          

      

   

效果图:

 

鼠标移上点击→

(勾选的列即为显示出来的列)

 

 

②  自定义的Menuepopup

例:

    "editPopup">

        "Group" image="/imgs/sml1.gif"/>

        "Sort Ascending" image="/imgs/sml2.gif"/>

        "Sort Descending" image="/imgs/sml3.gif"/>

   

    "300px">

       "editPopup">

           "第一列" />

           "第二列" />

      

      

          

             

             

          

          

             

             

          

          

             

             

          

      

   

效果图:

 

 

4.2.12  Grid中Detail组件的使用

detail组件是用来展示详情部分,主行和详情部分在同一行上。

例:

   

       "min" />

       "productName"/>

       "Price"/>

       "Item Location"/>

   

   

      

           "true">

             

                  "myimg" width="100px" height="100px"

                     src="/imgs/tea1.gif" />

                  这里面可以有其他的组件来展示详细信息。也可以直接使用文字来描述……

             

          

          

          

          

      

   

效果图:

展开时:

 

收拢后:

 

 

 

4.2.13  foot组件

用来显示grid的foot。

例:

"300px">

   

       "Type" width="50px" />

       "Content" />

   

   

      

          

           "99%" />

      

      

          

          

              "1" mold="select">

                  "Java Files,(*.java)" />

                  "All Files,(*.*)" />

             

              

效果图:

 

 

 

4.2.14  Grid中使用Group组件分组

支持groupfoot。

例:

    "800px">

       "true">

           "Brand" />

           " Processor Type " width="150px" />

           "Memory (RAM)" width="120px" />

           "Price" width="100px" />

           "Hard Drive Capacity" width="150px" />

      

      

           "Dell" />

          

             

             

             

             

             

          

          

             

             

             

              

             

          

          

             

             

             

             

             

          

           "Compaq" />

          

             

             

             

             

             

          

          

             

             

             

             

             

          

           "5">

             

          

      

   

效果图:

收起来:

 

 

 

4.3  List组件

相关子组件:listbox、listitem、listcell、listhead、listheader

listbox组件可以用来展示列表数据。用户可以选中列表数据中的某一条记录。

listbox的mold:default、select、paging。

如果我们使用mold=”select”,那么它将被解析成HTML的select标签。

 

4.3.1  List组件概观

例1:

"listbox demo" border="normal" width="250px">

    "box">

       "true">

           "name" sort="auto" />

           "gender" sort="auto" />

      

      

           "Mary" />

           "女" />

      

      

           "John" />

           "男" />

      

      

           "Jane" />

           "女" />

      

      

          

             

          

          

             

          

      

   

效果图:

 

4.3.2  mold为select的lisbox

当listbox的mold属性为select时,可以作为一个下拉框来使用。

例:

    "select" rows="1" width="70px">

       "Car" />

       "Taxi" />

       "Bus" selected="true" />

       "Train" />

   

效果图: →  

 

 

4.3.3  listbox的常用属性

属性名

说明

sizedByContent

根据内容改变大小。取值:true、false

一般与span=”true”连用。例如:

"true" span="true" width="800px">

span

当设置了sizeByContent后,每一列都只会占用它需要的宽度。如果我们想每一列都看起来宽松一点的话,就可以设置span=”true”

emptyMessage

当展现的内容为空时,就会显示我们设置的emptyMessage中的内容。

如:"test1" emptyMessage="没有相关数据">

sizable

listhead组件的属性,设置sizable=”true”后,用户就可以使用鼠标来更改列宽。例如:"true">

 

 

4.3.4  listbox的分页

同grid组件类似,只要在listbox组件上加上属性mold="paging" pageSize="n"即可。如果不指定pageSize,则会使用默认值20。

 

 

4.3.5  listbox的自动排序功能

我们通过listheader上的sort属性来实现listbox的自动排序。默认情况下的设置为sort=”auto”。它能对这一列所展示的字符串进行自动排序。如果我们想自定义的控制,根据指定的字段来排序,可以使用sort="auto(field1[,field2...])"的格式来指定。

①  默认的排序功能

例:

    "400px" mold="paging" pageSize="2">

       "true">

           "序号" sort="auto" hflex="min"/>

           "名字" sort="auto" />

           "性别" sort="auto" />

      

      

           "1" />

           "Mary" />

           "女" />

      

      

           "2" />

           "John" />

           "男" />

      

      

           "3" />

           "Jane" />

           "女" />

      

   

效果:

 

 

②  根据指定的字段来排序,使用sort="auto(field1[,field2...])"的格式

例:

"Test auto(FIELD_NAME1,FIELD_NAME2)" border="normal" width="300px">

   

   

       class Person {

           private String firstName;

           private String lastName;

           private int age;

   

           public Person(String firstName, String lastName, int age) {

              this.firstName = firstName;

              this.lastName = lastName;

              this.age = age;

           }

           public String getFirstName() {

              return firstName;

           }

           public String getLastName() {

              return lastName;

           }

           public String getFullName() {

              return firstName + " " + lastName;

           }

           public int getAge() {

              return age;

           }

       }

       java.util.List persons = new java.util.ArrayList(8);

       persons.add(new Person("Tom", "Yeh", 43));

       persons.add(new Person("Henri", "Chen", 43));

       persons.add(new Person("Jim", "Yeh", 39));

    ]]>

   

    "@{persons}">

      

           "Full Name"

              sort="auto(lastName, firstName)" />

           "Age" sort="auto(age)" />

      

       "@{each=person}">

           "@{person.fullName}" />

           "@{person.age}" />

      

   

效果图:

 

 

4.4  Tree组件

tree组件可以实现与listbox相似的功能。但是我们通常都是用tree组件来做树状的菜单。这里不做过多介绍。

 

请看下面的例子:

"main" width="100%" height="100%" border="none">

"200px" splittable="true" flex="true" collapsible="true" title="功能菜单">

"tree" zclass="z-dottree" width="150px" rows="100">

   

      

          

              "/imgs/menu.png"/>信息汇总

          

          

             

                 

                     "/imgs/menu.png"/>基本信息

                 

                 

                    

                        

                            "/imgs/menuitem.png"/>班级信息

                        

                    

                    

                        

                            "/imgs/menuitem.png"/>学生信息

                        

                    

                    

                        

                            "/imgs/menuitem.png"/>我的信息

                        

                     

                 

             

         

      

   

 

效果图:

 

 

 

4.5  开发中的ZK常用组件

4.5.1  A组件

例1:

"http://www.zkoss.org" label="Visit ZK!" image="/imgs/gear1.gif">

   

      

           What ever content

      

   

"http://www.zkoss.org" label="Visit ZK!"/>

"../../grid/paging.zul" label="Visit Grid Demo!"/>

效果图:

a组件中的路径都是相对路径。如果路径是以斜杠(/)开头,那么则表示是当前的context path(上下文路径)。其他的路径都是相对于文件本身的路径而言的。

a组件可以包含其他的组件,但是它的子组件也要能处理鼠标点击事件。

 

 

4.5.2  Button组件

按钮组件有两种类型,button和toolbarbutton,它们的主要功能是类似的,只是其外观显示不同。

在解析时,button组件使用html中的button标记,而toolbarbutton则使用的是html中的a标记。

①  button组件的属性

属性名

说明

label

指定按钮上的文字

image

为按钮指定图像

dir

用于控制图像和文字哪个显示在前面,默认是图像显示在前面。

若dir="reverse"则文字显示在前面

orient

控制布局是横向还是纵向,默认是横向布局。

orient="vertical"则为纵向布局

onClick

按钮被点击后进行的响应

href

按钮被点击后跳转的页面

mold

取值有:default、trendy、os

autodisable

通过设置这个属性,可以防止重复提交。

例:

效果图:

如果在按钮的id前面加上加号(+),则点击一次后被指定的按钮将变成disabled,需要我们手动变回enabled;如果不加+,则点击时的这次request完成以后,按钮将自动从disabled变成enabled

 

 

② 配置button默认的属性

在zk.xml中做如下设置,则可以使按钮的默认mold变成trendy:

    org.zkoss.zul.Button.mold

    trendy

 

在zk.xml中做如下设置,则可以使按钮的autodisable指向它自身:

   

        button

        button

       

            autodisable

            self

       

   

 

 

③  button上面使用图片

例1:

"按钮应用" border="normal" width="40%">

效果图:

 

④  按钮的onClick与href属性

我们可以通过两种方式为一个按钮指定动作:一是通过onClick来监听;二是使用href来指定一个路径。这两种方式中,href的优先级要高于onClick。如果同时指定两者,则onClick不会被发送。

 

⑤  使用html中的button标签

通过指定xml命名空间为native,则ZK解析器会按照html的格式来解析这个命名空间下的组件。(很少用)

例:

(实际应用中,我们可以使用下面的代码跳转到一个jsp页面,或者一个actoin中,等等)

 

 

 

 

4.5.3  验证码Captcha

例:

    验证码:"tb" value="请输入" onFocus='self.setValue("")' onBlur="check()"/>

    "cpa" length="5" width="200px" height="50px" />

   

       void check(){

       if(!tb.getValue().toLowerCase().equals(cpa.getValue().toLowerCase())){

              Messagebox.show("请输入正确的验证码");

              tb.setValue("请输入");

           }

       }

    ]]>

   

效果图:

 

 

4.5.4  combobutton组件

combobutton是一种特殊的按钮,它里面可以包含一个popup或者menuepopup做为child

例:

    "popup" image="/imgs/sml3.gif" autodrop="true">

      

          

             

                  Search

                 

             

              "200px">

                 

                     "Name" />

                     "Description" />

                 

                 

                     "John" />

                     "CEO" />

                 

                 

                     "Joe" />

                     "Engineer" />

                 

             

          

      

   

 

    "menu popup" image="/imgs/sml2.gif">

      

           "Index" />

          

"Menu">

             

                 

"Color Picker" content="#color=#029BCB" />

             

          

      

   

   

autodrop属性用于设置鼠标滑过时是否自动打开弹出框。

效果图:

 → →

 

 

 

4.5.5  Fisheye组件

例:

   

"450px">

       "Attach icon edge at bottom"

           onCheck='fsb.attachEdge=self.checked?"bottom":"top"' />

       "Vertical orient"

           onCheck='fsb.orient=self.checked?"vertical":"horizontal"' />

       "true" />

       "fsb"

           style="position:absolute;margin:80px 150px;" attachEdge="top"

           itemWidth="80" itemHeight="80" itemMaxHeight="160"

           itemMaxWidth="160">

          

              image="/imgs/button04.jpg"

              label="folder" onClick="alert(self.label)" />

          

              image="/imgs/button05.jpg"

              label="search" onClick="alert(self.label)" />

          

              image="/imgs/button06.jpg"

              label="project" onClick="alert(self.label)" />

          

              image="/imgs/button08.jpg"

              label="Email" onClick="alert(self.label)" />

          

              image="/imgs/button21.gif" label="Globe"

              onClick="alert(self.label)" />

          

              image="/imgs/button23.gif"

              label="telescope" onClick="alert(self.label)" />

      

   

效果图:        →

 

 

 

4.5.6  HTML组件

如果我们要在页面上直接使用html标签而不让zk的解析器来解析,那么我们就可以使用html组件。配合一起使用。

注意:html组件中的内容不是这个组件的child。我们可以在里面使用EL表达式

例:

"win" title="Html Demo" border="normal">

    

        

Hi, ${win.title}

        

It is the content of the html component.

     ]]>

效果图:

 

 

4.5.7  Iframe组件

iframe组件和HTML中的ifram标签的功能相同。

iframe组件和include组件很相似,但是它们有很大的不同:

◆ include包含进来的子页面是属于当前的页面的,也就是属性当前desktop的一部分。我们可以直接访问include包含进来的组件。包含的动作是在server端,browser对此一无所知。

◆ iframe包含进来的子页面是作为一个单独的页面来加载的。包含的动作发生在browser端。

例:

"win" title="This is an Iframe Demo!">