OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Compare Revisions

Regard whitespace Rev 155 → Rev 156

/trunk/OpenConcerto/src/org/openconcerto/utils/TableSorter.java
37,6 → 37,8
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
45,6 → 47,8
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
 
import net.jcip.annotations.Immutable;
 
/**
* 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
51,16 → 55,18
* 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. <p/>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. <p/>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:
* another copy of the table with the rows in a different order.
* <p/>
* 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.
* <p/>
* 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:
* <ul>
* <li>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
72,8 → 78,9
* column do not cancel the statuses of columns that are already sorting - giving a way to initiate
* a compound sort.
* </ul>
* <p/>This is a long overdue rewrite of a class of the same name that first appeared in the swing
* table demos in 1997.
* <p/>
* 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
92,11 → 99,13
private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);
 
public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((Comparable) o1).compareTo(o2);
}
};
public static final Comparator LEXICAL_COMPARATOR = new Comparator() {
public static final Comparator<Object> LEXICAL_COMPARATOR = new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
return o1.toString().compareTo(o2.toString());
}
108,8 → 117,8
private JTableHeader tableHeader;
private MouseListener mouseListener;
private TableModelListener tableModelListener;
private Map columnComparators = new HashMap();
private List sortingColumns = new ArrayList();
private Map<Class<?>, Comparator<?>> columnComparators = new HashMap<>();
private final List<Directive> sortingColumns = new ArrayList<>();
 
private boolean enabled;
private boolean sorting;
144,6 → 153,9
}
 
public void setTableModel(TableModel tableModel) {
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("must be called from EDT");
}
if (this.tableModel != null) {
this.tableModel.removeTableModelListener(tableModelListener);
}
188,6 → 200,9
}
 
public void setTableHeader(JTableHeader tableHeader) {
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("must be called from EDT");
}
if (this.tableHeader != null) {
this.tableHeader.removeMouseListener(mouseListener);
TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer();
207,9 → 222,22
return sortingColumns.size() != 0;
}
 
public final List<Directive> getSortingColumns() {
return Collections.unmodifiableList(this.sortingColumns);
}
 
public void setSortingColumns(List<Directive> sortingColumns) {
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("must be called from EDT");
}
this.sortingColumns.clear();
this.sortingColumns.addAll(sortingColumns);
sortingStatusChanged();
}
 
private Directive getDirective(int column) {
for (int i = 0; i < sortingColumns.size(); i++) {
Directive directive = (Directive) sortingColumns.get(i);
Directive directive = sortingColumns.get(i);
if (directive.column == column) {
return directive;
}
234,6 → 262,9
}
 
private synchronized void sortingStatusChanged() {
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("must be called from EDT");
}
this.sortingStatusChanged(true);
}
 
271,7 → 302,7
sortingStatusChanged(fire);
}
 
public void setColumnComparator(Class type, Comparator comparator) {
public void setColumnComparator(Class<?> type, Comparator<?> comparator) {
if (comparator == null) {
columnComparators.remove(type);
} else {
280,8 → 311,8
}
 
protected Comparator getComparator(int column) {
Class columnType = tableModel.getColumnClass(column);
Comparator comparator = (Comparator) columnComparators.get(columnType);
Class<?> columnType = tableModel.getColumnClass(column);
Comparator<?> comparator = columnComparators.get(columnType);
if (comparator != null) {
return comparator;
}
292,6 → 323,9
}
 
private Row[] getViewToModel() {
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("must be called from EDT");
}
if (viewToModel == null) {
int tableModelRowCount = tableModel.getRowCount();
viewToModel = new Row[tableModelRowCount];
318,6 → 352,9
}
 
private int[] getModelToView() {
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("must be called from EDT");
}
if (modelToView == null) {
int n = getViewToModel().length;
modelToView = new int[n];
334,31 → 371,50
 
// TableModel interface methods
 
@Override
public int getRowCount() {
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("must be called from EDT");
}
return (tableModel == null) ? 0 : tableModel.getRowCount();
}
 
@Override
public int getColumnCount() {
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("must be called from EDT");
}
return (tableModel == null) ? 0 : tableModel.getColumnCount();
}
 
@Override
public String getColumnName(int column) {
return tableModel.getColumnName(column);
}
 
public Class getColumnClass(int column) {
@Override
public Class<?> getColumnClass(int column) {
return tableModel.getColumnClass(column);
}
 
@Override
public boolean isCellEditable(int row, int column) {
return tableModel.isCellEditable(modelIndex(row), column);
}
 
@Override
public Object getValueAt(int row, int column) {
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("must be called from EDT");
}
return tableModel.getValueAt(modelIndex(row), column);
}
 
@Override
public void setValueAt(Object aValue, int row, int column) {
if (!SwingUtilities.isEventDispatchThread()) {
throw new IllegalStateException("must be called from EDT");
}
tableModel.setValueAt(aValue, modelIndex(row), column);
}
 
376,7 → 432,7
 
// Helper classes
 
private class Row implements Comparable {
private class Row implements Comparable<Row> {
private int modelIndex;
 
public Row(int index) {
383,12 → 439,13
this.modelIndex = index;
}
 
public int compareTo(Object o) {
@Override
public int compareTo(Row o) {
int row1 = modelIndex;
int row2 = ((Row) o).modelIndex;
int row2 = o.modelIndex;
 
for (Iterator it = sortingColumns.iterator(); it.hasNext();) {
Directive directive = (Directive) it.next();
for (Iterator<Directive> it = sortingColumns.iterator(); it.hasNext();) {
Directive directive = it.next();
int column = directive.column;
Object o1 = tableModel.getValueAt(row1, column);
Object o2 = tableModel.getValueAt(row2, column);
413,6 → 470,7
}
 
private class TableModelHandler implements TableModelListener {
@Override
public void tableChanged(TableModelEvent e) {
// If we're not sorting by anything, just pass the event along.
if (!isSorting()) {
487,6 → 545,7
}
 
private class MouseHandler extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent e) {
JTableHeader h = (JTableHeader) e.getSource();
TableColumnModel columnModel = h.getColumnModel();
523,6 → 582,7
this.priority = priority;
}
 
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Color color = c == null ? Color.GRAY : c.getBackground();
// In a compound sort, make each succesive triangle 20%
556,10 → 616,12
g.translate(-x, -y);
}
 
@Override
public int getIconWidth() {
return size;
}
 
@Override
public int getIconHeight() {
return size;
}
572,11 → 634,12
this.tableCellRenderer = tableCellRenderer;
}
 
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component c = tableCellRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (c instanceof JLabel) {
JLabel l = (JLabel) c;
l.setHorizontalTextPosition(JLabel.LEFT);
l.setHorizontalTextPosition(SwingConstants.LEFT);
int modelColumn = table.convertColumnIndexToModel(column);
l.setIcon(getHeaderRendererIcon(modelColumn, l.getFont().getSize()));
}
584,13 → 647,27
}
}
 
private static class Directive {
private int column;
private int direction;
@Immutable
public static class Directive {
private final int column;
private final int direction;
 
public Directive(int column, int direction) {
this.column = column;
this.direction = direction;
}
 
public final int getColumn() {
return this.column;
}
 
public final int getDirection() {
return this.direction;
}
 
@Override
public String toString() {
return this.getClass().getSimpleName() + " " + this.getDirection() + " on column " + this.getColumn();
}
}
}