Define Composite Component using Java Annotation in ZK6"

From Documentation
m
Line 4: Line 4:
 
|version=ZK 6+
 
|version=ZK 6+
 
}}
 
}}
 
ZK Composite is a way to encapsulate a bunch of components as a component with ZK MVC support. In ZK6, ZK Composite brings you the ability to define and implement your component with simple java API and annotation, your composite component can be used almost 100% like a native component in ZK6.
 
  
  
Line 12: Line 10:
 
=Introduction=
 
=Introduction=
  
This article will guide you:
+
ZK Composite is a way to encapsulate a bunch of components as a component with ZK MVC support. In ZK6, ZK Composite brings you the ability to define and implement your component with simple java API and annotation, your composite component can be used almost 100% like a native component in ZK6.
 +
 
 +
This article will guide you through the following topics:
 
* Why Composite?  
 
* Why Composite?  
 
* When should we use Composite?
 
* When should we use Composite?

Revision as of 02:54, 13 December 2011

DocumentationSmall Talks2011DecemberDefine Composite Component using Java Annotation in ZK6
Define Composite Component using Java Annotation in ZK6

Author
Ian Tsai, Engineer, Potix Corporation
Date
December 06, 2011
Version
ZK 6+


Introduction

ZK Composite is a way to encapsulate a bunch of components as a component with ZK MVC support. In ZK6, ZK Composite brings you the ability to define and implement your component with simple java API and annotation, your composite component can be used almost 100% like a native component in ZK6.

This article will guide you through the following topics:

  • Why Composite?
  • When should we use Composite?
  • How to design our Composite?

The ideas of Composite

In previous article Envisage ZK 6: An Annotation Based Composer For MVC Simon Pai showed us the new approach to do ZK MVC in ZK6, which might be the best common solution for page layout fragment controller implementation. but in some cases, we have some requirements to some special UI parts that simple ZK MVC cannot satisfiled:

  • This UI fragment suppose to be reused in a lot of places.
  • It need to be attached and detached according to condition.
  • It should interacted with other UI parts just like a ZK Component (ex: a Permission Inquiry Dialog).

In ZK5, we introduced a concept named ZK Composite Component which is more like a practice. And now in ZK 6 with the power that Java Annotation granted, we are able to design an utility API and "define by annotation" mechanism to provide more conveniences.

How to Use

Before I start to show you how to get, how to install, and how many detail features that Composite has, I'd much prefer to use a quick sample code to show you how it works.


The use case: An in-place editable ImageLabel

Let's imaging today we want to build a Component with look & feel like this:

Smalltalks-define-composite-using-java-anno-in-zk6-01.png

The ZUL file of this UI part is very simple:

<groupbox id="item" width="800px" closable="false" sclass="item">
	<caption>
		<label id="titleLabel" sclass="title" />
	</caption>
	<hlayout>
		<image id="labelImage" sclass="image" />
		<div sclass="desc-div">
			<label id="descLabel" sclass="desc" />
		</div>
	</hlayout>
</groupbox>

This component has three properties: title, description and image. Now, by clicking the title of this component, the in-place editor will showed up:

Smalltalks-define-composite-using-java-anno-in-zk6-02.png

The ZUL structure of in-place editor is also very simple:

<zk>
	<hlayout width="790px">
		<textbox id="editTitle" width="650px" />
		<button id="submitBtn" label="Submit" />
		<button id="cancelBtn" label="Cancel" />
	</hlayout>
	<textbox id="editDesc" rows="5" width="790px" />
</zk>

As what we can see an editing area showed up that we can edit title and description for this ImageLabel. Now, we have scratches of how an UI usage we want to have, let's think about what kind of component API that we want to have for this component.

Usage of ImageLabel in ZUL file

<window title="Composite Demo" border="normal" width="1000px">

	<imglabel title="test" 
		description="this is description!!" 
		imagePath="~./partial/img/Centigrade-Widget-Icons/Button-24x24.png">
		
		<attribute name="onAfterEdit"><![CDATA[
			alert("new title is: "+event.title);
		]]></attribute>
		
	</imglabel>

</window>

This sample code showed us three things:

  • The imageLabel that we finally have can be used directly in ZUL, that means our final Composite class need to be registered in to ZK's Language Definition as a Component Definition.
  • This ImageLabel has to have setters/getters for title, description and imagePath properties for developer to configure.
  • This imageLabel support it's own event type: onAfterEdit

Implementation of your Composite Class

Here is a sample code of how to use ZK 6 Composite technology:

 1 package demo.ui.composite;
 2 
 3 import org.zkoss.composite.Composite;
 4 import org.zkoss.composite.Composites;
 5 import org.zkoss.zk.ui.IdSpace;
 6 import org.zkoss.zk.ui.select.Listen;
 7 import org.zkoss.zk.ui.select.Wire;
 8 ...
 9 
