UI Component Forest"

From Documentation
m (correct highlight (via JWB))
 
(4 intermediate revisions by 2 users not shown)
Line 4: Line 4:
  
 
===Forest of Trees of Components===
 
===Forest of Trees of Components===
Like a tree structure, a component has at most one parent. A component might have multiple children. All components of a <tt>page</tt> form a [http://en.wikipedia.org/wiki/Document_Object_Model DOM] tree.
+
Like a tree structure, a component has at most one parent. A component might have multiple children. All components of a <code>page</code> form a [http://en.wikipedia.org/wiki/Document_Object_Model DOM] tree.
  
Some components accept only certain types of components as children. Some must be a child of certain type of components. Some don't allow any child at all. For example, <tt>Listbox</tt> in XUL accepts <tt>Listcols</tt> and <tt>Listitem</tt> only. Refer to Javadoc or XUL tutorials for details.
+
Some components accept only certain types of components as children. Some must be a child of certain type of components. Some don't allow any child at all. For example, <code>Listbox</code> in XUL accepts <code>Listcols</code> and <code>Listitem</code> only. Refer to Javadoc or XUL tutorials for details.
  
A component without any parent is called a '''root component'''. A page might have multiple root components, but this is against XML's syntax limitation: One document root only. You may use tags as <tt>zk</tt>, <tt>window</tt>, <tt>span</tt>, <tt>div</tt> as the document root to group these root components
+
A component without any parent is called a '''root component'''. A page might have multiple root components, but this is against XML's syntax limitation: One document root only. You may use tags as <code>zk</code>, <code>window</code>, <code>span</code>, <code>div</code> as the document root to group these root components
  
 
===ID Space===
 
===ID Space===
Line 15: Line 15:
 
The concept of ID space is hence introduced to resolve this issue. An ID space is a subset of components of a desktop. The uniqueness is guaranteed only in the scope of an ID space.
 
The concept of ID space is hence introduced to resolve this issue. An ID space is a subset of components of a desktop. The uniqueness is guaranteed only in the scope of an ID space.
  
The simplest form of an ID space is a <tt>window</tt> (<javadoc>org.zkoss.zul.Window</javadoc> ). All descendant components of a <tt>window</tt> (including the <tt>label</tt> window)forms an independent ID space. Thus, you could use a <tt>window</tt> as the topmost component of each page, such that developers need to maintain the uniqueness of each page separately.
+
The simplest form of an ID space is a <code>window</code> (<javadoc>org.zkoss.zul.Window</javadoc> ). All descendant components of a <code>window</code> (including the window itself) forms an independent ID space. Thus, you could use a <code>window</code> as the topmost component of each page, such that developers need to maintain the uniqueness of each page separately.
  
More generally, any component could form an ID space as long as it implements the <javadoc type="interface">org.zkoss.zk.ui.IdSpace</javadoc> interface. <tt>Page</tt> also implements the IdSpace interface, so it is also a space owner. Besides <tt>window</tt> and <tt>page</tt>, <tt>regular macro</tt> is another built-in space owner.
+
More generally, any component could form an ID space as long as it implements the <javadoc type="interface">org.zkoss.zk.ui.IdSpace</javadoc> interface. <code>Page</code> also implements the IdSpace interface, so it is also a space owner. Besides <code>window</code> and <code>page</code>, <code>regular macro</code> is another built-in space owner.
  
The topmost component of an ID space is called the owner of the ID space, which could be retrieved by the <tt>getSpaceOwner</tt> method in the Component interface.
+
The topmost component of an ID space is called the owner of the ID space, which could be retrieved by the <code>getSpaceOwner</code> method in the Component interface.
  
 
If an ID space, say X, is a descendant of another ID space, say Y, then space X's owner is part of space Y but descendants of X is not part of space Y.
 
If an ID space, say X, is a descendant of another ID space, say Y, then space X's owner is part of space Y but descendants of X is not part of space Y.
Line 48: Line 48:
 
Components in the same ID spaces are called fellows. For example, A, B, C and D are fellows of the same ID space.
 
Components in the same ID spaces are called fellows. For example, A, B, C and D are fellows of the same ID space.
  
To retrieve another fellow, you could use the <tt>getFellow</tt> method in the <tt>IdSpace</tt> interface or the <tt>Component</tt> interface.
+
To retrieve another fellow, you could use the <code>getFellow</code> method in the <code>IdSpace</code> interface or the <code>Component</code> interface.
  
Notice that the <tt>getFellow</tt> method can be invoked against any components in the same ID space, not just the space owner. Similarly, the <tt>getSpaceOwner</tt> method returns the same object for any components in the same ID space, no matter it is the space owner or not. In the example above, if C calls <tt>getSpaceOwner</tt> will get C itself, if C calls <tt>getSpaceOwnerOfParent</tt> will get A.
+
Notice that the <code>getFellow</code> method can be invoked against any components in the same ID space, not just the space owner. Similarly, the <code>getSpaceOwner</code> method returns the same object for any components in the same ID space, no matter it is the space owner or not. In the example above, if C calls <code>getSpaceOwner</code> will get C itself, if C calls <code>getSpaceOwnerOfParent</code> will get A.
  
The <javadoc>org.zkoss.zk.ui.Path</javadoc> class provides utilities to simplify the location of a component among ID spaces. The way of using it is similar to <tt>java.io.File</tt> .
+
The <javadoc>org.zkoss.zk.ui.Path</javadoc> class provides utilities to simplify the location of a component among ID spaces. The way of using it is similar to <code>java.io.File</code> .
  
 
<source lang="java" >
 
<source lang="java" >
Line 61: Line 61:
 
</source>
 
</source>
  
Remember that each GUI component has its corresponding java object. Through <tt>Path.getComponent()</tt>, you can get the object in java, and do whatever you want to manipulate the java object.[[example code for path getComponent | Learn more]]
+
Remember that each GUI component has its corresponding java object. Through <code>Path.getComponent()</code>, you can get the object in java, and do whatever you want to manipulate the java object.[[example code for path getComponent | Learn more]]
  
 
===Namespace and ID Space===
 
===Namespace and ID Space===
Line 68: Line 68:
  
 
*First, each ID space corresponds to exactly one namespace.  
 
*First, each ID space corresponds to exactly one namespace.  
*Second, variables defined in a namespace are visible to the zscript codes and [http://books.zkoss.org/wiki/ZK_ZUML_Reference/EL_Expressions EL expressions] that belong to the same namespace.
+
*Second, variables defined in a namespace are visible to the zscript codes and [[ZK_ZUML_Reference/EL_Expressions | EL expressions]] that belong to the same namespace.
  
In the following example, it will show: <tt>Hi, namespace  Hi, namespace</tt>
+
In the following example, it will show: <code>Hi, namespace  Hi, namespace</code>
 
<source lang="xml" >
 
<source lang="xml" >
 
<window border="normal">
 
<window border="normal">
Line 81: Line 81:
 
</source>
 
</source>
  
<tt>${l.value}</tt> is an EL expression, it means get the value of <tt>l</tt>.
+
<code>${l.value}</code> is an EL expression, it means get the value of <code>l</code>.
  
In the following example, there are two namespaces. One belongs to window <tt>w1</tt> while the other belongs to window <tt>w2</tt>. Thus, the <tt>b1</tt> button's <tt>onClick</tt> script refers to the label defined in window <tt>w2</tt> , while the <tt>b2</tt> button's <tt>onClick</tt> script refers to the checkbox defined in window <tt>w1</tt> .
+
In the following example, there are two namespaces. One belongs to window <code>w1</code> while the other belongs to window <code>w2</code>. Thus, the <code>b1</code> button's <code>onClick</code> script refers to the label defined in window <code>w2</code> , while the <code>b2</code> button's <code>onClick</code> script refers to the checkbox defined in window <code>w1</code> .
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 98: Line 98:
 
*Notice the namespace is '''hierarchical'''.  
 
*Notice the namespace is '''hierarchical'''.  
  
In other words, <tt>zscript</tt> in window <tt>w2</tt> can see components in window <tt>w1</tt> , unless it is overridden in window <tt>w2</tt> . Thus, clicking button <tt>b1</tt> will change label of <tt>c</tt> to "OK" in the following example.
+
In other words, <code>zscript</code> in window <code>w2</code> can see components in window <code>w1</code> , unless it is overridden in window <code>w2</code> . Thus, clicking button <code>b1</code> will change label of <code>c</code> to "OK" in the following example.
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 109: Line 109:
 
</source>
 
</source>
  
It looks strange at first glance, as <tt>onClick="c.value = &amp;quot;OK&amp;quot;"</tt> appears before <tt><label id="c"/></tt> is defined. Don't we have to declare variable before using it? Actually, it's a life cycle issue. <tt>zscript</tt> inside <tt>onClick</tt> is only evaluated when user actually clicks on the button. At that time, <tt><label id="c"/></tt> has been created already and is certainly visible to <tt>zscript</tt>.
+
It looks strange at first glance, as <code>onClick="c.value = &amp;quot;OK&amp;quot;"</code> appears before <code><label id="c"/></code> is defined. Don't we have to declare variable before using it? Actually, it's a life cycle issue. <code>zscript</code> inside <code>onClick</code> is only evaluated when user actually clicks on the button. At that time, <code><label id="c"/></code> has been created already and is certainly visible to <code>zscript</code>.
 
 
[[Namespace and ID Space more examples | For more example]]
 
  
 
===Manipulate DOM by Java===
 
===Manipulate DOM by Java===
[http://en.wikipedia.org/wiki/Document_Object_Model DOM](Document Object Model) is generated as the layout of zul components in ZUML. In addition to ZUML, you can use Java to add, remove, move nodes in DOM manually. When a component is created manually, it won't be added to any page automatically. In other words, it doesn't appear at user's browser. To add it to a page, you could invoke the <tt>setParent</tt>, <tt>appendChild</tt> or <tt>insertBefore</tt> method to assign a parent to it, and it becomes a part of a page if the parent is a part of a page.
+
[http://en.wikipedia.org/wiki/Document_Object_Model DOM](Document Object Model) is generated as the layout of zul components in ZUML. In addition to ZUML, you can use Java to add, remove, move nodes in DOM manually. When a component is created manually, it won't be added to any page automatically. In other words, it doesn't appear at user's browser. To add it to a page, you could invoke the <code>setParent</code>, <code>appendChild</code> or <code>insertBefore</code> method to assign a parent to it, and it becomes a part of a page if the parent is a part of a page.
  
As demonstrated in section [[Getting_started#Design_pattern:_MVC|Design pattern: MVC]], a <tt>label</tt> is appended to <tt>window</tt> when the <tt>button</tt> is clicked. A node that represents the <tt>label</tt> is added to the DOM tree, and the node of <tt>window</tt> is its parent.
+
As demonstrated in section [[ZK_Developer's_Guide/Advanced_ZK/MVC_in_ZK | Design pattern: MVC]], a <code>label</code> is appended to <code>window</code> when the <code>button</code> is clicked. A node that represents the <code>label</code> is added to the DOM tree, and the node of <code>window</code> is its parent.
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 122: Line 120:
 
</source>
 
</source>
  
Another way to add new child is through <tt>Executions.createComponents</tt>. Please refer to [http://www.zkoss.org/javadoc/3.5.2/zk/org/zkoss/zk/ui/Executions.html java doc for Executions]
+
Another way to add new child is through <code>Executions.createComponents</code>. Please refer to [http://www.zkoss.org/javadoc/latest/zk/org/zkoss/zk/ui/Executions.html java doc for Executions]
  
Note that, we can also write java code inside *.zul, which is called <tt>zscript</tt>.
+
Note that, we can also write java code inside *.zul, which is called <code>zscript</code>.
  
  
 
{{ ZKDevelopersGuidePageFooter}}
 
{{ ZKDevelopersGuidePageFooter}}

Latest revision as of 10:36, 19 January 2022

Stop.png This documentation is for an older version of ZK. For the latest one, please click here.



Forest of Trees of Components

Like a tree structure, a component has at most one parent. A component might have multiple children. All components of a page form a DOM tree.

Some components accept only certain types of components as children. Some must be a child of certain type of components. Some don't allow any child at all. For example, Listbox in XUL accepts Listcols and Listitem only. Refer to Javadoc or XUL tutorials for details.

A component without any parent is called a root component. A page might have multiple root components, but this is against XML's syntax limitation: One document root only. You may use tags as zk, window, span, div as the document root to group these root components

ID Space

It is common to decompose a visual presentation into several ZUML pages. For example, a page for displaying a purchase order, and a modal dialog for entering the payment term. If all components are uniquely identifiable in the same desktop, developers have to maintain the uniqueness of all identifiers for all pages that might created to the same desktop.

The concept of ID space is hence introduced to resolve this issue. An ID space is a subset of components of a desktop. The uniqueness is guaranteed only in the scope of an ID space.

The simplest form of an ID space is a window (Window ). All descendant components of a window (including the window itself) forms an independent ID space. Thus, you could use a window as the topmost component of each page, such that developers need to maintain the uniqueness of each page separately.

More generally, any component could form an ID space as long as it implements the IdSpace interface. Page also implements the IdSpace interface, so it is also a space owner. Besides window and page, regular macro is another built-in space owner.

The topmost component of an ID space is called the owner of the ID space, which could be retrieved by the getSpaceOwner method in the Component interface.

If an ID space, say X, is a descendant of another ID space, say Y, then space X's owner is part of space Y but descendants of X is not part of space Y.


Following zul example will get an ID space graph as below:

<?page id="P"?>
<zk>
	<window id="A">
		<hbox id="B">
			<button id="D" />
		</hbox>
		<window id="C">
			<button id="E" />
		</window>
	</window>
	<hbox id="F">
		<button id="G" />
	</hbox>
</zk>

Zk the id space.jpg

As depicted in the figure, there are three spaces: P, A and C. Space P includes P, A, F and G. Space A includes A, B, C and D. Space C includes C and E.

Components in the same ID spaces are called fellows. For example, A, B, C and D are fellows of the same ID space.

To retrieve another fellow, you could use the getFellow method in the IdSpace interface or the Component interface.

Notice that the getFellow method can be invoked against any components in the same ID space, not just the space owner. Similarly, the getSpaceOwner method returns the same object for any components in the same ID space, no matter it is the space owner or not. In the example above, if C calls getSpaceOwner will get C itself, if C calls getSpaceOwnerOfParent will get A.

The Path class provides utilities to simplify the location of a component among ID spaces. The way of using it is similar to java.io.File .

//below are 3 different ways to get the same component E
Path.getComponent("/A/C/E");//if call Path.getComponent under the same page.
new Path("A/C", "E").getComponent();
Path.getComponent("//P/A/C/E");//for page, you have to use // as prefix

Remember that each GUI component has its corresponding java object. Through Path.getComponent(), you can get the object in java, and do whatever you want to manipulate the java object. Learn more

Namespace and ID Space

To grant the interpreter an access to the components directly, the namespace concept (Namespace ) is introduced.

  • First, each ID space corresponds to exactly one namespace.
  • Second, variables defined in a namespace are visible to the zscript codes and EL expressions that belong to the same namespace.

In the following example, it will show: Hi, namespace Hi, namespace

<window border="normal">
	<label id="l" value="changed by zscript, therefore not shown"/>
	<zscript>
		l.value = "Hi, namespace";
	</zscript>
	${l.value}
</window>

${l.value} is an EL expression, it means get the value of l.

In the following example, there are two namespaces. One belongs to window w1 while the other belongs to window w2. Thus, the b1 button's onClick script refers to the label defined in window w2 , while the b2 button's onClick script refers to the checkbox defined in window w1 .

<window id="w1">
	<window id="w2">
		<label id="c"/>
		<button id="b1" onClick="c.value = &quot;OK&quot;" label="click me"/>
	</window>
	<checkbox id="c"/>
	<button id="b2" onClick="c.label = &quot;OK&quot;" label="click me"/>
</window>
  • Notice the namespace is hierarchical.

In other words, zscript in window w2 can see components in window w1 , unless it is overridden in window w2 . Thus, clicking button b1 will change label of c to "OK" in the following example.

<window id="w1">
	<window id="w2">
		<button id="b1" onClick="c.value = &quot;OK&quot;" label="Click me"/>
	</window>
	<label id="c"/>
</window>

It looks strange at first glance, as onClick="c.value = &quot;OK&quot;" appears before <label id="c"/> is defined. Don't we have to declare variable before using it? Actually, it's a life cycle issue. zscript inside onClick is only evaluated when user actually clicks on the button. At that time, <label id="c"/> has been created already and is certainly visible to zscript.

Manipulate DOM by Java

DOM(Document Object Model) is generated as the layout of zul components in ZUML. In addition to ZUML, you can use Java to add, remove, move nodes in DOM manually. When a component is created manually, it won't be added to any page automatically. In other words, it doesn't appear at user's browser. To add it to a page, you could invoke the setParent, appendChild or insertBefore method to assign a parent to it, and it becomes a part of a page if the parent is a part of a page.

As demonstrated in section Design pattern: MVC, a label is appended to window when the button is clicked. A node that represents the label is added to the DOM tree, and the node of window is its parent.

evt.getTarget().appendChild(new Label("Hello"));

Another way to add new child is through Executions.createComponents. Please refer to java doc for Executions

Note that, we can also write java code inside *.zul, which is called zscript.



Last Update : 2022/01/19

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