Implement Custom Java Class

From Documentation


Implement Custom Java Class


As described in the earlier sections, a macro component is instantiated to represent a regular macro. By default, HtmlMacroComponent is assumed (and instantiated). However, you provide a custom Java class to provide a better API to simplify the access and to encapsulate the implementation.

Implement Custom Java Class for Macro

The implementation is straightforward. First, the custom Java class for macro components must extend from HtmlMacroComponent. Second, it shall invoke HtmlMacroComponent.compose() in the constructor[1], such that the template will be applied in the constructor.

For example, suppose we have a macro template as follows.

<hlayout>
	Username: <textbox id="mc_who"/>
</hlayout>

Then, we could implement a Java class for it:

package foo;

import org.zkoss.zk.ui.HtmlMacroComponent;
import org.zkoss.zul.Textbox;

public class Username extends HtmlMacroComponent {
    private Textbox mc_who; //will be wired when compose() is called
    public Username() {
        compose(); //fore the template to be applied
    }
    public String getWho() {
        return mc_who.getValue();
    }
    public void setWho(String who) {
        mc_who.setValue(who);
    }
    //public void onOK() {..} //you could add event listeners too
}

Notice that HtmlMacroComponent.compose() will wire fellows and event listener automatically, so we could access them directly (such as the mc_who member). For more information, please refer to the Wire Variables and Wire Event Listeners sections.

Also notice that the arg variable is still available to the template to represent properties set by DynamicPropertied.setDynamicProperty(String, Object). However, it is pointless to use it if we provide all required setters.


  1. HtmlMacroComponent.compose() is available in 5.0.5. For 5.0.4 or earlier, please invoke HtmlMacroComponent.afterCompose() instead.

Declare Macro with Custom Java Class

To make ZK Loader to know which custom Java class to use, we have to specify the class attribute when declaring it in the component directives. For example,

<?component name="username" macroURI="/WEB-INF/macros/username.zul"
   class="foo.Username"?>

Use Macro with Custom Java Class

In ZUML

The use of the macro component with a custom Java class in a ZUML page is the same as other macro components.

In Java

The main purpose of introducing a custom Java class is to simplify the use of a macro component in Java. For example, you could invoke a more meaningful setter, say, setWho, directly rather than DynamicPropertied.setDynamicProperty(String, Object). In additions, the instantiation could be as simple as follows:

Username ua = new Username();
ua.setParent(wnd);
ua.setWho("Joe");

Macro Component and ID Space

Like Window, HtmlMacroComponent also implements IdSpacce. It means a macro component (excluding inline macros) is a space owner. In other words, it is free to use whatever identifiers to identify components inside the template.

For example, assume we have a macro defined as follows.

<hlayout>
	Username: <textbox id="who" value="${arg.who}"/>
</hlayout>

Then, the following codes work correctly.

<?component name="username" macroURI="/WEB-INF/macros/username.zul"?>
<zk>
	<username/>
	<button id="who"/> <!-- no conflict because it is in a different ID space -->
</zk>

However, the following codes don't work.

<?component name="username" macroURI="/WEB-INF/macros/username.zul"?>
<username id="who"/>

Why? Like any ID space owner, the macro component itself is in the same ID space with its child components. There are two alternative solutions:

1. Use a special prefix for the identifiers of child components of a macro component. For example, "mc_who" instead of "who".

<hlayout>
	Username: <textbox id="mc_who" value="${arg.who}"/>
</hlayout>

2. Use the window component to create an additional ID space.

<window>
	<hlayout>
		Username: <textbox id="who" value="${arg.who}"/>
	</hlayout>
</window>

The first solution is suggested, if applicable, due to the simplicity.

Version History

Last Update : 2010/11/9

Version Date Content
5.0.5 October, 2010 HtmlMacroComponent.compose() was introduced.



Last Update : 2010/11/09

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