users@woodstock.java.net

Re: Dynamic table sorting question

From: Dan Labrecque <Dan.Labrecque_at_Sun.COM>
Date: Fri, 22 Feb 2008 19:24:41 -0500

Basically, you just need to ensure the sorter is set before the decode
phase. If you are creating the table dynamically, using a session scoped
bean will help ensure this is available when the page is refreshed.
Otherwise, you may need to use a phase listener.

Note that you can also set the tableDataSorter attribute of the
tableRowGroup tag. That will ensure the sorter is available, regardless
of what phase TableRowGroupis in. I suspect you're creating tables
dynamically, but you can still have a tag in the JSP page. For example,
you at least need a table tag in order to set its binding attribute. As
long as you have a binding, you can add child components dynamically.

Dan

Jianbo wrote:
> Hi Dan,
> I will have do more study on TableRowGroup's life cycle to understand why my
> table sorter has been ignored.
>
> All I want to do is to use my own table sorter (which is a subclass of
> BasicTableDataSorter.) I want to override BasicTableDataSorter's sort(...)
> method so I can plugin our existing sorting mechanism.
>
> I understand how an object being compared and sorted. We have a complicated
> working system that can handle many different kind of objects (their
> converting, rendering, and sorting which is often involving something else
> instead of only the object type itself). I don't want to rewrite them. So I
> want to create a TableDataProvider with our data and perform all data
> handling with our existing code and keep the TableDataProvider updated.
>
> I have got everything working with icesoft. But I like Woodstock so much
> that I really want to use it instead. I have just started trying it. I will
> go back to my study then.
> Thanks again.
> jianbo
>
>
> Dan Labrecque wrote:
>
>> Jianbo wrote:
>>
>>> Hi Dan,
>>> Thanks for your reply.
>>> I tried more things again following your suggestion, but failed again and
>>> again.
>>>
>>>
>> You can see a live example of sortable Alarms in a table below.
>>
>> http://webdev2.sun.com/example/faces/table/alarms.jsp
>>
>> Here is the code we use to implement Comparator for an Alarm component.
>>
>> /**
>> * Return zero if the severity of <code>o1</code> equals
>> <code>o2</code>,
>> * negative 1 if the severity <code>o1</code> is less than
>> <code>o2</code>,
>> * positive 1 if the severity <code>o1</code> is greater than
>> * <code>o2</code>.
>> */
>> public int compare(Object o1, Object o2) {
>> // Optimization. By definition if the severities or type's
>> // are equal the Alarms are equal.
>> //
>> String type1 = ((Alarm)o1).getSeverity();
>> String type2 = ((Alarm)o2).getSeverity();
>> if (type1 != null && type1.equals(type2)) {
>> return 0;
>> }
>>
>> // Here we need to get the indicator from each object
>> // and based on the severity level, and then call the
>> // compareTo method. This method should have been from the
>> // Comparable interface and not the Comparator.
>> //
>> List<Indicator> indList = getIndicators();
>> Indicator ind1 = getIndicator(indList, type1);
>>
>> Indicator ind2 = getIndicator(indList, type2);
>>
>> if (ind1 != null && ind2 != null) {
>> return ind1.compareTo(ind2);
>> }
>>
>> if (ind1 == null && ind2 != null) {
>> return -1;
>> }
>>
>> if (ind1 != null && ind2 == null) {
>> return 1;
>> }
>>
>> // both ind1 and ind2 are null
>> //
>> return 0;
>> }
>>
>>
>>> Here is one of the things I tried:
>>>
>>> I created my own MyTableSorter (but it doesn't do anything except
>>> printing
>>> out some info):
>>>
>>> public class MyTableSorter extends BasicTableDataSorter
>>> {
>>> @Override
>>> public SortCriteria[] getSortCriteria()
>>> {
>>> System.out.println("Sorter: getSortCriteria");
>>> return super.getSortCriteria();
>>> }
>>>
>>> @Override
>>> public Locale getSortLocale()
>>> {
>>> System.out.println("Sorter: getSortLocale");
>>> return super.getSortLocale();
>>> }
>>>
>>> @Override
>>> public void setSortCriteria(SortCriteria[] arg0)
>>> {
>>> System.out.println("Sorter: setSortCriteria");
>>> super.setSortCriteria(arg0);
>>> }
>>>
>>> @Override
>>> public void setSortLocale(Locale arg0)
>>> {
>>> System.out.println("Sorter: setSortLocale");
>>> super.setSortLocale(arg0);
>>> }
>>>
>>> @Override
>>> public RowKey[] sort(TableDataProvider arg0, RowKey[] arg1) throws
>>> DataProviderException
>>> {
>>> System.out.println("Sorter: sort ");
>>> return super.sort(arg0, arg1);
>>> }
>>> }
>>>
>>> and I set it to the TableRowGroup (in Dynamic.java):
>>> rowGroup.setTableDataSorter(new MyTableSorter());
>>>
>>> When the table (dynamicTable.jsp, DynamicTableBean.java .....) is loaded,
>>> MyTableSorter's getSortCriteria() and sort(...) are called. But there is
>>> no
>>> SortCriteria yet, so sort(...) doesn't do anything. So far so good.
>>>
>>> But, when I click on column headers, the table is sorted by some other
>>> sorter instead of MyTableSorter. MyTableSorter's getSortCriteria() and
>>> sort(...) are never called again.
>>>
>>> What happened? What did I miss?
>>>
>>>
>> Obviously, I can't look at your app from here. However, the
>> getTableDataSorter method of TableRowGroup, it will only create its own
>> BasicTableDataSorter if one has not been set.
>>
>> Look at how your custom BasicTableDataSorter is being set. More
>> importantly, when? After selecting on a sort, the control must be
>> decoded. If the BasicTableDataSorter has not been set prior to the
>> decode phase, the table has no choice but to use its own sorter. The fix
>> could be as simple as marking your backing bean session scoped. That is,
>> any properties set during the previous invoke appliaction phase must be
>> maintained.
>>
>> In the TLD docs for TableRowGroup, you will find a "Life Cycle" section
>> that explains how the table behaves in the JSF framework.
>>
>> http://webdev2.sun.com/woodstock-tlddocs
>>
>>
>>> I tried to figure out the real sorter being used; so I changed (in
>>> Dynamic.java)
>>> TableRowGroup rowGroup = new TableRowGroup();
>>> to
>>> MyTableRowGroup rowGroup = new MtTableRowGroup();
>>>
>>> Where MyTableRowGroup doesn't do anything except printing out the sorter
>>> object:
>>> public class MyTableRowGroup extends TableRowGroup {
>>> @Override
>>> public TableDataSorter getTableDataSorter()
>>> {
>>> TableDataSorter sorter = super.getTableDataSorter();
>>> System.out.println("Which sorter: " + sorter);
>>> return sorter;
>>> }
>>> }
>>>
>>>
>>> When the table first loaded, it tells me that MyTableSorter is the sorter
>>> in
>>> the rowGroup. So far so good.
>>> But, when I click on a column header to sort, I get an exception:
>>>
>>> exception
>>>
>>> javax.servlet.ServletException:
>>> com.lancope.jsf.tableBeans.util.Dynamic$MyTableRowGroup
>>> javax.faces.webapp.FacesServlet.service(FacesServlet.java:277)
>>>
>>> root cause
>>>
>>> java.lang.InstantiationException:
>>> com.lancope.jsf.tableBeans.util.Dynamic$MyTableRowGroup
>>> java.lang.Class.newInstance0(Class.java:335)
>>> java.lang.Class.newInstance(Class.java:303)
>>>
>>> com.sun.faces.application.StateManagerImpl.newInstance(StateManagerImpl.java:616)
>>>
>>> com.sun.faces.application.StateManagerImpl.restoreTree(StateManagerImpl.java:705)
>>>
>>> com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:204)
>>>
>>> javax.faces.application.StateManagerWrapper.restoreView(StateManagerWrapper.java:178)
>>>
>>> com.sun.faces.application.ViewHandlerImpl.restoreView(ViewHandlerImpl.java:318)
>>>
>>> com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:176)
>>> com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
>>>
>>> com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:104)
>>> com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
>>> javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
>>>
>>> I am very lost.
>>> Can you tell me what I did wrong and what I missed?
>>> Really appreciate your help.
>>> jianbo
>>>
>>>
>> Please try the Comparator approach before attempting to extend
>> TableRowGroup. I'm not prepared to support that just yet.
>>
>> Dan
>>
>>
>>> Dan Labrecque wrote:
>>>
>>>
>>>> I don't have any examples for you. However, BasicTableDataSorter tests
>>>> if objects implement Comparator, first. If the sorted object implements
>>>> this interface, you can control the sort. Otherwise, you could extend
>>>> BasicTableDataSorter and provide that to TableRowGroup.
>>>>
>>>> Dan
>>>>
>>>> Jianbo wrote:
>>>>
>>>>
>>>>> I have just started trying Woodstock dynamic table component. I am
>>>>> using the /dynamicTable/ example which has a list of /Name/s.
>>>>> Everything works fine with default sorting feature. But I want to do
>>>>> my own sorting with my own comparator.
>>>>>
>>>>> For example, I want to sort last name column in a different way (e.g.
>>>>> sort by the last letter of last name. I know it is crazy but I just
>>>>> want to know how to do it.)
>>>>>
>>>>> I have tried several things: subclass /ObjectArrayDataProvider/;
>>>>> subclass /BasicTableDataSorter/ and set it to my /TableRowGroup/; etc.
>>>>> But none or them works.
>>>>>
>>>>> I have searched and searched but didn't find an example.
>>>>>
>>>>> Please help me.
>>>>> Thanks,
>>>>> jianbo
>>>>> ------------------------------------------------------------------------
>>>>> View this message in context: Dynamic table sorting question
>>>>> <http://www.nabble.com/Dynamic-table-sorting-question-tp15592362p15592362.html>
>>>>> Sent from the Project Woodstock - Users mailing list archive
>>>>> <http://www.nabble.com/Project-Woodstock---Users-f26168.html> at
>>>>> Nabble.com.
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>