Implementing ZK MVC"

From Documentation
m
m
Line 3: Line 3:
 
The MVC is developers' favorite pattern as it neatly separates various application layers in a clear manner. ZK fosters this process by allowing UI declaration to be done using an XML declarative language. It should be noted, however, that we can create Swing programmatic UIs using Richlets.
 
The MVC is developers' favorite pattern as it neatly separates various application layers in a clear manner. ZK fosters this process by allowing UI declaration to be done using an XML declarative language. It should be noted, however, that we can create Swing programmatic UIs using Richlets.
  
ZK MVC revolves around two key items, the <javadoc>org.zkoss.zk.ui.util.GenericForwardComposer</javadoc> and the apply attribute. The <javadoc>org.zkoss.zk.ui.util.GenericForwardComposer</javadoc> is a utility class which adds auto-wire functionality to provide access to UI objects from Java code without any effort. Let’s see the demonstration of how to add  this functionality into the login page.
+
ZK MVC revolves around two key items, the <javadoc>org.zkoss.zk.ui.select.SelectorComposer</javadoc> and the apply attribute. The <javadoc>org.zkoss.zk.ui.select.SelectorComposer</javadoc> is a utility class which adds auto-wire functionality to provide access to UI objects from Java code without any effort. Let’s see the demonstration of how to add  this functionality into the login page.
  
  
===Creating a controller (GenericForwardComposed) & applying it===
+
===Creating a controller (SelectorComposer) & applying it===
  
  
First, we need to create a controller class named LoginViewCtrl which extends from the <javadoc>org.zkoss.zk.ui.util.GenericForwardComposer</javadoc>, this is a trivial matter in Java.
+
First, we need to create a controller class named LoginViewCtrl which extends from the <javadoc>org.zkoss.zk.ui.select.SelectorComposer</javadoc>, this is a trivial matter in Java.
  
 
<source lang="java">
 
<source lang="java">
public class LoginViewCtrl extends GenericForwardComposer
+
public class LoginViewCtrl extends SelectorComposer<Window>
</source >
+
</source>
 +
 
 +
SelectorComposer requires a control type, in this case we use Window as the root component we will apply the composer to will be a Window. For ease of use developers can use Component as SelectorComposer's type allowing the controller to work with any component as the root.
 
   
 
   
 
To create this class, we need to link it to our ZUL file. This has to be done by indicating the apply attribute.   
 
To create this class, we need to link it to our ZUL file. This has to be done by indicating the apply attribute.   
Line 19: Line 21:
 
<source lang="xml" high="4">
 
<source lang="xml" high="4">
 
<?page title="ZK Store - Login"?>
 
<?page title="ZK Store - Login"?>
<window id="loginWin" border="normal" width="300px"  
+
<window id="loginWin" border="normal" width="300px"
 
title="You are using: ${desktop.webApp.version}"
 
title="You are using: ${desktop.webApp.version}"
apply="demo.web.ui.ctrl.LoginViewCtrl">
+
apply="demo.web.ui.ctrl.LoginViewCtrl" mode="overlapped"
+
position="center,center">
 
<grid>
 
<grid>
 
<rows>
 
<rows>
<row> Name: <textbox id="nameTxb"/></row>
+
<row>
<row> Password:<textbox id="passwordTxb" type="password"/></row>
+
Name:
 +
<textbox id="nameTxb" />
 +
</row>
 +
<row>
 +
Password:
 +
<textbox id="passwordTxb" type="password" />
 +
</row>
 
</rows>
 
</rows>
 
</grid>
 
</grid>
<button id="confirmBtn" label="confirm"/>
+
<button id="confirmBtn" label="confirm" />
<label id="mesgLbl"/>
+
<label id="mesgLbl" />
 
</window>
 
</window>
</source >
+
</source>
  
 
As demonstrated in the code above, we set the apply attributes value to a full class name with path. In this case, it would be <mp>demo.web.ui.ctrl.LoginViewCtrl</mp>.
 
As demonstrated in the code above, we set the apply attributes value to a full class name with path. In this case, it would be <mp>demo.web.ui.ctrl.LoginViewCtrl</mp>.
Line 38: Line 46:
 
===Auto-wiring components and events ===
 
===Auto-wiring components and events ===
  
