Richlets"

From Documentation
m (deprecated)
m (correct highlight (via JWB))
 
Line 16: Line 16:
  
 
=== Implement the org.zkoss.zk.ui.Richlet interface ===
 
=== Implement the org.zkoss.zk.ui.Richlet interface ===
All richlets must implement the <javadoc type="interface">org.zkoss.zk.ui.Richlet</javadoc> interface. To simplify the task of implementing the required methods, you can extend <javadoc>org.zkoss.zk.ui.GenericRichlet</javadoc>. Then, when the specified URL is requested, the <tt>service</tt> method is called, and you can create the user interface then.
+
All richlets must implement the <javadoc type="interface">org.zkoss.zk.ui.Richlet</javadoc> interface. To simplify the task of implementing the required methods, you can extend <javadoc>org.zkoss.zk.ui.GenericRichlet</javadoc>. Then, when the specified URL is requested, the <code>service</code> method is called, and you can create the user interface then.
  
 
<source lang="java" >
 
<source lang="java" >
Line 51: Line 51:
 
</source>
 
</source>
 
   
 
   
Like servlets, you can implement the <tt>init</tt> and <tt>destroy</tt> methods to initialize and to destroy the richlet when it is loaded. Like servlet, a richlet is loaded once and serves all requests for the URL with which it is associated.
+
Like servlets, you can implement the <code>init</code> and <code>destroy</code> methods to initialize and to destroy the richlet when it is loaded. Like servlet, a richlet is loaded once and serves all requests for the URL with which it is associated.
  
 
==== One Richlet per URL ====
 
==== One Richlet per URL ====
Like servlets, a single richlet is created and shared for all users. In other words, the richlet (at least the <tt>service</tt> method) must be thread-safe. On the other hand, components are not shareable. Each desktop has an independent set of components. Therefore, it is generally not a good idea to store components as a data member of a richlet.
+
Like servlets, a single richlet is created and shared for all users. In other words, the richlet (at least the <code>service</code> method) must be thread-safe. On the other hand, components are not shareable. Each desktop has an independent set of components. Therefore, it is generally not a good idea to store components as a data member of a richlet.
  
 
There are many ways to solve this issue. A typical one is to use another class for holding the components for each desktop, as illustrated below.
 
There are many ways to solve this issue. A typical one is to use another class for holding the components for each desktop, as illustrated below.
Line 84: Line 84:
  
 
=== Configure web.xml and zk.xml ===
 
=== Configure web.xml and zk.xml ===
After implementing the richlet, you can define the richlet in <tt>zk.xml</tt> with the following statement:
+
After implementing the richlet, you can define the richlet in <code>zk.xml</code> with the following statement:
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 93: Line 93:
 
</source>
 
</source>
  
After declaring a richlet, you can map it to any number of URLs using the <tt>richlet-mapping</tt> element as shown below.
+
After declaring a richlet, you can map it to any number of URLs using the <code>richlet-mapping</code> element as shown below.
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 106: Line 106:
 
</source>
 
</source>
  
By default, richlets are disabled. To enable them, add the following declaration to <tt>web.xml</tt>. Once enabled, you can add as many as richlets as you want without modifying <tt>web.xml</tt> any more.
+
By default, richlets are disabled. To enable them, add the following declaration to <code>web.xml</code>. Once enabled, you can add as many as richlets as you want without modifying <code>web.xml</code> any more.
  
 
<source lang="xml" >
 
<source lang="xml" >
Line 117: Line 117:
 
