New Features of ZK 2.4.1
Tom M. Yeh and Henri Chen, Potix Corporation
July 6, 2007
Applicable to zk-2.5.0-FL-2007-07-12 and later.
- Applicable to yuiextz 0.5.1.
ZK 2.4.1 focuses mainly on fixing bugs and performance improving. In addition to over 20 bug fixes, there are 14 new features. In this article, we'll introduce the most exciting new additions to ZK 2.4.1.
Tree Controls with Paging
Since 2.4.1, tree controls introduced the pageSize property to control the number of tree items to display at once. By default, it is 10. That is, at most 10 tree items are displayed at the client for each level as depicted below.
A user can click to see more tree items (i.e., enlarge pageSize), or click or to scroll up and down.
If you want to display all tree items, simply set pageSize to -1.
<tree pageSize="-1"> ...
However, it is not recommended if the tree control is huge, since the browser is too slow to handle a tree with huge number of items.
In addition to the pageSize property of a tree control, you can change the page size of each treechildren instance by modifying the pageSize property of the corresponding treechildren instance.
<tree> <treechildren> <treeitem> <treerow/> <treechildren pageSize="20"/> ...
Not to Disable HTML Tags under Modal Windows
To turn off this feature, you have to specify the following in /WEB-INF/zk.xml.
<desktop-config> <disable-behind-modal>false</disable-behind-modal><!-- default: true --> </desktop-config>
The side effect is that a user may use the TAB or shift-TAB key to move the focus to a component that shall be disabled. Notice that, no matter this feature is turned on or not, the user is always prevented from clicking any component that doesn't belong to the modal window.
Notice: this side effect may be as worse as it looks like. After all, almost all Ajax solutions DO NOT disable the HTML tags behind the modal windows.
Customize the Generation of UUIDs
By default, UUIDs of components and desktops are generated completely dynamic and unpredictable. Thus, the browser won't access a wrong desktop accidentally even if the server is restarted.
However, as suggested by Lin Li at the forum, it will be impossible to use the run-of-the-mill record-and-replay testing tools on ZK applications. ZK 2.4.1 introduced a plugin to let developers provide a customized implementation of the UUID/ID generation.
To specify your own implementation of the UUID/ID generation, you have to specify the following in /WEB-INF/zk.xml:
<system-config> <id-generator-class>my.MyIdGenerator</id-generator-class> </system-config>
ThreadLocal Variables Synchronization
By default, ZK spawn a new thread to handle each new event. It thus supports the flexibility of suspending and resuming event handling codes at your will. The Messagebox and modal window are acctually implemented based on this threading mechanism. However, when using with some other frameworks (e.g. Hibernate and Spring), incompatibilities start to occur. For example, Hibernate keeps its "current" Hibernate session inside a ThreadLocal variable "context" of its org.hibernate.context.ThreadLocalSessionContext class. The "current" Hibernate session could be created in Servlet thread and expected to be referenced in the following operations. Now since ZK spawn a new thread for event handling, that "current" Hibernate session is not there any more and program hits the "bump".
We used to solve this issue by implementing the org.zkoss.zkplus.hibernate.HibernateSessionContextListener class (see this smalltalk). We also implemented this org.zkoss.zkplus.spring.SpringTransactionSynchronizationListener class to handle the thread incompatible issues between Spring and ZK. This kind of implementation can go on without ending. Recently, Marcos de Sousa reported a bug regarding Spring's session scoped variables that hits the incompatibility "bump" again. We can go on and implement another specific "Listner" to handle this issue? Or shouldn't we resolve this kind of issues once and for all?
Here is our "once and for all" solution: org.zkoss.zkplus.util.ThreadLocalListener. You specify this ThreadLocalListener and tell it what ThreadLocal variables should be handled and it will do the job for you. Just specify the following in /WEB-INF/zk.xml:
<listener> <description>ThreadLocal Variables Synchronizer</description> <listener-class>org.zkoss.zkplus.util.ThreadLocalListener</listener-class> </listener> <preference> <name>ThreadLocal</name> <value> class1=field11,field12,...; class2=field21,field22,...; ... </value> </preference>
The "classX" is the full class name where the ThreadLocal variables are defined while the "fieldX" is the ThreadLocal variable name itself. For example, you can specify as following to do the same thing as what org.zkoss.zkplus.hibernate.HibernateSessionContextListener class did.
<listener> <description>ThreadLocal Variables Synchronizer</description> <listener-class>org.zkoss.zkplus.util.ThreadLocalListener</listener-class> </listener> <preference> <name>ThreadLocal</name> <value> org.hibernate.context.ThreadLocalSessionContext=context; </value> </preference>
ThreadLocalVariableListener will handle the value synchronization of the ThreadLocal variable "context" of the org.hibernate.context.ThreadLocalSessionContext class between Servelet thread and event thread automatically.
ZK 2.4.1 compresses the output of the ZK loader and filter if the browser supports the gzip compression. It improves the transmission over the slow Internet connection dramatically. However, if you post-process the output of the ZK loader or filter, the compression might not be applicable. For example, you may use your own filter to do the compression. Then, you might have to remove your own filter, or configure ZK not to compress the output.
To disable the compression, you have to specify the compress parameter in WEB-INF/web.xml as follows.
<servlet> <servlet-name>zkLoader</servlet-name> <servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class> <init-param> <param-name>update-uri</param-name> <param-value>/zkau</param-value> </init-param> <init-param> <param-name>compress</param-name> <param-value>false</param-value> </init-param> </servlet>
|Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.|