When the <javadoc>org.zkoss.zk.ui.util.GenericForwardComposer</javadoc> is applied, we can declare the components within the class as private variables which will be auto wired with the equivalent ZUL components.
+
When the <javadoc>org.zkoss.zk.ui.select.SelectorComposer</javadoc> is applied, we can declare the components within the class as private variables which will be auto wired with the equivalent ZUL components when the annotation @Wire is present.
  
<source lang="java" high="9,10,11">
+
<syntax lang="java" high="3,4,6,7">
import org.zkoss.zul.Label;
+
public class LoginViewCtrl extends SelectorComposer<Window> {
import org.zkoss.zul.Textbox;
+
 
+
@Wire
import demo.model.bean.User;
+
private Textbox nameTxb, passwordTxb;
import demo.web.UserCredentialManager;
+
 
+
@Wire
public class LoginViewCtrl extends GenericForwardComposer {
 
 
 
private Textbox nameTxb;
 
private Textbox passwordTxb;
 
 
private Label mesgLbl;
 
private Label mesgLbl;
 
}
 
}
</source>
+
</syntax>
  
You can now access the UI components on the server-side and interact with them. All the wiring and communication is taken care of by ZK automatically.
+
You can now access the UI components on the server-side and interact with them. All the wiring and communication is taken care of by ZK automatically. There are many more advanced @Wire  options for more infomation on those please [[ZK_Developer's_Reference/MVC/Controller/Wire_Event_Listeners | click here]].
  
The next step is to enable the capturing of events. In this specific case we need to capture the <mp>onClick</mp> event of the button <mp>confirmBtn</mp>. To do so, we need to create a method with a specific signature. In this case, we can use the event name followed by a $ and the component ID. The method signature is as follows:
+
The next step is to enable the capturing of events. In this specific case we need to capture the <mp>onClick</mp> event of the button <mp>confirmBtn</mp>. To do so, we need to create a method with a specific annotation. In this case, we can use the event name followed by a an = then a # to dictate that the component ID will come next then the component ID. The method is as follows:
  
<source lang="java">
+
<syntax lang="java">
public void onClick$confirmBtn()
+
@Listen("onOK=#passwordTxb")
</source>
+
public void onOK() {
 +
doLogin();
 +
}
 +
</syntax>
  
Notice that the method does not take any parameters, however, if necessary, the method can take an <javadoc>org.zkoss.zk.ui.event.Event</javadoc> object as a parameter or the subsequent subclass which is applicable to the context.
+
Notice that the method does not take any parameters, however, if necessary, the method can take an <javadoc>org.zkoss.zk.ui.event.Event</javadoc> object as a parameter or the subsequent subclass which is applicable to the context. The @Listen annotation takes a selector string, for more information on how to construct selectors please refer to [[link not here yet]].
  
Lastly, we need to consider that people coming to the login.zul page may already be logged in just as our use case indicates. Therefore, we need to set up a mechanism that checks whether that is the case before loading the UI. This is done by overriding the <javadoc>org.zkoss.zk.ui.util.GenericForwardComposer</javadoc> method <javadoc method="doAfterCompose(org.zkoss.zk.ui.Component)">org.zkoss.zk.ui.util.GenericForwardComposer</javadoc> which would be called when the events and components are wired. Thus, if you override this method, please make sure to call the super method. At this stage, your <javadoc method="doAfterCompose(org.zkoss.zk.ui.Component)" class="false">org.zkoss.zk.ui.util.GenericForwardComposer</javadoc> method should look like this:
+
Lastly, we need to consider that people coming to the login.zul page may already be logged in just as our use case indicates. Therefore, we need to set up a mechanism that checks whether that is the case before loading the UI. This is done by overriding the <javadoc>org.zkoss.zk.ui.select.SelectorComposer</javadoc> method <javadoc method="doAfterCompose(org.zkoss.zk.ui.Component)">org.zkoss.zk.ui.select.SelectorComposer</javadoc> which would be called when the events and components are wired. Thus, if you override this method, please make sure to call the super method. At this stage, your <javadoc method="doAfterCompose(org.zkoss.zk.ui.Component)" class="false">org.zkoss.zk.ui.select.SelectorComposer</javadoc> method should look like this:
  
<source lang="java">
+
<syntax lang="java">
 
public void doAfterCompose(Component comp) throws Exception {
 
public void doAfterCompose(Component comp) throws Exception {
 
super.doAfterCompose(comp);
 
super.doAfterCompose(comp);
Line 73: Line 80:
 
//to be implemented, let’s check for a login
 
//to be implemented, let’s check for a login
 
}
 
}
</source>
+
</syntax>
  
 
Now we have the insights of what advantages ZK provides us with by wiring the components, events, and data automatically. We need to move on to deal with our goal of implementing a user management system to check credentials and redirect it according to our use case. The next section walks you through how user credentials is implemented using a session.
 
Now we have the insights of what advantages ZK provides us with by wiring the components, events, and data automatically. We need to move on to deal with our goal of implementing a user management system to check credentials and redirect it according to our use case. The next section walks you through how user credentials is implemented using a session.
  
 
{{ZKEssentialsPageFooter}}
 
{{ZKEssentialsPageFooter}}

Revision as of 02:28, 8 February 2012

Stop.png This article is out of date, please refer to http://books.zkoss.org/zkessentials-book/master/ for more up to date information.


The MVC is developers' favorite pattern as it neatly separates various application layers in a clear manner. ZK fosters this process by allowing UI declaration to be done using an XML declarative language. It should be noted, however, that we can create Swing programmatic UIs using Richlets.

ZK MVC revolves around two key items, the SelectorComposer and the apply attribute. The SelectorComposer is a utility class which adds auto-wire functionality to provide access to UI objects from Java code without any effort. Let’s see the demonstration of how to add this functionality into the login page.


Creating a controller (SelectorComposer) & applying it

First, we need to create a controller class named LoginViewCtrl which extends from the SelectorComposer, this is a trivial matter in Java.

public class LoginViewCtrl extends SelectorComposer<Window>

SelectorComposer requires a control type, in this case we use Window as the root component we will apply the composer to will be a Window. For ease of use developers can use Component as SelectorComposer's type allowing the controller to work with any component as the root.

To create this class, we need to link it to our ZUL file. This has to be done by indicating the apply attribute.

<?page title="ZK Store - Login"?>
<window id="loginWin" border="normal" width="300px"
	title="You are using: ${desktop.webApp.version}"
	apply="demo.web.ui.ctrl.LoginViewCtrl" mode="overlapped"
	position="center,center">
	<grid>
		<rows>
			<row>
				Name:
				<textbox id="nameTxb" />
			</row>
			<row>
				Password:
				<textbox id="passwordTxb" type="password" />
			</row>
		</rows>
	</grid>
	<button id="confirmBtn" label="confirm" />
	<label id="mesgLbl" />
</window>

As demonstrated in the code above, we set the apply attributes value to a full class name with path. In this case, it would be demo.web.ui.ctrl.LoginViewCtrl.

Auto-wiring components and events

When the SelectorComposer is applied, we can declare the components within the class as private variables which will be auto wired with the equivalent ZUL components when the annotation @Wire is present.

<syntax lang="java" high="3,4,6,7"> public class LoginViewCtrl extends SelectorComposer<Window> {

@Wire private Textbox nameTxb, passwordTxb;

@Wire private Label mesgLbl; } </syntax>

You can now access the UI components on the server-side and interact with them. All the wiring and communication is taken care of by ZK automatically. There are many more advanced @Wire options for more infomation on those please click here.

The next step is to enable the capturing of events. In this specific case we need to capture the onClick event of the button confirmBtn. To do so, we need to create a method with a specific annotation. In this case, we can use the event name followed by a an = then a # to dictate that the component ID will come next then the component ID. The method is as follows:

<syntax lang="java"> @Listen("onOK=#passwordTxb") public void onOK() { doLogin(); } </syntax>

Notice that the method does not take any parameters, however, if necessary, the method can take an Event object as a parameter or the subsequent subclass which is applicable to the context. The @Listen annotation takes a selector string, for more information on how to construct selectors please refer to link not here yet.

Lastly, we need to consider that people coming to the login.zul page may already be logged in just as our use case indicates. Therefore, we need to set up a mechanism that checks whether that is the case before loading the UI. This is done by overriding the SelectorComposer method SelectorComposer.doAfterCompose(Component) which would be called when the events and components are wired. Thus, if you override this method, please make sure to call the super method. At this stage, your doAfterCompose(Component) method should look like this:

<syntax lang="java"> public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp);

//to be implemented, let’s check for a login } </syntax>

Now we have the insights of what advantages ZK provides us with by wiring the components, events, and data automatically. We need to move on to deal with our goal of implementing a user management system to check credentials and redirect it according to our use case. The next section walks you through how user credentials is implemented using a session.


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