Load ZUML in Java
Overview
Execution provides a collection of methods to allow you to create components based a ZUML document, such as Execution.createComponents(String, Component, Map), Execution.createComponentsDirectly(String, String, Component, Map) and many others. In additions, Executions provides a similar collection of shortcuts, so that you don't have to retrieve the current execution first.
For example,
public class Controller extends GenericForwardComposer {
private Window main; //assumed wired automatically
public void onClick() {
Executions.createComponentsDirectly(
"<listbox><listitem label=\"foo\"/></listbox>", "zul", this, null);
}
...
Create from URI
There are several ways to create components based a ZUML document. One of the most common approach is to create components from a URI.
Map arg = new HashMap();
arg.put("someName", someValue);
Executions.createComponents("/foo/my.zul", parent, arg); //attach to page as root if parent is null
where parent
(an instance of Component) will become the parent of the components specified in the ZUML document. If parent
is null, the components specified in the ZUML documents will become the root components of the current page. In other words, the components created by Execution.createComponents(String, Component, Map) will be attached the current page.
The arg Object
The map passed to the createComponents method can be accessed in the page being created by use of the arg object. For example,
<button label="Submit" if="${arg.someName}"/>
Create Components Not Attached to Any Page
If you want to create components that won't be attached to a page, you could use Execution.createComponents(String, Map). It is useful if you wan to maintain a cache of components or implement a utility. For example,
Map arg = new HashMap();
arg.put("someName", someValue);
Component[] comps = Executions.getCurrent().createComponents("/foo/my.zul", arg); //won't be attached to a page
cache.put("pool", comps); //you can store and use them later since they are attached to any page
Create Components in Working Thread
With Executions.createComponents(WebApp, String, Map), you could create components in a working thread without any execution[1], though it is rare.
Of course, the components being created by Executions.createComponents(WebApp, String, Map) won't be attached to any page. You have to attach them manually, if you want to show them to the client.
- ↑ It means Executions.getCurrent() returns null. For example, it happens when the application starts, or in a working thread.
Create from Content Directly
If the ZUML document is a resource of Web application (i.e., not accessible thru ServletContext), you could use one of createComponentsDirectly
methods. For example, you could read the content into a string from database and pass it to Execution.createComponentsDirectly(String, String, Component, Map). Or, you could represent the content as a reader (say, representing BLOB in database) and then pass it to Execution.createComponentsDirectly(Reader, String, Component, Map)
For example, suppose we want to create a component from a remote site. Then, we could represent the resource as a URL and do as follows.
public void loadFromWeb(java.net.URL src, Component parent) {
return Executions.createComponentsDirectly(
new java.io.InputStreamReader(src.openStream(), "UTF-8"), parent, null);
}
Create from Page Definition
When creating components from URI (such as Execution.createComponents(String, Component, Map)), ZK Loader will cache the parsed result and reuse it to speed up the rendering.
However, if you create components from content directly (such as Execution.createComponentsDirectly(String, String, Component, Map)), there is no way to cache the parsed result. In other words, the ZUML content will be parsed each time createComponentsDirectly
is called.
It is OK if the invocation does not happen frequently. However, if you want to improve the performance, you could parse the content into PageDefinition by use of Executions.getPageDefinitionDirectly(WebApp, String, String), cache it, and then invoke Executions.createComponents(PageDefinition, Component, Map) to create them repeatedly.
PageDefinition is a Java object representing a ZUML document. It is designed to allow ZK Loader to interpret every efficiently. Unfortunately, it is not serializable, so you can not store it to database or other persistent storage. You could serialize or marshal the original content (i.e., ZUML document) if required.
Notices
There are a few notices worth to know.
No Page Created
When creating components from a ZUML document as described above, no page (Page) is created. Components are attached to the current page or to a component, or simply standalone. Since no page is created, there are a few differences than visiting a ZUML document directly[1].
- The <?page?>, <?script?>, <?link?>, <?header?> and other directives controlling a page (Page) have no function. It means you could not change the page's title, add JavaScript code, or add CSS with these directive in a ZUML document loaded in this way.
- On the other hands, <?function-mapper?>, <?variable-resolver?> and <?component?> all work correctly, since they decide how a ZUML document is parsed, rather than how the current page (Page) shall be.
- The variables, functions and classes defined in zscript will be stored in the interpreter of the current page (Page.getInterpreter(String)).
- If Execution.createComponents(String, Map), Executions.createComponents(WebApp, String, Map) or similar is used to create components not attached to any page, the variables, functions and classes defined in the ZUML document will be lost. Thus, it is a not good idea to use zscript in this case.
- ↑ Don't confuse a ZUML page with Page. The former refers to a file containing a ZUML document. The later is a Java object of Page represents a portion of a desktop.
Version History
Last Update : 2010/12/9
Version | Date | Content |
---|---|---|