The Serializable DataModel
package mypackage;
import java.io.Serializable;
import java.util.List;
import javax.faces.model.DataModel;
import javax.faces.model.DataModelEvent;
import javax.faces.model.DataModelListener;
/**
*
* SerializableListDataModel is basically the ListDataModel class from
* jsf-api-1.1, except that it implements the Serializable interface. This
* interface is needed by ICEfaces when rendering the table.
*/
public class SerializableListDataModel extends DataModel
implements
Serializable
{
public SerializableListDataModel()
{
this(null);
}
public SerializableListDataModel(List list)
{
index = -1;
setWrappedData(list);
}
public boolean isRowAvailable()
{
if (list == null) return false;
return index >= 0 && index < list.size();
}
public int getRowCount()
{
if (list == null) return -1;
else
return list.size();
}
public Object getRowData()
{
if (list == null) return null;
if (!isRowAvailable()) throw new IllegalArgumentException();
else
return list.get(index);
}
public int getRowIndex()
{
return index;
}
public void setRowIndex(int rowIndex)
{
if (rowIndex < -1) throw new IllegalArgumentException();
int old = index;
index = rowIndex;
if (list == null) return;
DataModelListener listeners[] = getDataModelListeners();
if (old != index && listeners != null)
{
Object rowData = null;
if (isRowAvailable()) rowData = getRowData();
DataModelEvent event = new DataModelEvent(this, index, rowData);
int n = listeners.length;
for (int i = 0; i < n; i++)
if (null != listeners[i]) listeners[i].rowSelected(event);
}
}
public Object getWrappedData()
{
return list;
}
public void setWrappedData(Object data)
{
if (data == null)
{
list = null;
setRowIndex(-1);
}
else
{
list = (List) data;
index = -1;
setRowIndex(0);
}
}
private int index;
private List list;
}
import java.io.Serializable;
import java.util.List;
import javax.faces.model.DataModel;
import javax.faces.model.DataModelEvent;
import javax.faces.model.DataModelListener;
/**
*
* SerializableListDataModel is basically the ListDataModel class from
* jsf-api-1.1, except that it implements the Serializable interface. This
* interface is needed by ICEfaces when rendering the table.
*/
public class SerializableListDataModel extends DataModel
implements
Serializable
{
public SerializableListDataModel()
{
this(null);
}
public SerializableListDataModel(List list)
{
index = -1;
setWrappedData(list);
}
public boolean isRowAvailable()
{
if (list == null) return false;
return index >= 0 && index < list.size();
}
public int getRowCount()
{
if (list == null) return -1;
else
return list.size();
}
public Object getRowData()
{
if (list == null) return null;
if (!isRowAvailable()) throw new IllegalArgumentException();
else
return list.get(index);
}
public int getRowIndex()
{
return index;
}
public void setRowIndex(int rowIndex)
{
if (rowIndex < -1) throw new IllegalArgumentException();
int old = index;
index = rowIndex;
if (list == null) return;
DataModelListener listeners[] = getDataModelListeners();
if (old != index && listeners != null)
{
Object rowData = null;
if (isRowAvailable()) rowData = getRowData();
DataModelEvent event = new DataModelEvent(this, index, rowData);
int n = listeners.length;
for (int i = 0; i < n; i++)
if (null != listeners[i]) listeners[i].rowSelected(event);
}
}
public Object getWrappedData()
{
return list;
}
public void setWrappedData(Object data)
{
if (data == null)
{
list = null;
setRowIndex(-1);
}
else
{
list = (List) data;
index = -1;
setRowIndex(0);
}
}
private int index;
private List list;
}
The Sortable DataModel
package mypackage;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Date;
import javax.faces.model.DataModel;
import javax.faces.model.DataModelListener;
import org.springframework.util.StringUtils;
/**
*
* SortableDataModel to make the table columns sortable.
*
*/
public class SortableDataModel extends DataModel implements Serializable
{
private DataModel model;
private Row[] rows;
public SortableDataModel()
{
}
public SortableDataModel(DataModel dataModel)
{
this.model = dataModel;
if (model != null)
{
initializeRows();
}
else
{
rows = null;
}
}
protected Row[] getRows()
{
return rows;
}
private void initializeRows()
{
int rowCnt = model.getRowCount();
if (rowCnt != -1)
{
rows = new Row[rowCnt];
for (int i = 0; i < rowCnt; ++i)
{
rows[i] = new Row(i);
}
}
}
@Override
public int getRowCount()
{
return model.getRowCount();
}
@Override
public Object getRowData()
{
return model.getRowData();
}
@Override
public int getRowIndex()
{
return model.getRowIndex();
}
@Override
public Object getWrappedData()
{
if (model == null)
{
return null;
}
return model.getWrappedData();
}
@Override
public boolean isRowAvailable()
{
return model.isRowAvailable();
}
@Override
public void setWrappedData(Object data)
{
model.setWrappedData(data);
}
@Override
public void addDataModelListener(DataModelListener listener)
{
model.addDataModelListener(listener);
}
@Override
public DataModelListener[] getDataModelListeners()
{
return model.getDataModelListeners();
}
@Override
public void removeDataModelListener(DataModelListener listener)
{
model.removeDataModelListener(listener);
}
public void setRowIndex(int rowIndex)
{
if (rowIndex == -1 || rowIndex >= model.getRowCount())
{
model.setRowIndex(rowIndex);
}
else
{
model.setRowIndex(rows[rowIndex].row);
}
}
protected class Row implements Serializable
{
private int row;
public Row(int row)
{
this.row = row;
}
public Object getData()
{
int originalIndex = model.getRowIndex();
model.setRowIndex(row);
Object thisRowData = model.getRowData();
model.setRowIndex(originalIndex);
return thisRowData;
}
}
protected abstract static class BaseComparator implements Comparator<Row>
{
private boolean ascending;
public BaseComparator(boolean ascending)
{
this.ascending = ascending;
}
public abstract int compareRowData(Row o1, Row o2);
// if the compareRowData returns 0, then use this method to further sort the
// rows. Usually this will use the column that will definitely return a
// non-zero value. The subclass comparator can override this method.
public int compareDefault(Row o1, Row o2)
{
return 0;
}
protected int compareNullValues(Object obj1, Object obj2)
{
if (obj1 != null && obj2 != null)
{
throw new IllegalArgumentException("Neither input is null.");
}
boolean s1 = (obj1 == null);
boolean s2 = (obj2 == null);
int diff = 0;
if (s1 && !s2)
{
diff = 1;
}
else if (!s1 && s2)
{
diff = -1;
}
return diff;
}
public int compare(Row o1, Row o2)
{
int diff = compareRowData(o1, o2);
if (diff == 0)
{
diff = compareDefault(o1, o2);
}
return ascending ? diff : -diff;
}
}
protected abstract static class StringComparator extends BaseComparator
{
public StringComparator(boolean ascending)
{
super(ascending);
}
public abstract String getString(Row row);
public int compareRowData(Row row1, Row row2)
{
String str1 = getString(row1);
String str2 = getString(row2);
boolean s1 = StringUtils.hasText(str1);
boolean s2 = StringUtils.hasText(str2);
int diff = 0;
if (s1 && !s2)
{
diff = 1;
}
else if (!s1 && s2)
{
diff = -1;
}
else if (!s1 && !s2)
{
diff = 0;
}
else if (s1 && s2)
{
diff = str1.compareTo(str2);
}
return diff;
}
}
protected abstract static class IntegerComparator extends BaseComparator
{
public IntegerComparator(boolean ascending)
{
super(ascending);
}
public abstract Integer getInteger(Row row);
public int compareRowData(Row bean1, Row bean2)
{
Integer int1 = getInteger(bean1);
Integer int2 = getInteger(bean2);
if (int1 != null && int2 != null)
{
return int1.intValue() - int2.intValue();
}
return compareNullValues(int1, int2);
}
}
protected abstract static class LongComparator extends BaseComparator
{
public LongComparator(boolean ascending)
{
super(ascending);
}
public abstract Long getLong(Row row);
public int compareRowData(Row row1, Row row2)
{
Long n1 = getLong(row1);
Long n2 = getLong(row2);
if (n1 != null && n2 != null)
{
Long temp = n1 - n2;
return temp.intValue();
}
return compareNullValues(n1, n2);
}
}
protected abstract static class DateComparator extends BaseComparator
{
public DateComparator(boolean ascending)
{
super(ascending);
}
public abstract Date getDate(Row row);
public int compareRowData(Row row1, Row row2)
{
Date date1 = getDate(row1);
Date date2 = getDate(row2);
if (date1 != null && date2 != null)
{
return date1.compareTo(date2);
}
return compareNullValues(date1, date2);
}
}
}
import java.io.Serializable;
import java.util.Comparator;
import java.util.Date;
import javax.faces.model.DataModel;
import javax.faces.model.DataModelListener;
import org.springframework.util.StringUtils;
/**
*
* SortableDataModel to make the table columns sortable.
*
*/
public class SortableDataModel extends DataModel implements Serializable
{
private DataModel model;
private Row[] rows;
public SortableDataModel()
{
}
public SortableDataModel(DataModel dataModel)
{
this.model = dataModel;
if (model != null)
{
initializeRows();
}
else
{
rows = null;
}
}
protected Row[] getRows()
{
return rows;
}
private void initializeRows()
{
int rowCnt = model.getRowCount();
if (rowCnt != -1)
{
rows = new Row[rowCnt];
for (int i = 0; i < rowCnt; ++i)
{
rows[i] = new Row(i);
}
}
}
@Override
public int getRowCount()
{
return model.getRowCount();
}
@Override
public Object getRowData()
{
return model.getRowData();
}
@Override
public int getRowIndex()
{
return model.getRowIndex();
}
@Override
public Object getWrappedData()
{
if (model == null)
{
return null;
}
return model.getWrappedData();
}
@Override
public boolean isRowAvailable()
{
return model.isRowAvailable();
}
@Override
public void setWrappedData(Object data)
{
model.setWrappedData(data);
}
@Override
public void addDataModelListener(DataModelListener listener)
{
model.addDataModelListener(listener);
}
@Override
public DataModelListener[] getDataModelListeners()
{
return model.getDataModelListeners();
}
@Override
public void removeDataModelListener(DataModelListener listener)
{
model.removeDataModelListener(listener);
}
public void setRowIndex(int rowIndex)
{
if (rowIndex == -1 || rowIndex >= model.getRowCount())
{
model.setRowIndex(rowIndex);
}
else
{
model.setRowIndex(rows[rowIndex].row);
}
}
protected class Row implements Serializable
{
private int row;
public Row(int row)
{
this.row = row;
}
public Object getData()
{
int originalIndex = model.getRowIndex();
model.setRowIndex(row);
Object thisRowData = model.getRowData();
model.setRowIndex(originalIndex);
return thisRowData;
}
}
protected abstract static class BaseComparator implements Comparator<Row>
{
private boolean ascending;
public BaseComparator(boolean ascending)
{
this.ascending = ascending;
}
public abstract int compareRowData(Row o1, Row o2);
// if the compareRowData returns 0, then use this method to further sort the
// rows. Usually this will use the column that will definitely return a
// non-zero value. The subclass comparator can override this method.
public int compareDefault(Row o1, Row o2)
{
return 0;
}
protected int compareNullValues(Object obj1, Object obj2)
{
if (obj1 != null && obj2 != null)
{
throw new IllegalArgumentException("Neither input is null.");
}
boolean s1 = (obj1 == null);
boolean s2 = (obj2 == null);
int diff = 0;
if (s1 && !s2)
{
diff = 1;
}
else if (!s1 && s2)
{
diff = -1;
}
return diff;
}
public int compare(Row o1, Row o2)
{
int diff = compareRowData(o1, o2);
if (diff == 0)
{
diff = compareDefault(o1, o2);
}
return ascending ? diff : -diff;
}
}
protected abstract static class StringComparator extends BaseComparator
{
public StringComparator(boolean ascending)
{
super(ascending);
}
public abstract String getString(Row row);
public int compareRowData(Row row1, Row row2)
{
String str1 = getString(row1);
String str2 = getString(row2);
boolean s1 = StringUtils.hasText(str1);
boolean s2 = StringUtils.hasText(str2);
int diff = 0;
if (s1 && !s2)
{
diff = 1;
}
else if (!s1 && s2)
{
diff = -1;
}
else if (!s1 && !s2)
{
diff = 0;
}
else if (s1 && s2)
{
diff = str1.compareTo(str2);
}
return diff;
}
}
protected abstract static class IntegerComparator extends BaseComparator
{
public IntegerComparator(boolean ascending)
{
super(ascending);
}
public abstract Integer getInteger(Row row);
public int compareRowData(Row bean1, Row bean2)
{
Integer int1 = getInteger(bean1);
Integer int2 = getInteger(bean2);
if (int1 != null && int2 != null)
{
return int1.intValue() - int2.intValue();
}
return compareNullValues(int1, int2);
}
}
protected abstract static class LongComparator extends BaseComparator
{
public LongComparator(boolean ascending)
{
super(ascending);
}
public abstract Long getLong(Row row);
public int compareRowData(Row row1, Row row2)
{
Long n1 = getLong(row1);
Long n2 = getLong(row2);
if (n1 != null && n2 != null)
{
Long temp = n1 - n2;
return temp.intValue();
}
return compareNullValues(n1, n2);
}
}
protected abstract static class DateComparator extends BaseComparator
{
public DateComparator(boolean ascending)
{
super(ascending);
}
public abstract Date getDate(Row row);
public int compareRowData(Row row1, Row row2)
{
Date date1 = getDate(row1);
Date date2 = getDate(row2);
if (date1 != null && date2 != null)
{
return date1.compareTo(date2);
}
return compareNullValues(date1, date2);
}
}
}
A Sample JSP File Using the Sortable DataModel
The following is a sample jsp file. It is actually an xhtml file because it uses a facelet template. This page also uses IceFaces to display the data page by page. It also uses Spring webflow.<ui:composition template="myFaceletTemplate.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ice="http://www.icesoft.com/icefaces/component"
xmlns:c="http://java.sun.com/jstl/core">
<ui:define name="content">
<ice:outputText styleClass="pageHeading"
value="My Page heading" />
<br />
<br />
<ice:form>
<ice:panelGroup>
<!-- Display counts about the table and the currently displayed page -->
<ice:dataPaginator id="dataScroll_2"
for="myAppData" rowsCountVar="rowsCount"
displayedRowsCountVar="displayedRowsCountVar"
firstRowIndexVar="firstRowIndex" lastRowIndexVar="lastRowIndex"
pageCountVar="pageCount" pageIndexVar="pageIndex">
<ice:outputFormat
value="{0} records found. Displaying reocrds {2} to {3} on page {4} of {5}."
styleClass="standard">
<f:param value="#{rowsCount}" />
<f:param value="#{displayedRowsCountVar}" />
<f:param value="#{firstRowIndex}" />
<f:param value="#{lastRowIndex}" />
<f:param value="#{pageIndex}" />
<f:param value="#{pageCount}" />
</ice:outputFormat>
</ice:dataPaginator>
<ice:panelGrid columns="2">
<!-- Layout table columns with column headings and 11 table rows per page -->
<ice:dataTable id="myAppData"
var="myAppSelection" styleClass="dataPaginatorTable"
value="#{myAppAdminForm.myAppSelections}"
rows="11" columnClasses="firstCol,lastCol,phoneCol,emailCol">
<ice:rowSelector
value="#{myAppSelection.selected}" multiple="true" />
<ice:column>
<f:facet name="header">
<ice:outputText id="columnSelection"
value="Selected" />
</f:facet>
<ice:selectBooleanCheckbox id="selection"
value="#{myAppSelection.selected}"
partialSubmit="true" />
</ice:column>
<ice:column>
<f:facet name="header">
<h:commandLink
action="#{myAppAdminForm.myAppSelections.sortByName}">
<ice:outputText id="columnName"
value="Name" />
</h:commandLink>
</f:facet>
<ice:outputText id="name"
value="#{myAppSelection.myApp.name}" />
</ice:column>
<ice:column>
<f:facet name="header">
<h:commandLink
action="#{myAppAdminForm.myAppSelections.sortByStartDate}">
<ice:outputText id="columnStartDate"
value="Start Date" />
</h:commandLink>
</f:facet>
<ice:outputText id="startDate"
value="#{myAppSelection.myApp.startDate}">
<f:convertDateTime type="date"
dateStyle="medium" />
</ice:outputText>
</ice:column>
</ice:dataTable>
</ice:panelGrid>
</ice:panelGroup>
<!-- Set up the buttons and links for browsing through the table
No. of pages to fast forward or rewind: 3
No. of direct links to pages: 4 -->
<ice:dataPaginator id="dataScroll_1"
for="myAppData" fastStep="3" pageCountVar="pageCount"
pageIndexVar="pageIndex" paginator="true" paginatorMaxPages="20"
styleClass="formBorderHighlight" renderFacetsIfSinglePage="false">
<f:facet name="first">
<ice:graphicImage id="firstpage_1"
url="./xmlhttp/css/xp/css-images/arrow-first.gif"
style="border:none;" title="first page" />
</f:facet>
<f:facet name="last">
<ice:graphicImage id="lastpage_1"
url="./xmlhttp/css/xp/css-images/arrow-last.gif"
style="border:none;" title="last page" />
</f:facet>
<f:facet name="previous">
<ice:graphicImage id="previouspage_1"
url="./xmlhttp/css/xp/css-images/arrow-previous.gif"
style="border:none;" title="previous page" />
</f:facet>
<f:facet name="next">
<ice:graphicImage id="nextpage_1"
url="./xmlhttp/css/xp/css-images/arrow-next.gif"
style="border:none;" title="next page" />
</f:facet>
<f:facet name="fastforward">
<ice:graphicImage id="fastforward_1"
url="./xmlhttp/css/xp/css-images/arrow-ff.gif"
style="border:none;" title="fast forward" />
</f:facet>
<f:facet name="fastrewind">
<ice:graphicImage id="fastrewind_1"
url="./xmlhttp/css/xp/css-images/arrow-fr.gif"
style="border:none;" title="fast backward" />
</f:facet>
</ice:dataPaginator>
<table>
<tr>
<td>
<ice:commandButton id="cmdSubmitSelection"
action="reviewSelections" value="Review Selections" />
<ice:commandButton action="cancel"
value="Cancel" immediate="true" />
</td>
</tr>
</table>
</ice:form>
</ui:define>
</ui:composition>
awesome this post is really and this topic is very useful for me,
ReplyDeletemore info