Sorter.java
上传用户:zhengdagz
上传日期:2014-03-06
资源大小:1956k
文件大小:6k
源码类别:

xml/soap/webservice

开发平台:

Java

  1. /*
  2.  * $Id: Sorter.java,v 1.14 2005/10/13 08:59:53 kleopatra Exp $
  3.  *
  4.  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
  5.  * Santa Clara, California 95054, U.S.A. All rights reserved.
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  * 
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  20.  */
  21. package org.jdesktop.swingx.decorator;
  22. import java.text.Collator;
  23. import java.util.Comparator;
  24. import java.util.Locale;
  25. /**
  26.  * Pluggable sorting filter.
  27.  *
  28.  * @author Ramesh Gupta
  29.  */
  30. public abstract class Sorter extends Filter {
  31.     private boolean ascending = true;
  32.     // JW: need to be updated if default locale changed
  33.     private Collator  collator;   // RG: compute this once
  34.     private Locale currentLocale;
  35.     private Comparator comparator;
  36.     public Sorter() {
  37.         this(0, true);
  38.     }
  39.     public Sorter(int col, boolean ascending) {
  40.         this(col, ascending, null);
  41.     }
  42.     public Sorter(int col, boolean ascending, Comparator comparator) {
  43.         super(col);
  44.         this.comparator = comparator;
  45.         setAscending(ascending);
  46.     }
  47.     
  48.     protected void refresh(boolean reset) {
  49.         refreshCollator();
  50.         super.refresh(reset);
  51.     }
  52.     /** 
  53.      * Subclasses must call this before filtering to guarantee the
  54.      * correct collator!
  55.      */
  56.     protected void refreshCollator() {
  57.         if (!Locale.getDefault().equals(currentLocale)) {
  58.             currentLocale = Locale.getDefault();
  59.             collator = Collator.getInstance();
  60.         }
  61.     }
  62.     /**
  63.      * exposed for testing only!
  64.      * @return
  65.      */
  66.     protected Collator getCollator() {
  67.         return collator;
  68.     }
  69.     /**
  70.      * set the Comparator to use when comparing values.
  71.      * If not null every compare will be delegated to it.
  72.      * If null the compare will follow the internal compare
  73.      * (no contract, but implemented here as:
  74.      * first check if the values are Comparable, if so
  75.      * delegate, then compare the String representation)
  76.      *
  77.      * @param comparator
  78.      */
  79.     public void setComparator(Comparator comparator) {
  80.         this.comparator = comparator;
  81.         refresh();
  82.     }
  83.     public Comparator getComparator() {
  84.         return this.comparator;
  85.     }
  86.     /**
  87.      * Adopts the row mappings of the specified sorter by cloning the mappings.
  88.      * 
  89.      * @param oldSorter
  90.      *            <code>Sorter</code> whose mappings are to be cloned
  91.      */
  92.     protected abstract void adopt(Sorter oldSorter);
  93.     /**
  94.      * Interposes this sorter between a filter pipeline and the component that
  95.      * the pipeline is bound to, replacing oldSorter as the previously
  96.      * interposed sorter. You should not have to call this method directly.
  97.      * @todo Pass in just the ComponentAdapter, and add methods to that for
  98.      * fetching the filter pipeline and old sorter, if any.
  99.      *
  100.      * PENDING: check when adopting from oldSorter makes sense!
  101.      * 
  102.      * @deprecated - use filterPipeline.setSorter instead
  103.      * 
  104.      * @param filters
  105.      * @param adapter
  106.      * @param oldSorter
  107.      */
  108.     public void interpose(FilterPipeline filters, ComponentAdapter adapter,
  109.                           Sorter oldSorter) {
  110.         if (filters != null) {
  111.             // let the pipeline do all the work
  112.             filters.setSorter(this);
  113.         } else {
  114.             releasePipeline();
  115.             assign(adapter);
  116.             adopt(oldSorter);
  117.             assign(filters);
  118.             refresh(oldSorter == null);
  119.         }
  120.     }
  121.     /**
  122.      * release the old
  123.      *
  124.      */
  125.     protected void releasePipeline() {
  126.         if (getPipeline() != null) {
  127.             getPipeline().setSorter(null);
  128.             assign((FilterPipeline) null);
  129.         }
  130.     }
  131.     public int compare(int row1, int row2) {
  132.         int result = compare(row1, row2, getColumnIndex());
  133.         return ascending ? result : -result;
  134.     }
  135.     /* Adapted from Phil Milne's TableSorter implementation.
  136.         This implementation, however, is not coupled to TableModel in any way,
  137.         and may be used with list models and other types of models easily. */
  138.     private int compare(int row1, int row2, int col) {
  139.         Object o1 = getInputValue(row1, col);
  140.         Object o2 = getInputValue(row2, col);
  141.         // If both values are null return 0
  142.         if (o1 == null && o2 == null) {
  143.             return 0;
  144.         }
  145.         else if (o1 == null) { // Define null less than everything.
  146.             return -1;
  147.         }
  148.         else if (o2 == null) {
  149.             return 1;
  150.         }
  151.         // JW: have to handle null first of all
  152.         // Seemingly, Comparators are not required to handle null. Hmm...
  153.         if (comparator != null) {
  154.             return comparator.compare(o1, o2);
  155.         }
  156.         // make sure we use the collator for string compares
  157.         if ((o1.getClass() == String.class) && (o2.getClass() == String.class)) {
  158.             return collator.compare((String)o1, (String) o2);
  159.         }
  160.         // patch from Jens Elkner (#189)
  161.         if ((o1.getClass().isInstance(o2)) && (o1 instanceof Comparable)) {
  162.             Comparable c1 = (Comparable) o1;
  163.             return c1.compareTo(o2);
  164.         } else if (o2.getClass().isInstance(o1) && (o2 instanceof Comparable)) {
  165.             Comparable c2 = (Comparable) o2;
  166.             return -c2.compareTo(o1);
  167.         }
  168.         return collator.compare(o1.toString(), o2.toString());
  169.     }
  170.     public boolean isAscending() {
  171.         return ascending;
  172.     }
  173.     public void setAscending(boolean ascending) {
  174.         this.ascending = ascending;
  175.         refresh();
  176.     }
  177.     public void toggle() {
  178.         ascending = !ascending;
  179.         refresh();
  180.     }
  181. }