You can think of ZK as being analogous to Ajax without JavaScript. It is composed of an Ajax-based, event-driven engine, a rich set of XHTML and XUL components, and a mark-up language called ZUML, which is used for creating feature-rich user interfaces. The business logic can be written through Java code directly integrated into your application, and which is triggered based on events or components. The most powerful feature of ZK is its rich set of control libraries for user interface development. Sound interesting?
First, let me describe the previous terms in a little more detail:
- XHTML: Extensible Hypertext markup language, or
XHTML, is combined HTML and XML. XHTML adds the power and flexibility
of HTML with the extensibility of XML. Listing 1 provides an example
of XHTML code.
Listing 1. XHTML example code<?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd"> <html xml:lang="en" lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Hello ZK</title> </head> <body> <h1>Introducing XHTML</h1> </body> </html>
- XUL:
XML User Interface language, or XUL, (pronounced as "Zool") is a
mark-up language developed by Mozilla, and is an XML application used
to describe graphical user interfaces. XUL has the ability to create
elements such as input controls, toolbars, menus, trees, keyboard
shortcuts, and so on. Listing 2 shows an example of XUL code.
Listing 2. XUL code sample<?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin/" type="text/css"?> <window id="main" title="My App" width="300" height="300" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <caption label="Hello World"/> </window> - ZUML:
ZK User Interface Markup Language, or ZUML, is used for defining the
rich user interface. Because it's based on XML, each element describes
the component, and the attribute describes the component value.
Listing 3 gives an example of ZUML code.
Listing 3. ZUML code sample<window title="Hello ZUML" border="normal"> Hello World! </window>
Obtaining and installing ZK is quite easy. The documentation on the libraries and setting up the folder structure has been defined very nicely on the ZK documentation site. (See Resources for a link.) So, getting ZK, including running the hello world application, should be simple.
ZK is a direct Ajax implementation—or in other words, a server-centric model. This is unlike other frameworks that expose you to the painful details of making Ajax calls. Additionally, Ajax calls require extensive use and knowledge of JavaScript for manipulating the Document Object Model (DOM) on the browser (client) and synchronizing data during client/server communication. ZK shields you from these complexities and lets you focus on the business logic. Other benefits of ZK include:
- Rich set of user interfaces
- Web service access
- Component data binding
- Simple, but powerful, mark-up language, ZUML
- Highly maintainable and extensible because there is no client code
- High usability
- Improved developer productivity
To understand how ZK works, let's look at a real-world example. This example is a manage customer application through which the user can perform various operations such as adding a new customer, editing the customer data, and soft deletions of the customer entries in the database. But, before diving into the code, I'll explain a few user interface screens that have been generated using ZK. After looking at the screens, I'll describe the architecture of ZK, which is the underlying engine for generating this impressive UI. Finally, I'll describe the code level details along with the configuration parameters used for this application.
Figure 1 shows the initial screen of the manage customer application.
Figure 1. Manage customer index page

Figure 1 shows the list of customers registered within the
application. The list is shown as a grid, with columns for an ID, the name
of the customer, the active date, and the deleted flag. The data in the
grid can be sorted (in either ascending or descending order) by clicking
the button near the column names. Sorting has been enabled for the ID
(int), Name (String), and active date (Date) column. Later in this
article, I'll explain how to customize the sorting using a Comparator object. Pagination has also been
enabled for this application, as shown at the bottom of the screen. The
page is enabled to show 5 records at a time, along with the ability to
move to the next page or directly to a specific page.
Figure 2. The top menu bar
Figure 2 shows the top bar of the manage customer application. This is implemented using the menubar widget of ZK. It includes an option to register a new customer and exit the application.
Now that you have looked at a couple of user flows of the sample application, let's jump into the architectural details of ZK.
A ZK application behaves similar to a desktop application in that the user activities automatically fire events on the server through the Client Engine. In turn, the components running on the server update the view to match that of the client. The client (browser) just acts as a view, while the application runs on the server and has complete access to resources like databases, Web services, and so on. Consequently, security concerns are minimal.
There are three major components within a ZK framework. As shown in Figure 3, these components are the ZK Client Engine, the ZK Loader, and the ZK Update Engine.
- ZK Client Engine: This is the client side of ZK, which sends requests to the server to get corresponding ZK responses. These responses, in turn, are used by the engine to update the DOM within the browser.
- ZK Loader: This component generates an HTML page based on a URL that is requested by the client.
- ZK Update Engine: This is also known as the Asynchronous Update (AU) Engine. This component is responsible for receiving the Ajax request and updating the corresponding attributes in the ZK component so the Client Engine can update the view on the browser.
Figure 3. The ZK architecture

