Load ZUML in Java"

From Documentation
(28 intermediate revisions by 5 users not shown)
Line 4: Line 4:
  
 
=Overview=
 
=Overview=
<javadoc>org.zkoss.zk.ui.Execution</javadoc> provides a collection of methods to allow you to create components based a ZUML document, such as <javadoc method="createComponents(java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>, <javadoc method="createComponentsDirectly(java.lang.String, java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc> and many others.
+
<javadoc>org.zkoss.zk.ui.Execution</javadoc> provides a collection of methods to allow you to create components based on a ZUML document, such as <javadoc method="createComponents(java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>, <javadoc method="createComponentsDirectly(java.lang.String, java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc> and many others.
In additions, <javadoc>org.zkoss.zk.ui.Executions</javadoc> provides a similar collection of shortcuts, so that you don't have to retrieve the current execution first.
+
In addition, <javadoc>org.zkoss.zk.ui.Executions</javadoc> provides a similar collection of shortcuts so that you do not have to retrieve the current execution first.
  
 
For example,
 
For example,
  
 
<source lang="Java">
 
<source lang="Java">
public class Controller extends GenericForwardComposer {
+
public class Controller extends SelectorComposer {
 +
    @Wire
 
     private Window main; //assumed wired automatically
 
     private Window main; //assumed wired automatically
     public void onClick() {
+
    @Listen(onClick = #main)
 +
     public void createListbox() {
 
         Executions.createComponentsDirectly(
 
         Executions.createComponentsDirectly(
 
           "<listbox><listitem label=\"foo\"/></listbox>", "zul", this, null);
 
           "<listbox><listitem label=\"foo\"/></listbox>", "zul", this, null);
Line 21: Line 23:
 
=Create from URI=
 
=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.
+
There are several ways to create components based on a ZUML document. One of the most common approach is to create components from a URI.
  
 
<source lang="Java">
 
<source lang="Java">
Line 29: Line 31:
 
</source>
 
</source>
  
where <code>parent</code> (an instance of <javadoc>org.zkoss.zk.ui.Component</javadoc>) will become the parent of the components specified in the ZUML document. If <code>parent</code> 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 <javadoc method="createComponents(java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc> will be attached the current page.
+
where <code>parent</code> (an instance of <javadoc>org.zkoss.zk.ui.Component</javadoc>) will become the parent of the components specified in the ZUML document. If <code>parent</code> 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 <javadoc method="createComponents(java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc> will be attached to the current page.
  
==arg==
+
==The arg Object==
 
The map passed to the <tt>createComponents</tt> method can be accessed in the page being created by use of [[ZUML Reference/EL Expressions/Implicit Objects/arg|the arg object]]. For example,
 
The map passed to the <tt>createComponents</tt> method can be accessed in the page being created by use of [[ZUML Reference/EL Expressions/Implicit Objects/arg|the arg object]]. For example,
  
Line 38: Line 40:
 
</source>
 
</source>
  
==Create Components Not Attached to Any Page==
+
==Create Components Not Attached to Any Pages==
If you want to create components that won't be attached to a page, you could use <javadoc method="createComponents(java.lang.String, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>. It is useful if you wan to maintain a cache of components or implement a utility. For example,
+
If you want to create components that will not be attached to a page, you could use <javadoc method="createComponents(java.lang.String, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>. It is useful if you want to maintain a cache of components or implement a utility.  
 +
 
 +
For example:
  
 
<source lang="Java">
 
<source lang="Java">
Line 45: Line 49:
 
arg.put("someName", someValue);
 
arg.put("someName", someValue);
 
Component[] comps = Executions.getCurrent().createComponents("/foo/my.zul", arg); //won't be attached to a page
 
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
+
cache.put("pool", comps); //you can store and use them later since they are not (yet) attached to any pages
 
</source>
 
</source>
  
 
==Create Components in Working Thread==
 
==Create Components in Working Thread==
  
With <javadoc method="createComponents(org.zkoss.zk.ui.WebApp, java.lang.String, java.util.Map)">org.zkoss.zk.ui.Executions</javadoc>, you could create components in a working thread without any execution<ref>It means <javadoc method="getCurrent()">org.zkoss.zk.ui.Executions</javadoc> returns null. For example, it happens when the application starts, or in a working thread.</ref>, though it is rare.  
+
With <javadoc method="createComponents(org.zkoss.zk.ui.WebApp, java.lang.String, java.util.Map)">org.zkoss.zk.ui.Executions</javadoc>, you could create components in a working thread without execution<ref>It means <javadoc method="getCurrent()">org.zkoss.zk.ui.Executions</javadoc> returns null. For example, it happens when the application starts, or in a working thread.</ref>, though it is rare.  
  
Of course, the components being created by <javadoc method="createComponents(org.zkoss.zk.ui.WebApp, java.lang.String, java.util.Map)">org.zkoss.zk.ui.Executions</javadoc> won't be attached to any page. You have to attach them manually, if you want to show them to the client.
+
Of course, the components being created by <javadoc method="createComponents(org.zkoss.zk.ui.WebApp, java.lang.String, java.util.Map)">org.zkoss.zk.ui.Executions</javadoc> will not be attached to any pages. You have to attach them manually, if you want to show them to the client.
  
 
<blockquote>
 
<blockquote>
Line 61: Line 65:
 
=Create from Content Directly=
 
=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 <code>createComponentsDirectly</code> methods. For example, you could read the content into a string from database and pass it to <javadoc method="createComponentsDirectly(java.lang.String, java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>. Or, you could represent the content as a reader (say, representing BLOB in database) and then pass it to <javadoc method="createComponentsDirectly(java.io.Reader, java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>
+
If the ZUML document is a resource of Web application (i.e., not accessible through ServletContext), you could use one of the <code>createComponentsDirectly</code> methods. For example, you could read the content into a string from database and pass it to <javadoc method="createComponentsDirectly(java.lang.String, java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>. Or, you could represent the content as a reader (say, representing BLOB in database) and then pass it to <javadoc method="createComponentsDirectly(java.io.Reader, java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>
  
 
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.
 
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.
Line 67: Line 71:
 
<source lang="xml">
 
<source lang="xml">
 
public void loadFromWeb(java.net.URL src, Component parent) {
 
public void loadFromWeb(java.net.URL src, Component parent) {
     return Executions.createComponentsDirectly(
+
     Executions.createComponentsDirectly(
 
         new java.io.InputStreamReader(src.openStream(), "UTF-8"), parent, null);
 
         new java.io.InputStreamReader(src.openStream(), "UTF-8"), parent, null);
 
}
 
}
Line 74: Line 78:
 
=Create from Page Definition=
 
=Create from Page Definition=
  
When creating components from URI (such as <javadoc method="createComponents(java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>), ZK Loader will cache the parsed result and reuse it to speed up the rendering.
+
When creating components from the URI (such as <javadoc method="createComponents(java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>), 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 <javadoc method="createComponentsDirectly(java.lang.String, java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>), there is no way to cache the parsed result. In other words, the ZUML content will be parsed each time <code>createComponentsDirectly</code> is called.
+
However, if you create components from the content directly (such as <javadoc method="createComponentsDirectly(java.lang.String, java.lang.String, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>), there is no way to cache the parsed result. In other words, the ZUML content will be parsed each time <code>createComponentsDirectly</code> 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 <javadoc>org.zkoss.zk.ui.metainfo.PageDefinition</javadoc> by use of <javadoc method="getPageDefinitionDirectly(org.zkoss.zk.ui.WebApp, java.lang.String, java.lang.String)">org.zkoss.zk.ui.Executions</javadoc>, cache it, and then invoke <javadoc method="createComponents(org.zkoss.zk.ui.metainfo.PageDefinition, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Executions</javadoc> to create them repeatedly.
+
It is OK if the invocation does not happen frequently. However, if you want to improve the performance, you could parse the content into <javadoc>org.zkoss.zk.ui.metainfo.PageDefinition</javadoc> by using <javadoc method="getPageDefinitionDirectly(org.zkoss.zk.ui.WebApp, java.lang.String, java.lang.String)">org.zkoss.zk.ui.Executions</javadoc>, cache it, and then invoke <javadoc method="createComponents(org.zkoss.zk.ui.metainfo.PageDefinition, org.zkoss.zk.ui.Component, java.util.Map)">org.zkoss.zk.ui.Executions</javadoc> to create them repeatedly.
  
<javadoc>org.zkoss.zk.ui.metainfo.PageDefinition</javadoc> 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.
+
<javadoc>org.zkoss.zk.ui.metainfo.PageDefinition</javadoc> is a Java object representing a ZUML document. It is designed to allow ZK Loader to interpret even more efficiently. Unfortunately, it is not serializable, so you can not store it into database or other persistent storage. You could serialize or marshal the original content (i.e., ZUML document) if required.
  
 
=Notices=
 
=Notices=
Line 87: Line 91:
 
==No Page Created==
 
==No Page Created==
  
When creating components from a ZUML document as described above, no page (<javadoc>org.zkoss.zk.ui.Page</javadoc>) 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<ref>Don't confuse a ZUML page with <javadoc>org.zkoss.zk.ui.Page</javadoc>. The former refers to a file containing a ZUML document. The later is a Java object of <javadoc>org.zkoss.zk.ui.Page</javadoc> represents [[ZK Developer's Reference/UI Composing/Component-based UI#Desktop.2C_Page_and_Component|a portion of a desktop]].</ref>.
+
When creating components from a ZUML document as described above, no page (<javadoc>org.zkoss.zk.ui.Page</javadoc>) is created. Components are attached to the current page, to a component, or simply standalone. Since no page is created, there are a few differences than visiting a ZUML document directly<ref>Don't confuse a ZUML page with <javadoc>org.zkoss.zk.ui.Page</javadoc>. The former refers to a file containing a ZUML document. The later is a Java object of <javadoc>org.zkoss.zk.ui.Page</javadoc> represents [[ZK Developer's Reference/UI Composing/Component-based UI#Desktop.2C_Page_and_Component|a portion of a desktop]].</ref>.
  
# The [[ZUML Reference/ZUML/Processing Instructions/page|&lt;?page?&gt;]],  [[ZUML Reference/ZUML/Processing Instructions/script|&lt;?script?&gt;]],  [[ZUML Reference/ZUML/Processing Instructions/link|&lt;?link?&gt;]], [[ZUML Reference/ZUML/Processing Instructions/header|&lt;?header?&gt;]] and other directives controlling a page (<javadoc>org.zkoss.zk.ui.Page</javadoc>) 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.
+
# The [[ZUML Reference/ZUML/Processing Instructions/page|&lt;?page?&gt;]],  [[ZUML Reference/ZUML/Processing Instructions/script|&lt;?script?&gt;]],  [[ZUML Reference/ZUML/Processing Instructions/link|&lt;?link?&gt;]], [[ZUML Reference/ZUML/Processing Instructions/header|&lt;?header?&gt;]] and other directives controlling a page (<javadoc>org.zkoss.zk.ui.Page</javadoc>) have no function. It means that 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, [[ZUML Reference/ZUML/Processing Instructions/function-mapper|&lt;?function-mapper?&gt;]], [[ZUML Reference/ZUML/Processing Instructions/variable-resolver|&lt;?variable-resolver?&gt;]] and [[ZUML Reference/ZUML/Processing Instructions/component|&lt;?component?&gt;]] all work correctly, since they decide how a ZUML document is parsed, rather than how the current page (<javadoc>org.zkoss.zk.ui.Page</javadoc>) shall be.
+
# On the other hands, when [[ZUML Reference/ZUML/Processing Instructions/function-mapper|&lt;?function-mapper?&gt;]], [[ZUML Reference/ZUML/Processing Instructions/variable-resolver|&lt;?variable-resolver?&gt;]] and [[ZUML Reference/ZUML/Processing Instructions/component|&lt;?component?&gt;]] work correctly, they decide how a ZUML document is parsed rather than how the current page (<javadoc>org.zkoss.zk.ui.Page</javadoc>) should be.
 
# The variables, functions and classes defined in zscript will be stored in the interpreter of the current page (<javadoc method="getInterpreter(java.lang.String)">org.zkoss.zk.ui.Page</javadoc>).
 
# The variables, functions and classes defined in zscript will be stored in the interpreter of the current page (<javadoc method="getInterpreter(java.lang.String)">org.zkoss.zk.ui.Page</javadoc>).
#*If <javadoc method="createComponents(java.lang.String, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>, <javadoc method="createComponents(org.zkoss.zk.ui.WebApp, java.lang.String, java.util.Map)">org.zkoss.zk.ui.Executions</javadoc> 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.
+
#*If <javadoc method="createComponents(java.lang.String, java.util.Map)">org.zkoss.zk.ui.Execution</javadoc>, <javadoc method="createComponents(org.zkoss.zk.ui.WebApp, java.lang.String, java.util.Map)">org.zkoss.zk.ui.Executions</javadoc> 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'' a good idea to use zscript in this case.
  
 
<blockquote>
 
<blockquote>
Line 100: Line 104:
  
 
=Version History=
 
=Version History=
Last Update : {{REVISIONYEAR}}/{{REVISIONMONTH}}/{{REVISIONDAY}}
+
{{LastUpdated}}
 
{| border='1px' | width="100%"
 
{| border='1px' | width="100%"
 
! Version !! Date !! Content
 
! Version !! Date !! Content

Revision as of 03:07, 26 August 2015



Overview

Execution provides a collection of methods to allow you to create components based on a ZUML document, such as Execution.createComponents(String, Component, Map), Execution.createComponentsDirectly(String, String, Component, Map) and many others. In addition, Executions provides a similar collection of shortcuts so that you do not have to retrieve the current execution first.

For example,

public class Controller extends SelectorComposer {
    @Wire
    private Window main; //assumed wired automatically
    @Listen(onClick = #main)
    public void createListbox() {
        Executions.createComponentsDirectly(
           "<listbox><listitem label=\"foo\"/></listbox>", "zul", this, null);
    }
...

Create from URI

There are several ways to create components based on 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 to 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 Pages

If you want to create components that will not be attached to a page, you could use Execution.createComponents(String, Map). It is useful if you want 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 not (yet) attached to any pages

Create Components in Working Thread

With Executions.createComponents(WebApp, String, Map), you could create components in a working thread without execution[1], though it is rare.

Of course, the components being created by Executions.createComponents(WebApp, String, Map) will not be attached to any pages. You have to attach them manually, if you want to show them to the client.


  1. 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 through ServletContext), you could use one of the 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) {
    Executions.createComponentsDirectly(
        new java.io.InputStreamReader(src.openStream(), "UTF-8"), parent, null);
}

Create from Page Definition

When creating components from the 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 the 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 using 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 even more efficiently. Unfortunately, it is not serializable, so you can not store it into 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, to a component, or simply standalone. Since no page is created, there are a few differences than visiting a ZUML document directly[1].

  1. The <?page?>, <?script?>, <?link?>, <?header?> and other directives controlling a page (Page) have no function. It means that 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.
  2. On the other hands, when <?function-mapper?>, <?variable-resolver?> and <?component?> work correctly, they decide how a ZUML document is parsed rather than how the current page (Page) should be.
  3. The variables, functions and classes defined in zscript will be stored in the interpreter of the current page (Page.getInterpreter(String)).

  1. 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 : 2015/08/26


Version Date Content
     



Last Update : 2015/08/26

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