10 @Composite
11 public class ImageLabel extends Div implements IdSpace {
12 	
13 	@Wire
14 	private Groupbox item;
15 	@Wire
16 	private Image labelImage;
17 	@Wire
18 	private Label titleLabel;
19 	@Wire
20 	private Label descLabel;
21 	
22 	public ImageLabel(){
23 		Composites.doCompose(this, null);
24 	}
25 	
26 	private InplaceEditor fInplaceEditor;
27 	
28 	@Listen("onClick= #titleLabel")
29 	public void doTitleClick(){
30 		if(fInplaceEditor==null){
31 			fInplaceEditor = new InplaceEditor();
32 			fInplaceEditor.setParent(item);
33 		}else{
34 			fInplaceEditor.doCancel();
35 		}
36 	}

The concept is very simple: you declare a Java class which extends a ZK Component, annotate this class, call Composites.doCompose(this, null); in your constructor, that's all. The detailed steps are listed bellow:

Create a Java class extends from an existing ZK Component (ex: Div or Window)

Normally your composite class will extends from a container component such as Div or Window, but the case to extends from a Collection Component such as Grid or Listbox is also very common, this part is very flexible, all depends on your needs.

Ensure your class implements IdSpace

ZK Composite requires a ZUL as the content template and will do the field-variable auto wiring & Event Listening method registration. In order to prevent id conflict, you must make your Composite class implements IdSpace.

Call Composites.doCompose in constructor

org.zkoss.composite.Composites is the utility API which will do the real hard works.While doCompose(...), Composites will get the meta information(java annotation) from given instance type and do the following process:

1. Getting macroURI from annotation(@Composite) if any, use referenced resource to generate content components of this composite.

2. Using ZK6 org.zkoss.zk.ui.select.Selectors to wire annotated member fields and annotated methods(as event listening methods).

ZK Composite Definition can be registered through package scanning

Use annotated class as some kind of configuration with package scan while application start is a common practice used in a lot of application framework such as Spring JBoss Seam and EJB3. Now in ZK Composite, we support the same mechanism to register a composite as a component definition into application's ZUL Language Definition, which means by given packages in zk.xml, ZK Composite will find all annotated public Composite class and register them. This is a very convenient feature to let you define a composite without creating & configuring a metainfo/zk/lang-addon.xml in your source directory.


Set up zk.xml library property for your target package

Here is an example of how to config packages in your application:

1 <library-property>
2     	<name>org.zkoss.composite.packageScan</name>
3     	<value>demo.ui.homepage.composite, demo.ui.product.composite</value>
4 </library-property>

As this example illustrated, by now ZK Composite use ZK Library properties as the configuration interface, if in your case instead of going through this strategy you want to configure it by yourself, here is the API:

1 org.zkoss.composite.CompositeCtrls.scan(pkg, wapp);

Currently ZK Composite depends on ZK-CPR and ASM4.0 to implement it's package resource scanning, please make sure you have these jars(which are already packed inside the zip)in your project.

Use @Composite to annotate your Composite class

Import: org.zkoss.composite.Composite then mark your component class with @Composite annotation. @Composite has two attributes:

1. macroURI: by default, you don't have to assign this attribute and ZK Composite technology will use [package]/[class_name to lowerCase].zul to get the content template. The macro uri that you can assigned can be a class path resource which use "/" as separator, a zk web context path or a URL that current application can resolve.

2. name: by default, ZK Composite technology will use lower-cased class simple name as component name, which is the tag name that you can use in zul under zul namespace(default xml namespace in ZK).

Here is an example with most detail:

10 import org.zkoss.composite.Composite;
11 ...
12 
13 @Composite(name="imglabel", macroURI="/WEB-INF/partial/_ImageLabel.zul")
14 public class ImageLabel extends Div implements IdSpace {
15 ...



Installation

Here is the prerequisite stuff of using Composite in ZK6.

Install ZK 6 into your Web Project

I assume the reader of this article has used ZK before so I won't explain too much on this part, if you don't know how to start with ZK, please take a look at ZK Installation Guide

(Download link listed at the bottom of this article.)

Download ZK-Composite.zip from Github.com

Here is the project's link: ZK-Composite

Download the ZK-Composite.zip from this web site and unpack it. I assume you already has a ZK project, if you don't have, please read the user guide to create one, now copy every jar files(asm4.0.jar, zkcomposite.jar, zkcpr.jar) under /lib/* to your project's /WEB-INF/lib/.

(Download link listed at the bottom of this article.)

Copy the sample code into your project

inside the unpacked archive there are two folders: src_demo/ and WebContent/ , copy them into your project.

Download & Other Resources



Comments



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