New Features of ZK 3.0 RC

From Documentation
DocumentationSmall Talks2007SeptemberNew Features of ZK 3.0 RC
New Features of ZK 3.0 RC

Author
Robbie Cheng, Engineer, Potix Corporation
Date
September 14, 2007
Version


The ZK team proudly presents you ZK 3.0 RC. It includes a lot of new features, more integrations with other components/frameworks, and the most important of all is the performance improvement - four ~ five times faster than ever! (See the report).

Don't hesitate! It's time to test drive!

In the following paragraphs, I'll introduce the most exciting new additions to ZK 3.0 RC.


Ease of Use

For ease of use, ZK provides server push which allows you to update client’s information more easily. In addition, the new property - forward - which allows you to forward event to other components without much effort. Moreover, the new expression of annotation is more intuitive and easy-to-read. Let's check it out!

Server Push

This is so-called reverse-Ajax which allows the server to send content to the client actively. ZK now supports server push implemented using client-polling technique. To use server push, the only two things you have to do are enabling server push, and starting your working Thread, and the rest of work will be finished by ZK. Let’s take a look at a real example below. For example, if you want to update the number of the client constantly. First of all, you have to enable server push for the desktop and to invoke the thread as follows,

<window title="Demo of Server Push">
<zscript>
  import org.zkoss.zkdemo.test.WorkingThread;
  WorkingThread thread;
  
  void startServerpush(){
	desktop.enableServerPush(true);
	thread= new WorkingThread(info).start();
  }
  void stopServerpush(){
	thread.setDone();
	desktop. enableServerPush(false);
  }
</zscript>
 <vbox>
 <button label="Start Push" onClick="startServerpush()"/>
 <button label="Stop Push" onClick="stopServerpush"/>
 <label id="info"/>
 </vbox>
</window>


Furthermore, to avoid the condition that a desktop might be accessed by multiple threads at the same which might cause the problem of synchronization. Thus, before accessing the desktop, you have to invoke Executions.activate(Desktop desktop) to get full control of the desktop, then release the control of the desktop by invoking Executions.deactivate(Desktop desktop) after the thread finishing its job as follows,

public class WorkingThread extends Thread {
 private final Desktop _desktop;
 private final Label _info;
 private int _cnt;
 private boolean _ceased;
 public WorkingThread(Label info) {
  _desktop = info.getDesktop();
  _info = info;
 }
 public void run() {
  try {
   while (!_ceased) {
	Threads.sleep(2000); //Update each two seconds
	Executions.activate(_desktop);
	try {
	 _info.setValue(Integer.toString(++_cnt));
	} catch (RuntimeException ex) {
	 throw ex;
	} catch (Error ex) {
	 throw ex;
	} finally {
	 Executions.deactivate(_desktop);
	}
   }
  } catch (InterruptedException ex) {
  }
 }
 public void setDone(){
  _ceased = true;
 }
}

In this example, the content of label will be updated by the Thread constantly until it is stopped. For more information, please refer to this small talk: Simple and Intuitive Server Push with a Chat Room Example

Foward Property

In the past, we usually register an event listener using zscript and specify related actions within it. This is simple and intuitive but the drawback of it is lower performance because of using zscript requires additional execution time for the interpreter (e.g. BeanShell).

Now, in ZK 3.0 RC, we provide a new property of components—forward—which allows you to forward events to other components to get rid of zscript. Please take a look at the following example. A window usually consists of several buttons, menu items and other controls. For example,

<window use="MyWindow">
...
<button label="OK"/>
<button label="Cancel"/>
</window>


When the user clicks the button, the onClick event is sent to the button itself. However, these events are better to process in the window rather than scattering around these buttons. To do that, you can use the forward attribute as follows.

<window use="MyWindow">
...
<button label="OK" forward="onOK"/>
<button label="Cancel" forward="onCancel"/>
</window>


where the forward attribute of the OK button specifies that the onClick event, if received, shall be forwarded to the space owner (i.e., the window) as the onOK event. Similarly, the onClick event targeting the Cancel button is forwarded as the onCancel event. Thus, you can handle the onOK and onCancel events in the space owner, MyWindow, as follows,

public class MyWindow extends Window {
  public void onOK() {
	//called when the OK button is clicked (or the ENTER button is pressed)
  }
  public void onCancel() {
	//called when the Cancel button is clicked (or the ESC button is pressed)
  }
}


New Expression of Annotation

In ZK 3.0 RC, we provide one more intuitive way to annotate ZK components. Let’s take a look at the classic way first.


The Classic Way

The classic way of annotation appears before the declaration of the element that you want to annotate:

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<window xmlns:a="http://www.zkoss.org/2005/zk/annotation">
  <a:bind model="persons" selectedItem="selected"/>
  <listbox rows="4">
	<a:bind _var="person"/>
	<listitem>
	  <a:bind label="person.firstName"/>
	  <listcell/>
	  <a:bind label="person.lastName"/>
	  <listcell/>
	</listitem>
  </listbox>
