It was left that way to provide identical backward compatible behavior. However, you should be able to subclass (or use) BaseSortableModel instead of the default sortable model.
On 11/27/07, CatalinPetrisor <[EMAIL PROTECTED]> wrote: > > That's a very good idea. However, in the latest svn sources the HtmlDataTable > component still uses SortableModel class to set the current sort column. > Wouldn't be normal to use BaseSortableModel class to allow extensibility? > > Thanks. > > > Mike Kienenberger wrote: > > > > As a first step in this process, I've separated SortableDataModel into > > SortableDataModel (current behavior, final, subclass of > > BaseSortableDataModel) and BaseSortableDataModel (extendable, works on > > Comparators). > > > > I tested all of the simple examples involving dataTable at one point, > > but it's possible that something may have slipped by me that I didn't > > notice. > > > > > > On 3/14/07, Mike Kienenberger <[EMAIL PROTECTED]> wrote: > >> I took a look at SortableModel and t:dataTable sorting again last > >> night. My requirements in most cases are to simply specify a sort > >> order in the page code, not to allow end-users to manipulate the sort > >> order. From what I can tell, there's no easy way to do this. I > >> documented the most effective method I could find on the wiki under a > >> "static sorting" subheading, but even that method leaves unnecessary > >> links in the column headers. > >> > >> At the same time, I looked into what it would take to make sorting > >> cleaner and more user-friendly. > >> > >> I came up with a subclass of extended dataTable and a replacement > >> SortableModel that did what I wanted for the most part: > >> > >> <my:sortableDataTable > >> preserveDataModel="true" > >> value="#{bean.carList}" > >> var="car" > >> > > >> <f:facet name="comparator"> > >> <my:propertyComparator > >> property="style.color" > >> descending="true" /> > >> </f:facet> > >> </my:sortableDataTable> > >> > >> This is based in part on reusing my components for sorting selectItem > >> lists. For some reason, couldn't make this work without using > >> preserveDataModel. [Strangely enough, doing the same thing with the > >> current t:dataTable sort attributes didn't require preserveDataModel.] > >> > >> In any case, a comparator component can be any UIComponent that > >> implements a ComparatorSource interface (ie, public Comparator > >> getComparator()), which provides a great deal of flexibility. > >> > >> The propertyComparator implementation basically does the same thing as > >> the internal guts of the current SortableModel, but is pluggable. I > >> used beanutils in my comparator rather than EL to process the property > >> expression, which also eliminates the "rowObjectGet" hack. An "EL > >> comparator" could be implemented if the EL processing features were > >> needed. > >> > >> I think it would be worthwhile to replace the current SortableModel > >> with a more generic pluggable one. A good start would be to pull all > >> of the property-resolving/comparison out of it, and stick it into a > >> comparator like I did. setSortCriteria(List criteria) appears to be > >> misnomer since only the first item in the list is used -- using a > >> comparator would also solve that issue as you can create > >> MultipleComparator that takes a list of other comparators and goes > >> through them in order. > >> > >> Following is what DataTable looks like to make this work. Note that > >> this doesn't handle the current sorting options. > >> > >> protected DataModel createDataModel() > >> { > >> DataModel dataModel = super.createDataModel(); > >> > >> UIComponent comparatorUIComponent = getComparator(); > >> Comparator comparator = null; > >> if (null != comparatorUIComponent) > >> { > >> if (comparatorUIComponent instanceof ComparatorSource) > >> { > >> comparator = > >> ((ComparatorSource)comparatorUIComponent).getComparator(); > >> } > >> else > >> { > >> // TODO: need log error instead > >> throw new RuntimeException("comparatorUIComponent > >> should > >> implement ComparatorSource"); > >> } > >> } > >> > >> boolean isSortable = null != comparator; > >> > >> if (isSortable) > >> { > >> if (!(dataModel instanceof BaseSortableModel)) > >> { > >> dataModel = new BaseSortableModel(dataModel); > >> } > >> > >> ((BaseSortableModel)dataModel).setComparator(comparator); > >> } > >> > >> return dataModel; > >> } > >> > >> After stripping out the comparator stuff from SortableModel, these are > >> the major changes: > >> > >> public void setComparator(Comparator _comparator) { > >> this._comparator = _comparator; > >> _sort(); > >> } > >> > >> > >> private void _sort() > >> { > >> if (null == _comparator) > >> { > >> // restore unsorted order: > >> _baseIndicesList = _sortedIndicesList = null; > >> return; > >> } > >> > >> //TODO: support -1 for rowCount: > >> int sz = getRowCount(); > >> if ((_baseIndicesList == null) || (_baseIndicesList.size() != > >> sz)) > >> { > >> // we do not want to mutate the original data. > >> // however, instead of copying the data and sorting the copy, > >> // we will create a list of indices into the original data, > >> and > >> // sort the indices. This way, when certain rows are made > >> current > >> // in this Collection, we can make them current in the > >> underlying > >> // DataModel as well. > >> _baseIndicesList = new IntList(sz); > >> } > >> > >> final int rowIndex = _model.getRowIndex(); > >> > >> _model.setRowIndex(0); > >> // Make sure the model has that row 0! (It could be empty.) > >> if (_model.isRowAvailable()) > >> { > >> Collections.sort(_baseIndicesList, new > >> RowDataComparator(_comparator, _model)); > >> _sortedIndicesList = null; > >> } > >> > >> _model.setRowIndex(rowIndex); > >> } > >> > >> protected class RowDataComparator implements Comparator > >> { > >> private Comparator dataComparator = null; > >> private DataModel dataModel = null; > >> > >> public RowDataComparator(Comparator comparator, DataModel > >> model) > >> { > >> this.dataComparator = comparator; > >> this.dataModel = model; > >> } > >> > >> public int compare(Object arg1, Object arg2) { > >> Integer r1 = (Integer)arg1; > >> Integer r2 = (Integer)arg2; > >> dataModel.setRowIndex(r1.intValue()); > >> Object rowData1 = _model.getRowData(); > >> dataModel.setRowIndex(r2.intValue()); > >> Object rowData2 = _model.getRowData(); > >> > >> return dataComparator.compare(rowData1, rowData2); > >> } > >> } > >> > >> > >> Also, here's how I'd like to improve t:selectItems. I've had a custom > >> subclass of f:selectItems of this working for awhile. Notice how we > >> can reuse the same propertyComparator component. This particular > >> implementation can take a list of comparator children and implicitly > >> wraps them in a MultipleComparator. That's not really possible with > >> a dataTable facet, so we'd want to provide a MultipleComparator > >> component. > >> > >> <my:orderedSelectItems value="#{bean.carList}"> > >> <my:propertyComparator > >> property="style.color" > >> descending="false" /> > >> </my:orderedSelectItems> > >> > > > > > > -- > View this message in context: > http://www.nabble.com/SortableModel-and-t%3AdataTable-changes-improvements-tf3403639.html#a13967432 > Sent from the My Faces - Dev mailing list archive at Nabble.com. > >