KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > console > views > InfoTableSorter


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2005 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Philip Milne.
22  * Contributor(s): Emmanuel Cecchet.
23  */

24
25 package org.objectweb.cjdbc.console.views;
26
27 import java.awt.event.InputEvent JavaDoc;
28 import java.awt.event.MouseAdapter JavaDoc;
29 import java.awt.event.MouseEvent JavaDoc;
30 import java.util.Date JavaDoc;
31 import java.util.Vector JavaDoc;
32
33 import javax.swing.JTable JavaDoc;
34 import javax.swing.event.TableModelEvent JavaDoc;
35 import javax.swing.event.TableModelListener JavaDoc;
36 import javax.swing.table.AbstractTableModel JavaDoc;
37 import javax.swing.table.JTableHeader JavaDoc;
38 import javax.swing.table.TableColumnModel JavaDoc;
39 import javax.swing.table.TableModel JavaDoc;
40
41 /**
42  * This code is inspired from the Swing tutorial demo version 1.5 12/17/97 from
43  * Philip Milne. It sorts the table when you click on a header.
44  *
45  * @author Philip Milne
46  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
47  * @version 1.0
48  */

49
50 public class InfoTableSorter extends AbstractTableModel JavaDoc
51     implements
52       TableModelListener JavaDoc
53 {
54   private TableModel JavaDoc model;
55   private int[] indexes;
56   private Vector JavaDoc sortingColumns = new Vector JavaDoc();
57   private boolean ascending = true;
58   private int compares;
59
60   /**
61    * Constructor
62    *
63    * @param model TableModel to use
64    */

65   public InfoTableSorter(TableModel JavaDoc model)
66   {
67     setModel(model);
68   }
69
70   private void setModel(TableModel JavaDoc model)
71   {
72     this.model = model;
73     model.addTableModelListener(this);
74     reallocateIndexes();
75   }
76
77   /**
78    * @see javax.swing.table.TableModel#getRowCount()
79    */

80   public int getRowCount()
81   {
82     return (model == null) ? 0 : model.getRowCount();
83   }
84
85   /**
86    * @see javax.swing.table.TableModel#getColumnCount()
87    */

88   public int getColumnCount()
89   {
90     return (model == null) ? 0 : model.getColumnCount();
91   }
92
93   /**
94    * @see javax.swing.table.TableModel#getColumnName(int)
95    */

96   public String JavaDoc getColumnName(int aColumn)
97   {
98     return model.getColumnName(aColumn);
99   }
100
101   /**
102    * @see javax.swing.table.TableModel#getColumnClass(int)
103    */

104   public Class JavaDoc getColumnClass(int aColumn)
105   {
106     return model.getColumnClass(aColumn);
107   }
108
109   /**
110    * @see javax.swing.event.TableModelListener#tableChanged(javax.swing.event.TableModelEvent)
111    */

112   public void tableChanged(TableModelEvent JavaDoc e)
113   {
114     reallocateIndexes();
115     fireTableChanged(e);
116   }
117
118   // The mapping only affects the contents of the data rows.
119
// Pass all requests to these rows through the mapping array: "indexes".
120

121   /**
122    * @see javax.swing.table.TableModel#getValueAt(int, int)
123    */

124   public Object JavaDoc getValueAt(int aRow, int aColumn)
125   {
126     return model.getValueAt(indexes[aRow], aColumn);
127   }
128
129   /**
130    * @see javax.swing.table.TableModel#setValueAt(java.lang.Object, int, int)
131    */

132   public void setValueAt(Object JavaDoc aValue, int aRow, int aColumn)
133   {
134     model.setValueAt(aValue, indexes[aRow], aColumn);
135   }
136
137   /**
138    * Add a mouse listener to the Table to trigger a table sort when a column
139    * heading is clicked in the JTable.
140    *
141    * @param table the JTable to sort
142    */

143   public void addMouseListenerToHeaderInTable(JTable JavaDoc table)
144   {
145     final InfoTableSorter sorter = this;
146     final JTable JavaDoc tableView = table;
147     tableView.setColumnSelectionAllowed(false);
148     MouseAdapter JavaDoc listMouseListener = new MouseAdapter JavaDoc()
149     {
150       public void mouseClicked(MouseEvent JavaDoc e)
151       {
152         TableColumnModel JavaDoc columnModel = tableView.getColumnModel();
153         int viewColumn = columnModel.getColumnIndexAtX(e.getX());
154         int column = tableView.convertColumnIndexToModel(viewColumn);
155         if (e.getClickCount() == 1 && column != -1)
156         {
157           int shiftPressed = e.getModifiers() & InputEvent.SHIFT_MASK;
158           sorter.sortByColumn(column, shiftPressed == 0);
159         }
160       }
161     };
162     JTableHeader JavaDoc th = tableView.getTableHeader();
163     th.addMouseListener(listMouseListener);
164   }
165
166   private void sortByColumn(int column, boolean ascending)
167   {
168     this.ascending = ascending;
169     sortingColumns.removeAllElements();
170     sortingColumns.addElement(new Integer JavaDoc(column));
171     compares = 0;
172     for (int i = 0; i < getRowCount(); i++)
173       for (int j = i + 1; j < getRowCount(); j++)
174         if (compare(indexes[i], indexes[j]) == -1)
175           swap(i, j);
176
177     fireTableChanged(new TableModelEvent JavaDoc(this));
178   }
179
180   private int compareRowsByColumn(int row1, int row2, int column)
181   {
182     int result = 0;
183     Class JavaDoc type = model.getColumnClass(column);
184     TableModel JavaDoc data = model;
185
186     // Check for nulls.
187

188     Object JavaDoc o1 = data.getValueAt(row1, column);
189     Object JavaDoc o2 = data.getValueAt(row2, column);
190
191     // If both values are null, return 0.
192
if (o1 == null && o2 == null)
193       return 0;
194     else if (o1 == null)
195       // Define null less than everything.
196
return -1;
197     else if (o2 == null)
198       return 1;
199
200     if (type.getSuperclass() == java.lang.Number JavaDoc.class)
201     {
202       Number JavaDoc n1 = (Number JavaDoc) data.getValueAt(row1, column);
203       double d1 = n1.doubleValue();
204       Number JavaDoc n2 = (Number JavaDoc) data.getValueAt(row2, column);
205       double d2 = n2.doubleValue();
206       result = (int) (d1 - d2);
207     }
208     else if (type == java.util.Date JavaDoc.class)
209     {
210       Date JavaDoc d1 = (Date JavaDoc) data.getValueAt(row1, column);
211       long n1 = d1.getTime();
212       Date JavaDoc d2 = (Date JavaDoc) data.getValueAt(row2, column);
213       long n2 = d2.getTime();
214       result = (int) (n1 - n2);
215     }
216     else if (type == String JavaDoc.class)
217     {
218       String JavaDoc s1 = (String JavaDoc) data.getValueAt(row1, column);
219       String JavaDoc s2 = (String JavaDoc) data.getValueAt(row2, column);
220       result = s1.compareTo(s2);
221     }
222     else
223     {
224       Object JavaDoc v1 = data.getValueAt(row1, column);
225       String JavaDoc s1 = v1.toString();
226       Object JavaDoc v2 = data.getValueAt(row2, column);
227       String JavaDoc s2 = v2.toString();
228       result = s1.compareTo(s2);
229     }
230     if (result < 0)
231       return -1;
232     else if (result > 0)
233       return 1;
234     else
235       return 0;
236   }
237
238   private int compare(int row1, int row2)
239   {
240     compares++;
241     for (int level = 0; level < sortingColumns.size(); level++)
242     {
243       Integer JavaDoc column = (Integer JavaDoc) sortingColumns.elementAt(level);
244       int result = compareRowsByColumn(row1, row2, column.intValue());
245       if (result != 0)
246         return ascending ? result : -result;
247     }
248     return 0;
249   }
250
251   private void reallocateIndexes()
252   {
253     int rowCount = model.getRowCount();
254
255     // Set up a new array of indexes with the right number of elements
256
// for the new data model.
257
indexes = new int[rowCount];
258
259     // Initialise with the identity mapping.
260
for (int row = 0; row < rowCount; row++)
261     {
262       indexes[row] = row;
263     }
264   }
265
266   private void swap(int i, int j)
267   {
268     int tmp = indexes[i];
269     indexes[i] = indexes[j];
270     indexes[j] = tmp;
271   }
272
273 }
274
Popular Tags