Single Page


Trilogy of Component Development

From development perspectives, there are three steps to implement a ZK component. First, you have to design the view. Second, you have to implement the handle (as a Java class) at the server. Finally, you have to configure it with a XML file, such that it is accessible to the applications.

How to implement the view depends on the client technology. For example, HTML tags and Java codes are required for the Ajax browsers, while Java MIDlet is required for Java Mobile clients. For the convenience of description, we focus on the Ajax browsers in this guide. The following illustrates the relationship among them.

Development of View

For Ajax browsers, the view of a component is basically a collection of HTML tags and, optionally, JavaScript methods. The HTML tags are the visual presentation, while JavaScript methods initialize, clean up, listen to browser events and communicate with the server.

HTML Tags

For Ajax browser, the visual presentation is implemented with a collection of HTML tags. For example, assume you want to use the HTML's BUTTON tag to represent a component, and then the visual presentation might look as follows.

<BUTTON id="z_ed_0" z.type="mycomps.MyButton">I am a button</BUTTON>

where z_ed_0 is the component's UUID (which is assigned by ZK Loader), and z.type is a special attribute used to indicate the type of the component.

The visual presentation are running at and interpreted by the browser. However, they are generated at the server, when the redraw method is called. Everything written to the writer argument passed to the redraw method will be sent to the client.

Instead of implementing redraw, you can extend from AbstractComponent and provide a or its deriving classes), and not to implement redraw directly. Rather, implement the so-called mold with your favorite Servlet technology, such as DSP, JSP, and so on. For convenience of description, we will use DSP mostly in this guide.

In addition to Java Servlet technologies, you can implement it with a so-called component renderer (org.zkoss.zk.ui.util.ComponentRenderer) instead. It is a bit harder to read but with better performance. We will talk more about it later.

JavaScript Methods

Except implementing a very simple component, you usually need to provide some JavaScript codes to interact with the user, to manipulate HTML tags, and to communicate with the server. The JavaScript codes depending on their purpose can be grouped into separate methods. For example, assume you want to register an event listener when the component is initialized at the browser, and then the JavaScript codes might look as follows.

zkMyButton.init = function (cmp) {
    zk.listen(cmp, "click", function (evt) {/*my listener*/});    
};

where the method name is determined by the component type and when to call. In this example, the button's z.type is mycomps.MyButton (specified in the z.type attribute as described above). It means the JavaScript codes are located in a JavaScript file called, /web/js/mycomps.js. (and it must be locatable by the class loader), and the component type is MyButton.

Since we want it to run during initialization, the method name shall be zkMyButton.init (= "zk" + "Type" + ".when"). Similarly, If you want a method to be called when the browser is resized, the method name will be zkMyButton.onSize. We will talk more about it later.

Development of Handle

The handle is the states and API of the component that Web applications access. More precisely, it is a Java class that implements the org.zkoss.zk.ui.Component interface.

You generally don't implement this interface directly. Rather, you, depending on the requrirement, extend from one of the existent classes, such as org.zkoss.zk.ui.AbstractComponent, org.zkoss.zk.ui.HtmlBasedComponent, and org.zkoss.zul.XulComponent.

For example, assume we want to extend the most skeletal implementation AbstractComponent, and then the Java class might look as follows.

public MyButton extends AbstractComponent {
}

If you are extending from one of the skeletal implementations, there is basically no abstract method you have to implement other than component-specific methods.

Configuration

Once you implement the view and handle, you can specify the component in a XML file such that ZK will load it and the application can use it. The configuration file is called lang-addon.xml[6]. There are two locations you can place this file. One is under the /metainfo/zk directory that is locatable by classpath (usually part of a JAR file). The other is inside a Web application (part of a WAR file) by specifying the correct path in /WEB-INF/zk.xml[7].

Let us assume the view is /web/myaddon/button.dsp and the handle is the com.myaddon.MyButton class. Then, the configuration will look like as follows.

<language-addon>
        <addon-name>myAddon</addon-name><language-name>xul/html</language-name>        
    <component>    
        <component-name>mybutton</component-name>        
        <component-class>com.myaddon.MyButton</component-class>        
        <mold>        
            <mold-name>default</mold-name>            
            <mold-uri>~./web/myaddon/button.dsp</mold-uri>            
        </mold>        
    </component>    
</language-addon>

As shown, each lang-addon.xml must specify an unique name (addon-name) and the language it belongs to (language-name). Each component definition must specify the component name (component-name), the handle (component-class) and the view (mold). Each component can have multiple views and each view has a name (mold-name). The default mold name is default., which the mold you must have (unless you want to implement the redraw method directly).



[6] If you want to define a brand new language rather than adding components to an existent one, you shall use lang.xml instead.

[7] Refer to the Developer's Reference for details.