</window>


The More Intuitive Way

The new way of annotation allows you to annotate components more intuitively. No separate declaration of annotations are required anymore, you could specify annotations as values within components’ declarations or their properties directly as follows,

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<window>
 <listbox rows="4" model="@{persons}" selectedItem="@{selected}">
	<listitem self="@{each=person}">
	  <listcell label="@{person.firstName}"/>
	  <listcell label="@{person.lastName}"/>
	</listitem>
  </listbox>
</window>

Note: self is a keyword to denote the annotation is used to annotate the component declaration, rather than any property.


ZK Components Reloaded

In ZK 3.0rc, we implemented TreeModel, and more ZK componets, including timebox, flash components, and etc.

TreeModel

Tree model is long-awaited by the community, finally ZK supports tree model. Please take a look at the following example,

 <window>
 <zscript>
  ArrayList al = new ArrayList();
  int i=0;
  for(; i < 100000; i++)
  {
   Object obj = ""+i;
   al.add(obj);
  }
  BinaryTreeModel btm = new BinaryTreeModel(al); 
 </zscript>
  <tree model="${btm}" id="tree" >
  </tree>
 </window>

For more information, please refer to ZK Tree Model.

Timebox

In addition to Datebox, ZK now supports Timebox which allows user to choose time by hour and minutes, for more information, please refer to Using Timebox Component.

Flash Components

Now, ZK supports versatile flash components which allow you to play media files, including .swf, youtube clip, and mp3 files. For more information, please refer to New ZK Flash Based Components.

Comboitem - HTML Description

ZK allows you to enrich the description of a Comboitem with HTML as follows,

<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c" ?>

<combobox>
 <comboitem label="Simple and Rich" 
   description="The simplest way to make Web applications rich"/>
 <comboitem label="Cool!"
 description="The coolest technology">
	   <![CDATA[ <b>Bold</b> and <i>italic</i>]]>
 </comboitem>
 <comboitem label="Ajax and RIA">
	   <![CDATA[<img src="/zkau/web/zul/img/slider/btn.gif"/>ZK, the best]]>
 </comboitem>
</combobox>


or you could add HTML content by programming as follows,

new Comboitem().setContent("<b>xx</b>....");


Tabbox - Lite Look

ZK provides a "lite" look of tabbox, and you could use it as follows,

<tabbox width="400px" sclass="lite">
  <tabs>
   <tab label="Tab 1"/>
   <tab label="Tab 2" closable="true"/>
   <tab label="Tab 2"/>
  </tabs>
  <tabpanels>
   <tabpanel>This is panel 1</tabpanel>
   <tabpanel>This is panel 2</tabpanel>
   <tabpanel>This is panel 3</tabpanel>
  </tabpanels>
 </tabbox>

The layout is shown in the following figure.

Lite1.jpg


Enhancement of Data-Binding

Data binding supports validation phase which allows you to do validation in your own way.

An Alternative Way of Validation

Before 3.0 RC, while using data binding, we used to do validation of values by specify conditions in constraint attribute of ZK components. From now on, data binding provides an alternative way to do validation by posting onBindingSave event to each of binding components so that you could do validation with your customized way by registering onBindingSave event listener in these components as follows,

<intbox value="@{person.age}">
<attribute name="onBindingSave">
   if (self.value < 18)
	  throw new WrongValueException("Age below 18 is not allowed to enter this site.")
</attribute>
</intbox>


Then, after posting onBindingSave events to all of binding components to make sure their values are validated. Then, data binding will post an onBindingValidation event to the ZK component which triggers data binding to work, for example, a button.

 <button label="submit">
   <custome-attributes passed="false"/>
   <attribute name="onBindingValidation">
	  self.setAttribute("passed",true);
	</attribute>
   <attribute name="onClick">
	  if (self.getAttribute("passed") == true)
		 Executions.sendRedirect("index.zul");
   </attribute>
 </button>

Finally, after posting all events of validation phase to all related ZK components, data binding will truly save data into data bean.


Namespace Extended

ZK supports native namespace for better performance, and it allows XML output. Please take a look at the following two paragraphs.

Native Namespace

In ZK 3.0 RC, we provide a new namespace—native namespace—for mixing ZK components with HTML tags in addition to XHTML namespace. The major difference between them is whether to create ZK components at the server side or not. If you used XHTML to mix HTML tags, ZK will generate corresponding ZK components at the server. On the contrast, ZK won’t generate ZK components at the server for better performance while using Native namespace.

