How to realize the idea of live data in a Grid

From Documentation
DocumentationSmall Talks2007MarchHow to realize the idea of live data in a Grid
How to realize the idea of live data in a Grid

Author
Robbie Cheng, Engineer, Potix Corporation
Date
March 19, 2007
Version
Applicable to ZK Freshly after March 12, 2007


Introduction

In the past,only Listbox supports "live data" since ZK's version 1.0. It's an encouraging news that Grid also supports "live data" from now on. Both Grid and Listbox are used to display data in the form of a table, however, there exists one major difference of their purposes. Since the purpose of Listbox is especially for the scenario of selectable data, Grid is more suitable for the case of table-like presentation data. Thus, developer could adopt the appropriate choice depends on different circumstances.

The main idea of "live data" is to separate data from the view. Developers only have to manipulate the data model, and the data of view (UI Component) will be updated accordingly. Secondly, it shortens the response time of user since only the required data will be downloaded at the first time. To fulfill this requirement, it requires implementations of two Interfaces,including org.zkoss.zul.ListModel and org.zkoss.zul.RowRenderer. RowRenderer is responsible for render data stored in the ListModel to the specified row in the Grid. In the following paragraphs, the usage and demonstration of "live data" in Grid will be introduced.


Three Steps to Use Live Data

1. Prepare the data in the form of ListModel. ZK has a concrete implementation called org.zkoss.zul.SimpleListModel for representing an array of objects.

2. Implement the org.zkoss.zul.RowRenderer interface for rendering a row of data into the Grid.

  • This is optional. If it is not specified, the default rowrender is used to render the data into the first column.
  • You could implement different renderers for represent the same data in different views.

3. Specify the data in the model property, and, optionally, the rowrender in the rowRenderer property.


Single-Column Example

In the following example, an array of data("data") is prepared , it is passed as a parameter for the generation of a ListModel("strset"). Last, asign this ListModel into a Grid by setting the model of the Grid.

   <window title="Live grid" border="normal">
   <zscript>
   
   String[] data = new String[30];
   for(int j=0; j < data.length; ++j) {
	 data[j] = "option "+j;
	 }
	 
   ListModel strset = new SimpleListModel(data);
   
   </zscript>
   <grid width="100px" height="100px" model="${strset}">
	   <columns>
		 <column label="options"/>
	   </columns>
   </grid>
   </window>


Two-Columns Example

Since the default rowrender only satisfies the scenario of single-column, a customized rowrender must be implemented to commit the scenario of multi-column. In the following example, a two-columns live data for grid is demonstrated.


1.Prepare the Data Model

The first step is to prepare required data. A two-way array is adoped in this expample and it is passed as a parameter for the generation of a ListModel which is implemented by SimpleListModel. In addtion, ListModel now supports various data types,including Array, List, Map, and Set in the form of ListModelArray,ListModelList, ListModelMap,and ListModelSet.

	 //prepare the data model 
	 String[][] model = new String[100][2]; 
	 for(int j=0; j < model.length; ++j) { 
		model[j][0] = "key"+j;
		model[j][1] = "value"+j; 
	 } 
	 ListModel strset = new SimpleListModel(model);


2.Define the RowRenderer Class

Secondly, to define a class which implements the interface RowRenderer,its method render(Row row, java.lang.Object data) is required to be implenmented.

Method render(Row row, java.lang.Object data)
row - The row to render the result.
data - Returned from ListModel.getElementAt()

In additon to pass required paremters into the method render(), the form of view (UI Component) for displaying data in the Grid also has to be defined, and any component which is supported by Grid could be adopted. In this example, Label is adopted, and the last step is to render Label into the specified row in the Grid by calling Label.setParent(Row row).

	 rowRenderer.java
	 
	 //define the RowRenderer class 
	 public class rowRenderer implements RowRenderer{ 
	 
	 public void render(Row row, java.lang.Object data) {
		 String[] _data = (String[])data;
		 new Label(_data[0]).setParent(row); 
		 new Label(_data[1]).setParent(row);
			}


3.Specify model and rowRenderer Property

The properties of model and rowRenderer could be specified directly in the Grid. In this example,methods, Grid.setModel() and Grid.setRowRenderer() are adopted to specify required objects for realizing the idea of "live data".

	 <window title="Two-Column Live Data Demo" border="normal"> 
	 
	   <grid id="mygrid" height="100px" width="400px">
		  <columns>
			  <column label="key"/>
			  <column label="value"/>
			</columns>
	   </grid>
		
	 <zscript><![CDATA[        
	 //prepare the data model 
	 String[][] model = new String[100][2]; 
	 
	 for(int j=0; j < model.length; ++j) {
		  model[j][0] = "key"+j;
		  model[j][1] = "value"+j; 
	 } 
	 
	 ListModel strset = new SimpleListModel(model);
	 mygrid.setModel(strset);
		mygrid.setRowRenderer(new rowRenderer());
	 ]]></zscript> 
	 
	 </window>


Example Code

Download the example code from here.


More Interfaces to Implement

  • For better control, your rowrender can also implement RowRendererExt.
  • In addition, you could also implement RendererCtrl to render all rows for the same request while starting an transaction.


Download the example code here.




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