users@woodstock.java.net

Re: Dynamic table sorting question

From: Dan Labrecque <Dan.Labrecque_at_Sun.COM>
Date: Thu, 21 Feb 2008 13:54:41 -0500

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.
>>>
>>
>>
>
>