📄 mytablesorter.java
字号:
} catch(Exception ex) {
//说明该JTable不MyTable
}
}
}
};
JTableHeader th = tableView.getTableHeader();
th.addMouseListener(listMouseListener);
}
private final void debug(String s) {
if(debug == true && s != null && !s.trim().equals(""))
System.out.println("TableSorter: -- " + s);
}
// private implementation starts here
// ======================================================================
private void checkModel() {
if(indexes.length != this.getRowCount()) {
debug("Sorter not informed of a change in model.");
}
}
private void reallocateIndexes() {
int rowCount = this.getRowCount();
// Set up a new array of indexes with the right number of elements
// for the new data model.
indexes = new int[rowCount];
// Initialise with the identity mapping.
for(int row = 0; row < rowCount; row++) {
indexes[row] = row;
}
}
//sort starts from here. The following functions are called one inside another.
private void sortByColumn(int column) {
sortByColumn(column, true);
}
private void sortByColumn(int column, boolean ascending) {
this.ascending = ascending;
sortingColumns.removeAllElements();
sortingColumns.addElement(new Integer(column));
sort(this);
//changed by chineseren for resort Table rows by indexes[]
//super.tableChanged(new TableModelEvent(this));
sortRows();
}
private void sortRows(){
Vector dataVector = this.getDataVector();
Vector newData = new Vector();
for (int i = 0; i < indexes.length; i++) {
//dataVector重新排序
newData.add(i,dataVector.get(indexes[i]));
}
this.setDataVector(newData,this.getColumnIdentifiers());
dataVector = null;
reallocateIndexes();
}
private void sort(Object sender) {
checkModel();
compares = 0;
//changed by chineseren for sort indexes
shuttlesort((int[])indexes.clone(), indexes, 0, indexes.length);
//sortIndexes();
}
/*private void sortIndexes(){
//从第n-1个开始向上冒泡排序,上面的是"小"的
for (int i = 0; i < indexes.length-1; i++) {//开始冒泡第i个
for (int j = indexes.length-1; j > i; j--) {//没趟从第indexes.length-1个开始比较到第i个
int ret = compare(indexes[j], indexes[j-1]);
if(0 > ret){
int tmp = indexes[j];
indexes[j] = indexes[j-1];
indexes[j-1] = tmp;
}
}
}
}*/
// This is a home-grown implementation which we have not had time
// to research - it may perform poorly in some circumstances. It
// requires twice the space of an in-place algorithm and makes
// NlogN assigments shuttling the values between the two
// arrays. The number of compares appears to vary between N-1 and
// NlogN depending on the initial order but the main reason for
// using it here is that, unlike qsort, it is stable.
private void shuttlesort(int from[], int to[], int low, int high) {
if(high - low < 2)
return;
int middle = (low + high) / 2;
shuttlesort(to, from, low, middle);
shuttlesort(to, from, middle, high);
int p = low;
int q = middle;
/* This is an optional short-cut; at each recursive call,
check to see if the elements in this subset are already
ordered. If so, no further comparisons are needed; the
sub-array can just be copied. The array must be copied rather
than assigned otherwise sister calls in the recursion might
get out of sinc. When the number of elements is three they
are partitioned so that the first set, [low, mid), has one
element and and the second, [mid, high), has two. We skip the
optimisation when the number of elements is three or less as
the first compare in the normal merge will produce the same
sequence of steps. This optimisation seems to be worthwhile
for partially ordered lists but some analysis is needed to
find out how the performance drops to Nlog(N) as the initial
order diminishes - it may drop very quickly. */
if(high - low >= 4 && compare(from[middle - 1], from[middle]) <= 0) {
for(int i = low; i < high; i++) {
to[i] = from[i];
}
return;
}
// A normal merge.
for(int i = low; i < high; i++) {
if(q >= high || (p < middle && compare(from[p], from[q]) <= 0)) {
to[i] = from[p++];
} else {
to[i] = from[q++];
}
}
}
private int compare(int row1, int row2) {
compares++;
for(int level = 0; level < sortingColumns.size(); level++) {
Integer column = (Integer)sortingColumns.elementAt(level);
int result = compareRowsByColumn(row1, row2, column.intValue());
if(result != 0) {
return ascending ? result : -result;
}
}
return 0;
}
private int compareRowsByColumn(int row1, int row2, int column) {
Class type = this.getColumnClass(column);
TableModel data = this;
// Check for nulls.
Object o1 = data.getValueAt(row1, column);
Object o2 = data.getValueAt(row2, column);
// If both values are null, return 0.
if (o1 == null && o2 == null) return 0;
// Define null less than everything.
else if(o1 == null)
return -1;
else if(o2 == null)
return 1;
/*
* We copy all returned values from the getValue call in case an
* optimised model is reusing one object to return many values.
* The Number subclasses in the JDK are immutable and so will not
* be used in this way but other subclasses of Number might want
* to do this to save space and avoid unnecessary heap allocation.
*/
if(type.getSuperclass() == java.lang.Number.class) {
Number n1 = (Number)data.getValueAt(row1, column);
double d1 = n1.doubleValue();
Number n2 = (Number)data.getValueAt(row2, column);
double d2 = n2.doubleValue();
if(d1 < d2)
return -1;
else if(d1 > d2)
return 1;
else
return 0;
}
else if(type == java.util.Date.class) {
Date d1 = (Date)data.getValueAt(row1, column);
long n1 = d1.getTime();
Date d2 = (Date)data.getValueAt(row2, column);
long n2 = d2.getTime();
if(n1 < n2)
return -1;
else if(n1 > n2)
return 1;
else
return 0;
}
else if(type == String.class) {
String s1 = (String)data.getValueAt(row1, column);
String s2 = (String)data.getValueAt(row2, column);
int result = s1.compareTo(s2);
if(result < 0)
return -1;
else if(result > 0)
return 1;
else
return 0;
}
else if(type == Boolean.class) {
Boolean bool1 = (Boolean)data.getValueAt(row1, column);
boolean b1 = bool1.booleanValue();
Boolean bool2 = (Boolean)data.getValueAt(row2, column);
boolean b2 = bool2.booleanValue();
if(b1 == b2)
return 0;
else if(b1)
return 1; // Define false < true
else
return -1;
}
else {
Object v1 = data.getValueAt(row1, column);
String s1 = v1.toString();
Object v2 = data.getValueAt(row2, column);
String s2 = v2.toString();
int result = s1.compareTo(s2);
if(result < 0)
return -1;
else if(result > 0)
return 1;
else
return 0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -