KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > suberic > pooka > gui > FolderTableModel


1 package net.suberic.pooka.gui;
2 import net.suberic.pooka.FolderInfo;
3 import net.suberic.pooka.thread.MessageLoader;
4 import javax.swing.table.AbstractTableModel JavaDoc;
5 import javax.swing.SwingUtilities JavaDoc;
6 import java.util.*;
7
8
9 /**
10  * This class holds the information about the Messages in a Folder.
11  * It actually uses a List of MessageProxys, but, for the Row information,
12  * just returns the values from MessageProxy.getTableInformation().
13  * It also uses a List of column names.
14  *
15  */

16
17 public class FolderTableModel extends AbstractTableModel JavaDoc {
18   static int ADD_MESSAGES = 0;
19   static int REMOVE_MESSAGES = 1;
20
21   private List data;
22   private List<String JavaDoc> columnNames;
23   private List<String JavaDoc> columnIds;
24   private List columnSizes;
25   private int currentSortColumn = -1;
26   private boolean currentAscending = true;
27   //private List displayData;
28
private List columnKeys;
29
30   public FolderTableModel(List newData, List<String JavaDoc> newColumnNames, List<String JavaDoc> newColumnSizes, List newColumnKeys, List<String JavaDoc> newColumnIds) {
31     data=newData;
32     columnNames = newColumnNames;
33     columnSizes = newColumnSizes;
34     columnKeys = newColumnKeys;
35     columnIds = newColumnIds;
36   }
37
38   public int getColumnCount() {
39     return columnNames.size();
40   }
41
42   public int getRowCount() {
43     return data.size();
44   }
45
46   public String JavaDoc getColumnName(int col) {
47     return columnNames.get(col);
48   }
49
50   public String JavaDoc getColumnId(int col) {
51     return columnIds.get(col);
52   }
53
54   /**
55    * This returns the value at the given row and column.
56    *
57    * note that i actually catch any ArrayOutOfBoundsExceptions and
58    * return a new Object if this happens.
59    *
60    * As defined in javax.swing.table.TableModel, more or less
61    */

62   public Object JavaDoc getValueAt(int row, int col) {
63     try {
64       MessageProxy mp = (MessageProxy) data.get(row);
65       if (mp == null)
66         return "null";
67       else {
68         if (! mp.isLoaded()) {
69           FolderInfo fi = mp.getFolderInfo();
70           if (fi != null) {
71             MessageLoader ml = fi.getMessageLoader();
72             if (ml != null) {
73               ml.loadMessages(mp, net.suberic.pooka.thread.MessageLoader.HIGH);
74             }
75           }
76           return (net.suberic.pooka.Pooka.getProperty("FolderTableModel.unloadedCell", "loading..."));
77         } else {
78           Object JavaDoc key = columnKeys.get(col);
79           Object JavaDoc returnValue = null;
80           try {
81             returnValue = mp.getTableInfo().get(key);
82             if (returnValue == null) {
83               if (! mp.getTableInfo().containsKey(key)) {
84                 // means that we need to load this again.
85
java.util.List JavaDoc columnHeaders = mp.getColumnHeaders();
86                 columnHeaders.add(key);
87                 mp.setRefresh(true);
88
89                 FolderInfo fi = mp.getFolderInfo();
90                 if (fi != null) {
91                   MessageLoader ml = fi.getMessageLoader();
92                   if (ml != null) {
93                     ml.loadMessages(mp, net.suberic.pooka.thread.MessageLoader.HIGH);
94                   }
95                 }
96               } else {
97                 return "";
98               }
99             }
100           } catch (javax.mail.MessagingException JavaDoc me) {
101             if (((MessageProxy)data).getFolderInfo().getLogger().isLoggable(java.util.logging.Level.WARNING))
102               me.printStackTrace();
103           }
104
105           if (returnValue == null) {
106             return (net.suberic.pooka.Pooka.getProperty("FolderTableModel.unloadedCell", "loading..."));
107           }
108           return returnValue;
109         }
110       }
111     } catch (ArrayIndexOutOfBoundsException JavaDoc ae) {
112       return (net.suberic.pooka.Pooka.getProperty("FolderTableModel.exceptionCell", "exception"));
113     }
114   }
115
116   public boolean isCellEditable(int rowIndex, int columnIndex) {
117     return false;
118   }
119
120   /**
121    * This returns the MessageProxy for the given row.
122    */

123   public MessageProxy getMessageProxy(int rowNumber) {
124     try {
125       return (MessageProxy)(data.get(rowNumber));
126     } catch (ArrayIndexOutOfBoundsException JavaDoc ae) {
127       return null;
128     }
129   }
130
131   /**
132    * This returns the row number for the given MessageProxy,
133    * or -1 if the MessageProxy does not exist in the table.
134    */

135
136   public int getRowForMessage(MessageProxy mp) {
137     return data.indexOf(mp);
138   }
139
140   /**
141    * This adds a List of new MessageProxys to the FolderTableModel.
142    */

143   public void addRows(List newRows) {
144     addOrRemoveRows(newRows, FolderTableModel.ADD_MESSAGES);
145   }
146
147   /**
148    * This removes a List of MessageProxys from the FolderTableModel.
149    */

150   public void removeRows(List rowsDeleted) {
151
152     addOrRemoveRows(rowsDeleted, FolderTableModel.REMOVE_MESSAGES);
153   }
154
155   /**
156    * This is a single synchronized method to make sure that we don't
157    * add and/or delete two things at once. This is usually called
158    * from addRows() or removeRows().
159    */

160
161   public synchronized void addOrRemoveRows(List changedMsg, int addOrRem) {
162     final int firstRow, lastRow;
163
164     if (changedMsg != null && changedMsg.size() > 0) {
165       if (addOrRem == FolderTableModel.ADD_MESSAGES) {
166         firstRow = data.size() + 1;
167         lastRow = firstRow + changedMsg.size() -1;
168
169         data.addAll(changedMsg);
170         if (! SwingUtilities.isEventDispatchThread())
171           try {
172             SwingUtilities.invokeAndWait(new Runnable JavaDoc() {
173                 public void run() {
174                   fireTableRowsInserted(firstRow, lastRow);
175                 }
176               });
177           } catch (Exception JavaDoc e) {
178           }
179         else
180           fireTableRowsInserted(firstRow, lastRow);
181
182       } else if (addOrRem == FolderTableModel.REMOVE_MESSAGES) {
183         for (int i = 0; i < changedMsg.size() ; i++) {
184           final int rowNumber = data.indexOf(changedMsg.get(i));
185           if (rowNumber > -1) {
186             data.remove(changedMsg.get(i));
187
188             if ( ! SwingUtilities.isEventDispatchThread())
189               try {
190                 SwingUtilities.invokeAndWait(new Runnable JavaDoc() {
191                     public void run() {
192                       fireTableRowsDeleted(rowNumber, rowNumber);
193                     }
194                   });
195               } catch (Exception JavaDoc e) {
196               }
197             else
198               fireTableRowsDeleted(rowNumber, rowNumber);
199
200           }
201         }
202       }
203     } else {
204       System.out.println("got an empty/null added or deleted event.");
205       if (changedMsg == null) {
206         System.out.println("changedMsg was null.");
207
208       } else if ( changedMsg.size() > 0) {
209         System.out.println("changedMsg.size() = 0");
210       }
211       Thread.currentThread().dumpStack();
212     }
213   }
214
215   public int getColumnSize(int columnIndex) {
216     try {
217       return Integer.parseInt((String JavaDoc)columnSizes.get(columnIndex));
218     } catch (Exception JavaDoc e) {
219       return 0;
220     }
221   }
222
223
224   // all of this is the sorting code.
225

226   /**
227    * This is a class which compares the given MessageProxy's by the
228    * value of the particular column in the TableInfo.
229    */

230   protected class RowComparator implements Comparator {
231
232     public int column;
233     public Object JavaDoc columnKey;
234
235     public RowComparator(int newColumn) {
236       column = newColumn;
237       columnKey = columnKeys.get(column);
238     }
239
240     /**
241      * This compares two row objects (MessageProxy's) by column.
242      */

243     public int compare(Object JavaDoc row1, Object JavaDoc row2) {
244       // Check for nulls.
245

246       // If both values are null, return 0.
247
if (row1 == null && row2 == null) {
248         return 0;
249       } else if (row1 == null) { // Define null less than everything.
250
return -1;
251       } else if (row2 == null) {
252         return 1;
253       }
254
255
256       Object JavaDoc o1 = null;
257       Object JavaDoc o2 = null;
258
259       try {
260         o1 = ((MessageProxy)row1).getTableInfo().get(columnKey);
261       } catch (javax.mail.MessagingException JavaDoc me) {
262         if (((MessageProxy)row1).getFolderInfo().getLogger().isLoggable(java.util.logging.Level.WARNING))
263           me.printStackTrace();
264       }
265
266       try {
267         o2 = ((MessageProxy)row2).getTableInfo().get(columnKey);
268       } catch (javax.mail.MessagingException JavaDoc me) {
269         if (((MessageProxy)row2).getFolderInfo().getLogger().isLoggable(java.util.logging.Level.WARNING))
270           me.printStackTrace();
271       }
272
273       // again, check for nulls.
274
if (o1 == null && o2 == null) {
275         return 0;
276       } else if (o1 == null) { // Define null less than everything.
277
return -1;
278       } else if (o2 == null) {
279         return 1;
280       }
281
282       Class JavaDoc type = o1.getClass();
283
284       if (type.getSuperclass() == java.lang.Number JavaDoc.class) {
285         Number JavaDoc n1 = (Number JavaDoc)o1;
286         double d1 = n1.doubleValue();
287         Number JavaDoc n2 = (Number JavaDoc)o2;
288         double d2 = n2.doubleValue();
289
290         if (d1 < d2) {
291           return -1;
292         } else if (d1 > d2) {
293           return 1;
294         } else {
295           return 0;
296         }
297       } else if (type == java.util.Date JavaDoc.class) {
298         Date d1 = (Date)o1;
299         long n1 = d1.getTime();
300         Date d2 = (Date)o2;
301         long n2 = d2.getTime();
302
303         if (n1 < n2) {
304           return -1;
305         } else if (n1 > n2) {
306           return 1;
307         } else {
308           return 0;
309         }
310       } else if (type == String JavaDoc.class) {
311         String JavaDoc s1 = (String JavaDoc)o1;
312         String JavaDoc s2 = (String JavaDoc)o2;
313         int result = s1.compareTo(s2);
314
315         if (result < 0) {
316           return -1;
317         } else if (result > 0) {
318           return 1;
319         } else {
320           return 0;
321         }
322       } else if (type == Boolean JavaDoc.class) {
323         Boolean JavaDoc bool1 = (Boolean JavaDoc)o1;
324         boolean b1 = bool1.booleanValue();
325         Boolean JavaDoc bool2 = (Boolean JavaDoc)o2;
326         boolean b2 = bool2.booleanValue();
327
328         if (b1 == b2) {
329           return 0;
330         } else if (b1) { // Define false < true
331
return 1;
332         } else {
333           return -1;
334         }
335       } else {
336         try {
337
338           if (Class.forName("java.lang.Comparable").isAssignableFrom(type)) {
339             return ((Comparable JavaDoc)o1).compareTo(o2);
340           }
341         } catch (ClassNotFoundException JavaDoc cnfe) {
342           System.out.println("couldn't find class comparable.");
343         }
344
345         Object JavaDoc v1 = o1;
346         String JavaDoc s1 = v1.toString();
347         Object JavaDoc v2 = o2;
348         String JavaDoc s2 = v2.toString();
349         int result = s1.compareTo(s2);
350
351         if (result < 0) {
352           return -1;
353         } else if (result > 0) {
354           return 1;
355         } else {
356           return 0;
357         }
358       }
359     }
360
361     public boolean equals(Object JavaDoc comparator2) {
362       return super.equals(comparator2);
363     }
364   }
365
366   /**
367    * This is for the reverse sort.
368    */

369   public class ReverseRowComparator extends RowComparator {
370     public ReverseRowComparator(int newColumn) {
371       super(newColumn);
372     }
373
374     public int compare(Object JavaDoc row1, Object JavaDoc row2) {
375       return (super.compare(row1, row2) * -1);
376     }
377   }
378
379   /**
380    * This sorts the data List by the value of the given column.
381    */

382   public void sortByColumn(int column, boolean ascending) {
383     if (ascending)
384       java.util.Collections.sort(data, new RowComparator(column));
385     else
386       java.util.Collections.sort(data, new ReverseRowComparator(column));
387
388     this.fireTableChanged(new javax.swing.event.TableModelEvent JavaDoc(this));
389
390     currentSortColumn = column;
391     currentAscending = ascending;
392   }
393
394   /**
395    * Sorts by the given column. If the column is already the one that
396    * is sorted by, then reverses the sort.
397    */

398   public void sortByColumn(int column) {
399     if (column == currentSortColumn) {
400       sortByColumn(column, !currentAscending);
401     } else {
402       sortByColumn(column, true);
403     }
404   }
405
406   /**
407    * Returns all of the MessageProxies in this FolderTableModel.
408    */

409   public List getAllProxies() {
410     return new Vector(data);
411   }
412 }
413
Popular Tags