Matrix Model"

From Documentation
(Created page with "{{ZKDevelopersReferencePageHeader}} __TOC__ {{ZK EE}} Here we describe how to implement a matrix model (<javadoc type="interface">org.zkoss.zkmax.zul.MatrixModel</javadoc>). F...")
 
m
 
(4 intermediate revisions by 2 users not shown)
Line 4: Line 4:
 
  {{ZK EE}}
 
  {{ZK EE}}
  
Here we describe how to implement a matrix model (<javadoc type="interface">org.zkoss.zkmax.zul.MatrixModel</javadoc>). For the concept of component, model and render, please refer to [[ZK_Developer's_Reference/MVC/Model/List_Model#Model-driven_Display|the Model-driven Display section]].
+
Here we describe how to implement a matrix model (<javadoc type="interface">org.zkoss.zkmax.zul.MatrixModel</javadoc>). For the concept of component, model and renderer, please refer to [[ZK_Developer's_Reference/MVC/Model/List_Model#Model-driven_Display|the Model-driven Display section]].
  
By default, ZK does not provide a built-in model implementation class for ''MatrixModel'' because Biglistbox is designed to handle unlimited data set, therefore, there is no need to handle model data in memory. This usage is application-dependent and varies from case to case. However, you can extend your own implementation from the <javadoc type="interface">org.zkoss.zul.AbstractListModel</javadoc> skeleton class.
+
By default, ZK does not provide a built-in model implementation class for ''MatrixModel'' because [[ZK Component Reference/Data/Biglistbox | Biglistbox]] is designed to handle unlimited data set, therefore, there is no need to handle model data in memory. This usage is application-dependent and varies from case to case. However, you can extend your own implementation from the <javadoc type="interface">org.zkoss.zul.AbstractListModel</javadoc> skeleton class.
  
To implement a ''MatrixModel'' needs to consider the performance issue that handles a huge data set in memory with Java Collection Framework. The issue is when using the default implementation of <i>Java Collection Framework</i> as it goes through every entry to gather the value of <b><i>hashCode</i></b> when searching the key in <b>Map/Set</b> or to check every entry for <b>equals</b> and <b>toString</b> functions. This implementation method greatly reduces the performance of <i><b>Biglistbox</b></i>, therefore, to use the <i><b>Biglistbox</b></i> component with <b><i>MatrixModel</i></b>, we need to implement a clever and simple <b><i>List</i></b> for traversing huge data sets.
+
To implement a ''MatrixModel'', one needs to consider the performance issue that handles a huge data set in memory with Java Collection Framework. The issue is when using the default implementation of <i>Java Collection Framework</i> as it goes through every entry to gather the value of <b><i>hashCode</i></b> when searching the key in <b>Map/Set</b> or to check every entry for <b>equals</b> and <b>toString</b> functions. This implementation method greatly reduces the performance of <i><b>Biglistbox</b></i>. Therefore, to use the <i><b>Biglistbox</b></i> component with <b><i>MatrixModel</i></b>, we need to implement a clever and simple <b><i>List</i></b> for traversing huge data sets.
  
 
== FakerKeyList ==
 
== FakerKeyList ==
 
In this example, we create a ''FakerKeyList'' to implement the ''List'' interface for ''MatrixModel'' to handle the partial big data in memory.
 
In this example, we create a ''FakerKeyList'' to implement the ''List'' interface for ''MatrixModel'' to handle the partial big data in memory.
<source lang="java" high="4,23,28,38">
+
<source lang="java" highlight="4,23,28,38">
 
private class FakerKeyList<T> extends AbstractList<T> {
 
private class FakerKeyList<T> extends AbstractList<T> {
 
final int _size;
 
final int _size;
Line 64: Line 64:
 
Following is the fragment code:
 
Following is the fragment code:
  
<source lang="java" high="9,14">
+
<source lang="java" highlight="9,14">
 
public class FakerMatrixModel<Head extends List, Row extends List, Cell, Header> extends
 
public class FakerMatrixModel<Head extends List, Row extends List, Cell, Header> extends
 
AbstractListModel<Row> implements MatrixModel<Row, Head, Cell, Header>, Sortable {
 
AbstractListModel<Row> implements MatrixModel<Row, Head, Cell, Header>, Sortable {
Line 117: Line 117:
  
 
== Resource ==
 
== Resource ==
All of the example above can be found here - [https://github.com/zkoss/zk/blob/master/zktest/src/org/zkoss/zktest/test2/big/FakerMatrixModel.java  Github's FakerMatrixModel source code]
+
All of the examples above can be found here - [https://github.com/zkoss/zk/blob/master/zktest/src/org/zkoss/zktest/test2/big/FakerMatrixModel.java  Github's FakerMatrixModel source code]
 
=Version History=
 
=Version History=
{{LastUpdated}}
+
 
{| border='1px' | width="100%"
+
{| class='wikitable' | width="100%"
 
! Version !! Date !! Content
 
! Version !! Date !! Content
 
|-
 
|-
 
| 6.0.1
 
| 6.0.1
 
| March 2012
 
| March 2012
| The Biglistbox and MatrixModel was introduced
+
| The Biglistbox and MatrixModel were introduced
 
|}
 
|}
  
 
{{ZKDevelopersReferencePageFooter}}
 
{{ZKDevelopersReferencePageFooter}}

Latest revision as of 01:58, 30 January 2024

  • Available for ZK:
  • http://www.zkoss.org/product/zkhttp://www.zkoss.org/whyzk/zkeeVersion ee.png

Here we describe how to implement a matrix model (MatrixModel). For the concept of component, model and renderer, please refer to the Model-driven Display section.

By default, ZK does not provide a built-in model implementation class for MatrixModel because Biglistbox is designed to handle unlimited data set, therefore, there is no need to handle model data in memory. This usage is application-dependent and varies from case to case. However, you can extend your own implementation from the AbstractListModel skeleton class.

To implement a MatrixModel, one needs to consider the performance issue that handles a huge data set in memory with Java Collection Framework. The issue is when using the default implementation of Java Collection Framework as it goes through every entry to gather the value of hashCode when searching the key in Map/Set or to check every entry for equals and toString functions. This implementation method greatly reduces the performance of Biglistbox. Therefore, to use the Biglistbox component with MatrixModel, we need to implement a clever and simple List for traversing huge data sets.

FakerKeyList

In this example, we create a FakerKeyList to implement the List interface for MatrixModel to handle the partial big data in memory.

private class FakerKeyList<T> extends AbstractList<T> {
	final int _size;
	Map<String, T> _updateCache = new HashMap<String,T> ();
	final Fun<?> _fn;
	final String _key;

	public FakerKeyList(int size, int key, Fun<?> fn) {
		_size = size;
		_key = key + "_" + size;
		_fn = fn;
	}

	@Override
	public T get(int index) {
		// if changed, returns the changed value
		Object val = _updateCache.get(String.valueOf(index));
		if (val != null)
			return (T) val;
		return (T) _fn.apply(index);
	}

	@Override
	public int hashCode() {
		return _key.hashCode();
	}
		
	@Override
	public boolean equals(Object obj) {
		if (obj == this)
			return true;
		if (obj instanceof FakerKeyList) {
			return _key.equals(((FakerKeyList)(obj))._key);
		}
		return false;
	}
	
	@Override
	public String toString() {
		return _key;
	}

	// omitted...
}

As you can see, we use a key string as the key for toString, hashCode, and equals methods to speed up searching time. Fun class on the other hand, is a handy class to render the model data for this example.

FakerMatrixModel

In this example, we create a FakerMatrixModel to implement MatrixModel. Following is the fragment code:

public class FakerMatrixModel<Head extends List, Row extends List, Cell, Header> extends
		AbstractListModel<Row> implements MatrixModel<Row, Head, Cell, Header>, Sortable {

	// omitted...

	private boolean _sortDir = true;

	@Override
	public Row getElementAt(int index) {
		final int rowIndex = _sortDir ? index : getSize() - index - 1; // handle the sorting
		final String key = String.valueOf(rowIndex);
		List<String> value = _rowCache.get(key);
		if (value == null) {
			value = new FakerKeyList<String>(_colSize, rowIndex, new Fun() {
				@Override
				public Object apply(int index) {
					return "y = " + rowIndex;
				}});
			_rowCache.put(key, value);
		}
		return (Row) value;
	}

	// omitted...
}

MatrixModel is extended from the ListModel interface and uses the getElementAt(int) method to receive row data from the FakerKeyList object that implements the List interface.

Sortable Model

The MatrixModel can also support Sortable interface. In your implementor class you can just implement the Sortable interface and provide Sortable.sort(Comparator, boolean) and Sortable.getSortDirection(Comparator) methods.

For example,

	public void sort(Comparator cmpr, boolean ascending) {
		_sorting = cmpr;
		_sortDir = ascending;
		fireEvent(ListDataEvent.STRUCTURE_CHANGED, -1, -1);
	}

	@Override
	public String getSortDirection(Comparator cmpr) {
		if (Objects.equals(_sorting, cmpr))
			return _sortDir ? "ascending" : "descending";
		return "natural";
	}

As you can see, we fire a data change event with ListDataEvent.STRUCTURE_CHANGED attribute to notify the component that model data has been changed.

Notify for Data Updates

MatrixModel is the same as ListModel when notify for data updates, please refer to ListMode#Notify_for_Data_Updates

Resource

All of the examples above can be found here - Github's FakerMatrixModel source code

Version History

Version Date Content
6.0.1 March 2012 The Biglistbox and MatrixModel were introduced



Last Update : 2024/01/30

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