X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;ds=inline;f=src%2Fjalview%2Futil%2FTableSorter.java;h=5e9556e2d9971aa69e6366b59bbdb1f6fa30ba52;hb=a049d57f4693f1b60ab02fdf2c9403a2e9c59444;hp=469bd7f594ef7045d20a79d8b7e8221a0e3017d5;hpb=7bc226b58110fa26d9dbd3f0c78095d06909ffc3;p=jalview.git
diff --git a/src/jalview/util/TableSorter.java b/src/jalview/util/TableSorter.java
index 469bd7f..5e9556e 100755
--- a/src/jalview/util/TableSorter.java
+++ b/src/jalview/util/TableSorter.java
@@ -1,20 +1,19 @@
/*
- * Jalview - A Sequence Alignment Editor and Viewer
- * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
+ * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with Jalview. If not, see .
*/
package jalview.util;
@@ -28,50 +27,42 @@ import javax.swing.event.*;
import javax.swing.table.*;
/**
- * TableSorter is a decorator for TableModels; adding sorting
- * functionality to a supplied TableModel. TableSorter does
- * not store or copy the data in its TableModel; instead it maintains
- * a map from the row indexes of the view to the row indexes of the
- * model. As requests are made of the sorter (like getValueAt(row, col))
- * they are passed to the underlying model after the row numbers
- * have been translated via the internal mapping array. This way,
- * the TableSorter appears to hold another copy of the table
- * with the rows in a different order.
+ * TableSorter is a decorator for TableModels; adding sorting functionality to a
+ * supplied TableModel. TableSorter does not store or copy the data in its
+ * TableModel; instead it maintains a map from the row indexes of the view to
+ * the row indexes of the model. As requests are made of the sorter (like
+ * getValueAt(row, col)) they are passed to the underlying model after the row
+ * numbers have been translated via the internal mapping array. This way, the
+ * TableSorter appears to hold another copy of the table with the rows in a
+ * different order.
*
- * TableSorter registers itself as a listener to the underlying model,
- * just as the JTable itself would. Events recieved from the model
- * are examined, sometimes manipulated (typically widened), and then
- * passed on to the TableSorter's listeners (typically the JTable).
- * If a change to the model has invalidated the order of TableSorter's
- * rows, a note of this is made and the sorter will resort the
- * rows the next time a value is requested.
+ * TableSorter registers itself as a listener to the underlying model, just as
+ * the JTable itself would. Events recieved from the model are examined,
+ * sometimes manipulated (typically widened), and then passed on to the
+ * TableSorter's listeners (typically the JTable). If a change to the model has
+ * invalidated the order of TableSorter's rows, a note of this is made and the
+ * sorter will resort the rows the next time a value is requested.
*
- * When the tableHeader property is set, either by using the
- * setTableHeader() method or the two argument constructor, the
- * table header may be used as a complete UI for TableSorter.
- * The default renderer of the tableHeader is decorated with a renderer
- * that indicates the sorting status of each column. In addition,
- * a mouse listener is installed with the following behavior:
+ * When the tableHeader property is set, either by using the setTableHeader()
+ * method or the two argument constructor, the table header may be used as a
+ * complete UI for TableSorter. The default renderer of the tableHeader is
+ * decorated with a renderer that indicates the sorting status of each column.
+ * In addition, a mouse listener is installed with the following behavior:
*
- * -
- * Mouse-click: Clears the sorting status of all other columns
- * and advances the sorting status of that column through three
- * values: {NOT_SORTED, ASCENDING, DESCENDING} (then back to
- * NOT_SORTED again).
- *
-
- * SHIFT-mouse-click: Clears the sorting status of all other columns
- * and cycles the sorting status of the column through the same
- * three values, in the opposite order: {NOT_SORTED, DESCENDING, ASCENDING}.
- *
-
- * CONTROL-mouse-click and CONTROL-SHIFT-mouse-click: as above except
- * that the changes to the column do not cancel the statuses of columns
- * that are already sorting - giving a way to initiate a compound
- * sort.
+ *
- Mouse-click: Clears the sorting status of all other columns and advances
+ * the sorting status of that column through three values: {NOT_SORTED,
+ * ASCENDING, DESCENDING} (then back to NOT_SORTED again).
+ *
- SHIFT-mouse-click: Clears the sorting status of all other columns and
+ * cycles the sorting status of the column through the same three values, in the
+ * opposite order: {NOT_SORTED, DESCENDING, ASCENDING}.
+ *
- CONTROL-mouse-click and CONTROL-SHIFT-mouse-click: as above except that
+ * the changes to the column do not cancel the statuses of columns that are
+ * already sorting - giving a way to initiate a compound sort.
*
*
- * This is a long overdue rewrite of a class of the same name that
- * first appeared in the swing table demos in 1997.
- *
+ * This is a long overdue rewrite of a class of the same name that first
+ * appeared in the swing table demos in 1997.
+ *
* @author Philip Milne
* @author Brendon McLean
* @author Dan van Enckevort
@@ -79,24 +70,26 @@ import javax.swing.table.*;
* @version 2.0 02/27/04
*/
-public class TableSorter
- extends AbstractTableModel
+public class TableSorter extends AbstractTableModel
{
protected TableModel tableModel;
public static final int DESCENDING = -1;
+
public static final int NOT_SORTED = 0;
+
public static final int ASCENDING = 1;
- private static Directive EMPTY_DIRECTIVE = new Directive( -1, NOT_SORTED);
+ private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);
public static final Comparator COMPARABLE_COMAPRATOR = new Comparator()
{
public int compare(Object o1, Object o2)
{
- return ( (Comparable) o1).compareTo(o2);
+ return ((Comparable) o1).compareTo(o2);
}
};
+
public static final Comparator LEXICAL_COMPARATOR = new Comparator()
{
public int compare(Object o1, Object o2)
@@ -106,12 +99,17 @@ public class TableSorter
};
private Row[] viewToModel;
+
private int[] modelToView;
private JTableHeader tableHeader;
+
private MouseListener mouseListener;
+
private TableModelListener tableModelListener;
+
private Map columnComparators = new HashMap();
+
private List sortingColumns = new ArrayList();
public TableSorter()
@@ -171,20 +169,20 @@ public class TableSorter
if (this.tableHeader != null)
{
this.tableHeader.removeMouseListener(mouseListener);
- TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer();
+ TableCellRenderer defaultRenderer = this.tableHeader
+ .getDefaultRenderer();
if (defaultRenderer instanceof SortableHeaderRenderer)
{
- this.tableHeader.setDefaultRenderer( ( (SortableHeaderRenderer)
- defaultRenderer).
- tableCellRenderer);
+ this.tableHeader
+ .setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer);
}
}
this.tableHeader = tableHeader;
if (this.tableHeader != null)
{
this.tableHeader.addMouseListener(mouseListener);
- this.tableHeader.setDefaultRenderer(
- new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer()));
+ this.tableHeader.setDefaultRenderer(new SortableHeaderRenderer(
+ this.tableHeader.getDefaultRenderer()));
}
}
@@ -243,7 +241,7 @@ public class TableSorter
return null;
}
return new Arrow(directive.direction == DESCENDING, size,
- sortingColumns.indexOf(directive));
+ sortingColumns.indexOf(directive));
}
private void cancelSorting()
@@ -356,8 +354,7 @@ public class TableSorter
// Helper classes
- private class Row
- implements Comparable
+ private class Row implements Comparable
{
private int modelIndex;
@@ -369,9 +366,9 @@ public class TableSorter
public int compareTo(Object o)
{
int row1 = modelIndex;
- int row2 = ( (Row) o).modelIndex;
+ int row2 = ((Row) o).modelIndex;
- for (Iterator it = sortingColumns.iterator(); it.hasNext(); )
+ for (Iterator it = sortingColumns.iterator(); it.hasNext();)
{
Directive directive = (Directive) it.next();
int column = directive.column;
@@ -398,15 +395,15 @@ public class TableSorter
}
if (comparison != 0)
{
- return directive.direction == DESCENDING ? -comparison : comparison;
+ return directive.direction == DESCENDING ? -comparison
+ : comparison;
}
}
return 0;
}
}
- private class TableModelHandler
- implements TableModelListener
+ private class TableModelHandler implements TableModelListener
{
public void tableChanged(TableModelEvent e)
{
@@ -431,12 +428,16 @@ public class TableSorter
// We can map a cell event through to the view without widening
// when the following conditions apply:
//
- // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and,
- // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,
- // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and,
+ // a) all the changes are on one row (e.getFirstRow() == e.getLastRow())
+ // and,
+ // b) all the changes are in one column (column !=
+ // TableModelEvent.ALL_COLUMNS) and,
+ // c) we are not sorting on that column (getSortingStatus(column) ==
+ // NOT_SORTED) and,
// d) a reverse lookup will not trigger a sort (modelToView != null)
//
- // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.
+ // Note: INSERT and DELETE events fail this test as they have column ==
+ // ALL_COLUMNS.
//
// The last check, for (modelToView != null) is to see if modelToView
// is already allocated. If we don't do this check; sorting can become
@@ -448,26 +449,25 @@ public class TableSorter
// clause avoids this problem.
int column = e.getColumn();
if (e.getFirstRow() == e.getLastRow()
- && column != TableModelEvent.ALL_COLUMNS
- && getSortingStatus(column) == NOT_SORTED
- && modelToView != null)
+ && column != TableModelEvent.ALL_COLUMNS
+ && getSortingStatus(column) == NOT_SORTED
+ && modelToView != null)
{
int viewIndex = getModelToView()[e.getFirstRow()];
- fireTableChanged(new TableModelEvent(TableSorter.this,
- viewIndex, viewIndex,
- column, e.getType()));
+ fireTableChanged(new TableModelEvent(TableSorter.this, viewIndex,
+ viewIndex, column, e.getType()));
return;
}
- // Something has happened to the data that may have invalidated the row order.
+ // Something has happened to the data that may have invalidated the row
+ // order.
clearSortingState();
fireTableDataChanged();
return;
}
}
- private class MouseHandler
- extends MouseAdapter
+ private class MouseHandler extends MouseAdapter
{
public void mouseClicked(MouseEvent e)
{
@@ -482,8 +482,10 @@ public class TableSorter
{
cancelSorting();
}
- // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or
- // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed.
+ // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING}
+ // or
+ // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is
+ // pressed.
status = status + (e.isShiftDown() ? -1 : 1);
status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 1}
setSortingStatus(column, status);
@@ -491,11 +493,12 @@ public class TableSorter
}
}
- private static class Arrow
- implements Icon
+ private static class Arrow implements Icon
{
private boolean descending;
+
private int size;
+
private int priority;
public Arrow(boolean descending, int size, int priority)
@@ -539,7 +542,7 @@ public class TableSorter
g.drawLine(dx, 0, 0, 0);
g.setColor(color);
- g.translate( -x, -y);
+ g.translate(-x, -y);
}
public int getIconWidth()
@@ -553,8 +556,7 @@ public class TableSorter
}
}
- private class SortableHeaderRenderer
- implements TableCellRenderer
+ private class SortableHeaderRenderer implements TableCellRenderer
{
private TableCellRenderer tableCellRenderer;
@@ -564,14 +566,11 @@ public class TableSorter
}
public Component getTableCellRendererComponent(JTable table,
- Object value,
- boolean isSelected,
- boolean hasFocus,
- int row,
- int column)
+ Object value, boolean isSelected, boolean hasFocus, int row,
+ int column)
{
Component c = tableCellRenderer.getTableCellRendererComponent(table,
- value, isSelected, hasFocus, row, column);
+ value, isSelected, hasFocus, row, column);
if (c instanceof JLabel)
{
JLabel l = (JLabel) c;
@@ -586,6 +585,7 @@ public class TableSorter
private static class Directive
{
private int column;
+
private int direction;
public Directive(int column, int direction)