[jboss-user] [JBoss Seam] - Here is a Richfaces Ajax Datascroler and Seam Example
supernovasoftware.com
do-not-reply at jboss.com
Fri Dec 14 11:26:02 EST 2007
I use the following to view large tables where fetching the all the results is not feasible. It has about 1 million rows.
It does assume that you object implements the interface Idable shown next.
|
| import java.io.IOException;
| import java.io.Serializable;
| import java.util.ArrayList;
| import java.util.HashMap;
| import java.util.List;
| import java.util.Map;
|
| import javax.faces.context.FacesContext;
|
| import org.ajax4jsf.model.DataVisitor;
| import org.ajax4jsf.model.ExtendedDataModel;
| import org.ajax4jsf.model.Range;
| import org.ajax4jsf.model.SequenceRange;
| import org.jboss.seam.ScopeType;
| import org.jboss.seam.annotations.Logger;
| import org.jboss.seam.annotations.Out;
| import org.jboss.seam.log.Log;
|
| import my.package.Idable;
|
| public abstract class BaseExtendedDataModel<T,ID extends Serializable> extends ExtendedDataModel implements BaseExtendedDataModelDAO<T, ID>{
|
| private @Logger Log log;
|
| @Out(scope=ScopeType.CONVERSATION, required=false)
| public List<T> listRow;
|
| private ID currentId;
| private Map<ID, T> wrappedData = new HashMap<ID, T>();
| private List<ID> wrappedKeys;
| private Long rowCount; // better to buffer row count locally
|
| public abstract Long getCount();
| public abstract List<T> getList(Integer firstRow, Integer maxResults);
| public abstract T findById(ID id);
|
| public void wrap(FacesContext context, DataVisitor visitor, Range range, Object argument, List<T> list) throws IOException
| {
| wrappedKeys = new ArrayList<ID>();
| wrappedData = new HashMap<ID, T>();
| for (T row : list)
| {
| Idable idable = (Idable) row;
| ID id = (ID) idable.getId();
| wrappedKeys.add(id);
| wrappedData.put(id, row);
| visitor.process(context, id, argument);
| }
| }
|
| public boolean hasById(ID id)
| {
| for (T row : listRow)
| {
| Idable idable = (Idable) row;
| Long rowId = (Long) idable.getId();
| if (rowId.equals(id))
| {
| return true;
| }
| }
| return false;
| }
|
| @Override
| public void walk(FacesContext context, DataVisitor visitor, Range range, Object argument) throws IOException
| {
| int firstRow = ((SequenceRange) range).getFirstRow();
| int maxResults = ((SequenceRange) range).getRows();
| wrap(context, visitor, range, argument, getList(firstRow, maxResults));
| }
|
| /*
| * This method normally called by Visitor before request Data Row.
| */
| @Override
| public void setRowKey(Object key)
| {
| this.currentId = (ID) key;
| }
|
| @Override
| public int getRowCount()
| {
| if(rowCount == null)
| return (rowCount = this.getCount()).intValue();
| else
| return rowCount.intValue();
| }
|
| @Override
| public boolean isRowAvailable()
| {
| if (currentId == null) {
| return false;
| } else {
| return hasById(currentId);
| }
| }
|
| /**
| * This is main way to obtain data row. It is intensively used by framework.
| * We strongly recommend use of local cache in that method.
| */
| @Override
| public Object getRowData() {
| if (currentId == null) {
| return null;
| } else {
| T ret = wrappedData.get(currentId);
| if (ret == null) {
| ret = this.findById(currentId);
| wrappedData.put(currentId, ret);
| return ret;
| } else {
| return ret;
| }
| }
| }
|
| /**
| * Unused rudiment from old JSF staff.
| */
| @Override public Object getWrappedData() { throw new UnsupportedOperationException(); }
| @Override public int getRowIndex() { throw new UnsupportedOperationException(); }
| @Override public void setRowIndex(int rowIndex) { throw new UnsupportedOperationException(); }
| @Override public void setWrappedData(Object data) { throw new UnsupportedOperationException(); }
|
| /**
| * Unused update data.
| */
| // @Override public void update() { throw new UnsupportedOperationException(); }
|
| /**
| * TODO if this is never called by the framework why is it necessary.
| */
| @Override public Object getRowKey() { if (true) throw new UnsupportedOperationException(); return currentId; }
|
| }
|
| public interface BaseExtendedDataModelDAO<T, ID> {
| |
| | }
|
|
Idable interface
| public interface Idable
| {
| public Long getId();
| }
|
I extend the base class as shown below.
| import java.util.List;
|
| import org.jboss.seam.annotations.In;
| import org.jboss.seam.annotations.Name;
|
| import mypackage.general.access.Access;
|
| @Name("accessExtendedDataModel")
| public class AccessExtendedDataModel extends BaseExtendedDataModel<Access, Long>
| {
| @In(create=true) AccessDAO accessDAO;
|
| @Override
| public Long getCount()
| {
| return accessDAO.getCount();
| }
|
| @Override
| public Access findById(Long id)
| {
| return accessDAO.findById(id);
| }
|
| @Override
| public List<Access> getList(Integer firstRow, Integer maxResults)
| {
| return listRow = accessDAO.getRange(firstRow, maxResults);
| }
|
Then in the facelets page
| <a4j:form>
| <rich:datascroller for="accessList" />
| <rich:spacer height="10" />
| <rich:dataTable id="accessList"
| value="#{accessExtendedDataModel}"
| var="accessL"
| styleClass="f_table"
| rowClasses="tr0,tr1"
| rows="30">
| <rich:column id="id">
| <f:facet name="header">id</f:facet>
| <h:outputText value="#{accessL.id}" />
| </rich:column>
| <rich:column id="User">
| <f:facet name="header">User</f:facet>
| <h:outputText value="#{accessL.usr.usr}" />
| </rich:column>
| </rich:dataTable>
| </a4j:form>
|
The scroller is now connected to the datatable. This is a first pass and was adapted for an example in the Richfaces cvs I took a while back.
The paging is all done with Ajax and only 30 objects are loaded at a time.
Any suggestions for improvement are most welcome.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4112998#4112998
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4112998
More information about the jboss-user
mailing list