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

xml/soap/webservice

开发平台:

Java

  1. /*
  2.  * $Id: ShuttleSorter.java,v 1.6 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. /**
  23.  * Pluggable sorting filter.
  24.  *
  25.  * @author Ramesh Gupta
  26.  */
  27. public class ShuttleSorter extends Sorter {
  28.     private int[] toPrevious;
  29.     public ShuttleSorter() {
  30.         this(0, true);
  31.     }
  32.     public ShuttleSorter(int col, boolean ascending) {
  33.         super(col, ascending);
  34.     }
  35.     protected void init() {
  36.         toPrevious = new int[0];
  37.     }
  38.     /**
  39.      * Adopts the row mappings of the specified sorter by cloning the mappings.
  40.      *
  41.      * @param oldSorter <code>Sorter</code> whose mappings are to be cloned
  42.      */
  43.     protected void adopt(Sorter oldSorter) {
  44.         if (oldSorter != null) {
  45.             toPrevious = ((ShuttleSorter) oldSorter).toPrevious.clone();
  46.             /** @todo shouldn't cast */
  47.             fromPrevious = ((ShuttleSorter) oldSorter).fromPrevious.clone();
  48.             /** @todo shouldn't cast */
  49.         }
  50.     }
  51.     
  52.     /**
  53.      * Resets the internal row mappings from this filter to the previous filter.
  54.      */
  55.     protected void reset() {
  56.         int inputSize = getInputSize();
  57.         toPrevious = new int[inputSize];
  58.         fromPrevious = new int[inputSize];
  59.         for (int i = 0; i < inputSize; i++) {
  60.             toPrevious[i] = i; // reset before sorting
  61.         }
  62.     }
  63.     /**
  64.      * Performs the sort.
  65.      */
  66.     protected void filter() {
  67.         sort(toPrevious.clone(), toPrevious, 0, toPrevious.length);
  68.         // Generate inverse map for implementing convertRowIndexToView();
  69.         for (int i = 0; i < toPrevious.length; i++) {
  70.             fromPrevious[toPrevious[i]] = i;
  71.         }
  72.     }
  73.     public int getSize() {
  74.         return toPrevious.length;
  75.     }
  76.     protected int mapTowardModel(int row) {
  77.         return toPrevious[row];
  78.     }
  79. // Adapted from Phil Milne's TableSorter implementation.
  80. // This implementation, however, is not coupled to TableModel in any way,
  81. // and may be used with list models and other types of models easily.
  82. // This is a home-grown implementation which we have not had time
  83. // to research - it may perform poorly in some circumstances. It
  84. // requires twice the space of an in-place algorithm and makes
  85. // NlogN assigments shuttling the values between the two
  86. // arrays. The number of compares appears to vary between N-1 and
  87. // NlogN depending on the initial order but the main reason for
  88. // using it here is that, unlike qsort, it is stable.
  89.     protected void sort(int from[], int to[], int low, int high) {
  90.         if (high - low < 2) {
  91.             return;
  92.         }
  93.         int middle = (low + high) >> 1;
  94.         sort(to, from, low, middle);
  95.         sort(to, from, middle, high);
  96.         int p = low;
  97.         int q = middle;
  98.         /* This is an optional short-cut; at each recursive call,
  99.          check to see if the elements in this subset are already
  100.          ordered.  If so, no further comparisons are needed; the
  101.          sub-array can just be copied.  The array must be copied rather
  102.          than assigned otherwise sister calls in the recursion might
  103.          get out of sinc.  When the number of elements is three they
  104.          are partitioned so that the first set, [low, mid), has one
  105.          element and and the second, [mid, high), has two. We skip the
  106.          optimisation when the number of elements is three or less as
  107.          the first compare in the normal merge will produce the same
  108.          sequence of steps. This optimisation seems to be worthwhile
  109.          for partially ordered lists but some analysis is needed to
  110.          find out how the performance drops to Nlog(N) as the initial
  111.          order diminishes - it may drop very quickly.  */
  112.         if (high - low >= 4 && compare(from[middle - 1], from[middle]) <= 0) {
  113.             for (int i = low; i < high; i++) {
  114.                 to[i] = from[i];
  115.             }
  116.             return;
  117.         }
  118.         // A normal merge.
  119.         for (int i = low; i < high; i++) {
  120.             if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) {
  121.                 to[i] = from[p++];
  122.             }
  123.             else {
  124.                 to[i] = from[q++];
  125.             }
  126.         }
  127.     }
  128. }