Then, you can visit [http://localhost:8080/PROJECT_NAME/zk/test http://localhost:8080/PROJECT_NAME/zk/test] to request the richlet.
 
Then, you can visit [http://localhost:8080/PROJECT_NAME/zk/test http://localhost:8080/PROJECT_NAME/zk/test] to request the richlet.
  
The URL specified in the <tt>url-pattern</tt> element must start with <tt>/</tt>. If the URI ends with <tt>/*</tt>, then it is matched to all request with the same prefix. To retrieve the request's actual URL, you can check the value returned by the <tt>getRequestPath</tt> method of the current page.
+
The URL specified in the <code>url-pattern</code> element must start with <code>/</code>. If the URI ends with <code>/*</code>, then it is matched to all request with the same prefix. To retrieve the request's actual URL, you can check the value returned by the <code>getRequestPath</code> method of the current page.
  
 
<source lang="java" >
 
<source lang="java" >
Line 127: Line 127:
 
</source>
 
</source>
 
   
 
   
'''Tip''': By specifying <tt>/*</tt> as the <tt>url-pattern</tt>, you can map all unmatched URLs to your richlet.
+
'''Tip''': By specifying <code>/*</code> as the <code>url-pattern</code>, you can map all unmatched URLs to your richlet.
  
 
{{ ZKDevelopersGuidePageFooter}}
 
{{ ZKDevelopersGuidePageFooter}}

Latest revision as of 10:39, 19 January 2022

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


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

A richlet is a small Java program that creates all necessary components in response to user's request.

When a user requests the content of an URL, the ZK loader checks if the resource of the specified URL is a ZUML page or a richlet. If it is a ZUML page, then the ZK loader creates components automatically based on the ZUML page's content as we described in the previous chapters.

If the resource is a richlet, the ZK loader hands over the processing to the richlet. What and how to create components are all handled by the richlet. In other words, it is the developer's job to create all necessary components programmatically in response to the request.

The choice between ZUML pages and richlets depends on your preference. Most developers find ZUML pages simpler and more readable.

It is straightforward to implement a richlet. First, implement the Richlet interface and then declare the association of the richlet with a URL.

Implement the org.zkoss.zk.ui.Richlet interface

All richlets must implement the Richlet interface. To simplify the task of implementing the required methods, you can extend GenericRichlet. Then, when the specified URL is requested, the service method is called, and you can create the user interface then.

 package org.zkoss.zkdemo;

 import org.zkoss.zk.ui.Page;
 import org.zkoss.zk.ui.GenericRichlet;
 import org.zkoss.zk.ui.event.*;
 import org.zkoss.zul.*;

 public class TestRichlet extends GenericRichlet {
     //Richlet//
     public void service(Page page) {
         page.setTitle("Richlet Test");

         final Window w = new Window("Richlet Test", "normal", false);
         new Label("Hello World!").setParent(w);
         final Label l = new Label();
         l.setParent(w);

         final Button b = new Button("Change");
         b.addEventListener(Events.ON_CLICK,
             new EventListener() {
                 int count;
                 public void onEvent(Event evt) {
                     l.setValue("" + ++count);
                 }
             });
         b.setParent(w);

         w.setPage(page);
     }
 }

Like servlets, you can implement the init and destroy methods to initialize and to destroy the richlet when it is loaded. Like servlet, a richlet is loaded once and serves all requests for the URL with which it is associated.

One Richlet per URL

Like servlets, a single richlet is created and shared for all users. In other words, the richlet (at least the service method) must be thread-safe. On the other hand, components are not shareable. Each desktop has an independent set of components. Therefore, it is generally not a good idea to store components as a data member of a richlet.

There are many ways to solve this issue. A typical one is to use another class for holding the components for each desktop, as illustrated below.

import org.zkoss.zk.ui.Page;
import org.zkoss.zul.Window;


 class MyApp { //one per desktop
     Window _main;
     MyApp(Page page) {
         _main = new Window();
         _main.setPage(page);
     }
 }
 
import org.zkoss.zk.ui.GenericRichlet;
import org.zkoss.zk.ui.Page;

class MyRichlet extends GenericRichlet {
	public void service(Page page) {
		new MyApp(page); //create and forget
    }
}

Configure web.xml and zk.xml

After implementing the richlet, you can define the richlet in zk.xml with the following statement:

<richlet>
    <richlet-name>Test</richlet-name>
    <richlet-class>org.zkoss.zkdemo.TestRichlet</richlet-class>
</richlet>

After declaring a richlet, you can map it to any number of URLs using the richlet-mapping element as shown below.

<richlet-mapping>
    <richlet-name>Test</richlet-name>
    <url-pattern>/test</url-pattern>
</richlet-mapping>
<richlet-mapping>
    <richlet-name>Test</richlet-name>
    <url-pattern>/some/more/*</url-pattern>
</richlet-mapping>

By default, richlets are disabled. To enable them, add the following declaration to web.xml. Once enabled, you can add as many as richlets as you want without modifying web.xml any more.

<servlet-mapping>
    <servlet-name>zkLoader</servlet-name>
    <url-pattern>/zk/*</url-pattern>
</servlet-mapping>

Then, you can visit http://localhost:8080/PROJECT_NAME/zk/test to request the richlet.

The URL specified in the url-pattern element must start with /. If the URI ends with /*, then it is matched to all request with the same prefix. To retrieve the request's actual URL, you can check the value returned by the getRequestPath method of the current page.

 public void service(Page page) {
     if ("/some/more/hi".equals(page.getRequestPath()) {
         ...
     }
 }

Tip: By specifying /* as the url-pattern, you can map all unmatched URLs to your richlet.



Last Update : 2022/01/19

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