One thing to notice is that there is no difference between the out put of these two namespaces. If you mix HTML tags with ZK component using native namespace as follows,

	<n:ul xmlns:n="http://www.zkoss.org/2005/zk/native">
	  <n:li>
		<textbox/>
	  </n:li>
	  <n:li>
		<textbox/>
	  </n:li>
	</n:ul>


in which will generates the following HTML tags to the browser:

	<ul>
	  <li>
		<input id="z_a3_2"/>
	  </li>
	  <li>
		<input id="z_a3_5"/>
	  </li>
	</ul>

However, if you want to change the content of these HTML tags dynamically, you should use XHTML namespace instead of Native namespace. The choice is yours.


XML Output

Nowadays, XML have become the standard format of many devices and protocols, such as RSS and SVG. It is straightforward to output XML with ZK. ZK generates them directly to the output without instantiating a ZK component for each of them.

The following is an example that generates the SVG output. It looks very similar to the XML output you want to generate, except you can use zscript, EL expressions, macro components and other ZK features.

	<?page contentType="image/svg+xml;charset=UTF-8"?>

	<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
	  <z:zscript xmlns:z="http://www.zkoss.org/2005/zk"><![CDATA[
	  String[] bgnds = {"purple", "blue", "yellow"};
	  int[] rads = {30, 25, 20};
	  ]]></z:zscript>
	  <circle style="fill:${each}" forEach="${bgnds}"
	  cx="${50+rads[forEachStatus.index]}"
	  cy="${20+rads[forEachStatus.index]}"
	  r="${rads[forEachStatus.index]}"/>
	</svg>

For more information, please refer to XML Output in dev's guide.


Performance Tips

Pluggable EL Evaluator.

In ZK 3.0 RC, by making the EL evaluator pluggable, ZK gives you an option to use JSP 2.1's EL, OGNL, MVEL and others. Currently, JSP 2.0, JSP 2.1 and MVEL plugin are available in ZK. In the following example, we demonstrate you how to use MVEL to evaluate EL.

	<?evaluator name="mvel"?>
	<window id="w" title="MVEL Demo">
	  ${new org.zkoss.zul.Textbox().setParent(w)}
	</window>

You can integrate with other EL evaluator by implementing the org.zkoss.xel.ExpressionFactory interface. For more information, please refer to "The evaluator Directive" in developer's reference.


A Faster Way to Render ZK Components

In addition to DSP, JSP and any Servlet technologies, you can implement the org.zkoss.zk.util.ComponentRenderer interface, and then specify it in the moldURI attribute by starting with "class:". With this approach, the performance is improved a lot, if we can specify a class and render the component directly without going through Servlet.

	<?component name="window" extends="window" mold-name="default" 
	mold-uri="class:com.mycompany.myWindowRender" ?>

	<window title="Faster Window!" border="normal" width="200px">
	 Hello, World!
	</window>


Other Features

Other convenient features are illustrated in the following paragraphs.

A New Way to Avoid Session Timeout

In the past, a session is considered as timeout, if it doesn't receive any client request in the specified timeout interval. From now on, ZK allows you to keep a session alive by using a Timer which sends onTimer event to the server. Thus, you could specify whether to keep the session alive, when receiving the onTimer event as follows,

	<session-config>
	  <timer-keep-alive>true</timer-keep-alive>
	</session-config>


A New Way to Use TLD of DSP

Usually, if we want to use TLD in ZUL page, we have to copy those TLD files to \WEB-INF directory, and include them as follows,

 <?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>


Now, ZK provides you an easier way by including those TLDs as follows without copying those TLD files as follows,

         <? taglib uri="http://www.zkoss.org/dsp/zweb/core" pefix="c" ?>


Integration with Other Frameworks

JSF

JSF (JavaServer Faces) is a technology used for building user interfaces for JavaServer applications. Now, ZK provides a set of JSF components which wrap ZK components, and implement the features of JSF like ValueBinding, Converter, Validator, etc. For more information, please refer to this smalltalk, Enrich Your JSF Applications with ZK Today!

JSP

This is great news for developers and companies who want to bring rich interface to their legacy JSP applications with ZK. Here, ZK introduces you a JSP tag library of ZK which allows you to integrate ZK components into your JSP pages using JSP tags. For more information. please take a look at the following smalltalks, Use ZK JSP Tags in Your JSP Pages, ZK JSP Tag Lib Support Initiator and Annotation

Ext-JS

Yui-Ext-- now called Ext JS, is a world famous client-side, JavaScript library for building web applications. However, using Yui-Ext JavaScript library with server side Java code is very complicated. But don't worry, ZK framework will as always do the complicated part for you. There are many useful and amazing widgets and functions, please refer to the following smalltalks, Integrating Yui-Ext into ZK Framework, New Features of yuiextz 0.5.1., Y-Grid Support Drag-Drop and DataBinding, Enrich the Layout of ZK with Ext JS




Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.