The mechanism of the flow as described in Figure 3 is as follows:
- The ZK Loader serves the HTML, including the CSS, JavaScript, and so on, based on the URL requested by the client. This includes the ZK Client Engine, which is responsible for monitoring the client-side events and sending and receiving the ZK Requests and ZK Responses to the server.
- The Client Engine triggers events
based on the user's actions like
onChange,onClick, and so on. - These events invoke the ZK Update Engine, which updates the properties of the ZK components and responds to the Client Engine.
- After receiving this response the Client Engine updates the DOM tree within the browser so that the user can see this updated view.
Next, I'll move on to describing the details of creating a sample application to manage customers. I use the Eclipse IDE to demonstrate the application's creation, but any IDE of your choice should work.
The basic idea is to create a dynamic Web application project and point it to the application server runtime, which in this case is the Apache Tomcat runtime.
After setting up the new project and the runtime, replicate the folder structure as shown in Figure 4.
Figure 4. The directory structure
The directory structure of the manage customer application follows the same pattern directory structure as described in Figure 4.
Note that the core of the files for this application are contained within the WebContent folder. Within the WebContent folder I have the following subdirectories:
- META-INF – This contains the database credential information for connecting to the MySQL database.
- WEB-INF – This includes the library folder containing the ZK JAR files required for running the application. It also includes the web.xml file, which describes the datasource.
- In addition, all the associated zul and HTML files are contained within the WebContent folder. These files serve as the view part of the application, providing the dynamic and static content to the Web app.
The sample file zkManageCustomer.zip (see Download) contains the zipped version of the application. It also includes the metadata files required by Eclipse so that it can be imported directly into that IDE seamlessly.
The Java 2 Platform, Enterprise Edition (J2EE) perspective in Eclipse has a server tab, which when right-clicked shows the user an option of creating a new server. This server can be used to manage the application server from the Eclipse IDE.
After the new server is configured, the newly created resources need to be configured on the server. This server configuration deploys the resources that are created during the course of development.
Configuration of Tomcat and MySQL
The example program is configured to work with Tomcat and MySQL. However, you should have no trouble getting it to run in another Java application server, including WebSphere. Since the example uses JDBC, it should work with any supported SQL database, such as DB2 Express-C with only minor changes to the connection code.
To connect
Tomcat to the MySQL database you need to define a resource reference. This
element specifies the name of a resource manager connection factory
reference. In this case, it would be the database connection specified by
jdbc/mysql, which is of javax.sql.DataSource
type.
Listing 4. Resource manager connection factory in web.xml
. . . <resource-ref> <description>DB Connection</description> <res-ref-name>jdbc/mysql</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> . . . |
You also need to define a connection resource in the context.xml file under the WebContent/META-INF folder. This file contains properties such as the driver name, jndi name, username, password, datatype, and the URL.
Listing 5. Context definition in context.xml
. . . <Context> <Resource driverClassName="com.mysql.jdbc.Driver" maxActive="4" maxIdle="2" maxWait="5000" auth="Container" name="jdbc/mysql" password="" type="javax.sql.DataSource" url="jdbc:mysql://localhost:3306/customer" username="root"/> </Context> . . . |
The customer database has a single table that can be created by running the script shown in Listing 6.
Listing 6. Script to create database
use customer; CREATE TABLE `customer` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `date` date DEFAULT NULL, `deleted` tinyint(1) DEFAULT '0', PRIMARY KEY (`ID`) ); |
Adjusting the application to work with DB2
To connect Tomcat to a DB2-Express C or another DB2 variant database the configuration is very similar to the one described for MySQL. Here is an example showing configuration of the resource manager connection factory in web.xml: . . .
Listing 7. Resource manager connection factory in web.xml
. . . DB Connection jdbc/db2db javax.sql.DataSource Container . . . |
For the context definition, a typical example would be as follows: . . .
Listing 8. context definition
. . . maxActive="4" maxIdle="2" maxWait="5000" auth="Container" name="jdbc/db2db" password="" type="javax.sql.DataSource" url="jdbc:db2://localhost:(port)/customer" username="db2admin"/> . . . |
A brief description of the application was presented previously in this article. The manage customers application provides the functions of:
- Dashboard page enabling user operations, including a view of all customers
- Adding new customers
- Editing existing customers
- Enabling the deletion of customers (Soft delete)
Figure 5 shows the dashboard page of the application. The default view shows the list of customers in the database.
Figure 5. The dashboard screen

The dashboard screen shows a list of all the registered customers. Along with the list of customers, the user also has the ability to sort the data on the basis of either the ID or the Name.
The index.zul
file has various attributes such as borderlayout, menubar, menu, and menupopup,
all of which define the look and feel of the application.
Listing 9. index.zul file
<menubar id="menubar" width="800px">
<menu label="Manage Customers">
<menupopup>
<menuitem label="Register New Customer">
<attribute name="onClick"><![CDATA[
Window win = (Window) Executions.createComponents("addCustomer.zul", null, null);
win.doModal();
win.setTitle("Enter Customer Data");
win.setClosable(true);
win.setMaximizable(true);
]]></attribute>
</menuitem>
<menuseparator />
<menuitem label="Exit" onClick="win.detach()" />
</menupopup>
</menu>
</menubar> |
As
shown in Listing 9, I have defined a menubar
with a menu label for registering new customers. When this menu is clicked
(onClick) I instantiate a Window object through the
Executions object using another zul called addCustomer. I also set the attribute for making the dialog
modal, closable,
and so on. In addition, I include an exit menu that closes the
application. The menubar, along with the
defined attributes, gives this application a rich-client look and feel.
Listing 10 shows how the table is populated using a listbox element, where I define a model based on
which table element is
populated.
Listing 10. Sample listbox element defining the table
<listbox id="customerList" model="@{myList}" mold="paging" pageSize="5"
multiple="true" width="800px" rows="${custCount}">
<listhead sizable="true">
<listheader label="Id" sort="auto(id)"/>
<listheader label="Name" sort="auto(name)"/>
<listheader label="Active Date" sort="auto(date)"/>
<listheader label="Deleted?" />
</listhead>
<listitem self="@{each=myList}" onClick="showEdit(self.getLabel())">
<listcell label="@{myList.id}" />
<listcell label="@{myList.name}" />
<listcell label="@{myList.date}" />
<listcell label="@{myList.deleted}"/>
</listitem>
</listbox> |
The
paging function can be activated using the mold
attribute of listbox. Additionally, the sorting
based on the column headers can be defined by enabling auto on the sort attribute of the listheader. The myList object is a
list of Customer objects, which are composed of
attributes such as id,
name, date, and the deleted flag of the Customer. The service returns
this list, which is then iterated by ZK through the "each =myList". The listcell labels
then show each attribute of the customer object in the listbox.
Also, for enabling the edit function I attach a
showEdit method to the onClick event.
The register customer dialog is implemented as a grid with mandatory values for the Customer name and Date.
Listing 11. Customer dialog grid code
<grid fixedLayout="true" width="450px"> <rows> <row> <label value="Customer Name" /> <textbox id="customerName" constraint="no empty" /> </row> <row> <label value="Date" /> <datebox id="date" constraint="no empty"/> </row> <row> <button label="Save" onClick="submit()" /> <button label="Cancel" onClick="addCustomerWin.detach()" /> </row> </rows> </grid> |
The
constraints of mandatory for the dialog is specified using "no empty" as the constraint attribute. ZK also
gives you the ability to define custom constraints.
When the Save
button is clicked I attach a Java method called submit() to this event. This submit() method receives the name and date value supplied by
the user and sets it in a newly created customer object. This object is
then passed to the service for adding to the database. Listing 12 shows
this code.
Listing 12. Java code for the Save button
void submit() throws Exception {
Customer cust = new Customer();
cust.setName(customerName.getValue());
java.util.Date utilDate = date.getValue();
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
cust.setDate(sqlDate);
com.test.services.CustomerService custSvc = new com.test.services.CustomerService();
custSvc.addCustomer(cust);
Executions.getCurrent().sendRedirect("index.zul");
addCustomerWin.detach();
} |
Figure 6. Register customer
Figure 7 shows a screen to edit the customer's name or date, along with a soft delete option.
Figure 7. Edit/Delete screen
The mechanism to edit is very similar to how you set the register customer code. You pass the new values of name, date, and the deleted flag to the update service for updating the record in the database. If you want to set up additional help, you can use the code in Listing 11 to create a pop-up element.
Listing 13. Code for pop-up element
<row>
<label value="Delete?"/>
<hbox>
<checkbox id="deleted" name="deleted" checked="${cust.deleted}"/>
<label value="whats this?" style="font:9;cursor:help;valign:center"
popup="help"/>
</hbox>
<popup id="help" width="400px">
<html>Checking this box will enable soft delete of the record.</html>
</popup>
</row> |
The great advantages of ZK are its tools. One example is ZK-Studio (an Eclipse plug-in), which is used as an integrated development environment. It includes features like the ZUL editor, the ZUL Visual editor, the ZK Style designer, and the DB Form builder. Figure 8 shows the ZUL Visual editor, which was used for the creation of this sample project.
Figure 8. ZUL Visual Editor
This article described features of ZK, an open source Ajax framework written in Java code. The article used a simple real-world example running on Apache Tomcat and connecting to a MySQL database. The ZK framework has a rich set of components, a mark-up language, powerful development tools, and great documentation, along with being open source and an event-driven Ajax framework. Because of all this, ZK is becoming a popular choice for developing low-cost, rich Internet applications.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample application | zkManageCustomers.zip | 67KB | HTTP |
Information about download methods
Learn
- Read the documentation for ZK
on the project site.
- Try live demos of applications using
ZK.
- Read about more
techniques in the ZK Developer Guide.
- Read the ZK Studio
documentation to learn more about ZK Studio's
features.
- The Getting started with XULRunner explores the Mozilla platform by
showing a basic desktop application using XULRunner.
- Download DB2
Express-C. It's free, but with the internal power of
DB2.
Get products and technologies
- See the ZK Open source Ajax project site.




