KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > columba > mail > gui > table > TableView


1 // The contents of this file are subject to the Mozilla Public License Version
2
// 1.1
3
//(the "License"); you may not use this file except in compliance with the
4
//License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
5
//
6
//Software distributed under the License is distributed on an "AS IS" basis,
7
//WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
8
//for the specific language governing rights and
9
//limitations under the License.
10
//
11
//The Original Code is "The Columba Project"
12
//
13
//The Initial Developers of the Original Code are Frederik Dietz and Timo
14
// Stich.
15
//Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
16
//
17
//All Rights Reserved.
18
package org.columba.mail.gui.table;
19
20 import javax.swing.JOptionPane JavaDoc;
21 import javax.swing.table.TableCellRenderer JavaDoc;
22 import javax.swing.table.TableColumn JavaDoc;
23 import javax.swing.tree.TreePath JavaDoc;
24
25 import org.columba.api.plugin.IExtension;
26 import org.columba.api.plugin.IExtensionHandler;
27 import org.columba.api.plugin.PluginHandlerNotFoundException;
28 import org.columba.core.logging.Logging;
29 import org.columba.core.plugin.PluginManager;
30 import org.columba.mail.gui.table.model.HeaderTableModel;
31 import org.columba.mail.gui.table.model.MessageNode;
32 import org.columba.mail.gui.table.model.TableModelSorter;
33 import org.columba.mail.gui.table.plugins.BasicHeaderRenderer;
34 import org.columba.mail.gui.table.plugins.BasicRenderer;
35 import org.columba.mail.gui.table.plugins.BooleanHeaderRenderer;
36 import org.columba.mail.plugin.IExtensionHandlerKeys;
37 import org.columba.mail.resourceloader.MailImageLoader;
38 import org.frapuccino.treetable.CustomTreeTableCellRenderer;
39 import org.frapuccino.treetable.TreeTable;
40
41 /**
42  * This widget is a mix between a JTable and a JTree ( we need the JTree for the
43  * Threaded viewing of mailing lists )
44  *
45  * @version 0.9.1
46  * @author fdietz
47  */

48 public class TableView extends TreeTable {
49
50     private HeaderTableModel headerTableModel;
51
52     private IExtensionHandler handler;
53
54     private TableModelSorter sorter;
55
56     private int defaultRowHeight;
57
58     public TableView(HeaderTableModel headerTableModel, TableModelSorter sorter) {
59         super();
60
61         this.sorter = sorter;
62         this.headerTableModel = headerTableModel;
63
64         defaultRowHeight = getRowHeight();
65
66         setModel(headerTableModel);
67
68         // load plugin handler used for the columns
69
try {
70             handler = PluginManager
71                     .getInstance().getExtensionHandler(
72                             IExtensionHandlerKeys.ORG_COLUMBA_MAIL_TABLERENDERER);
73         } catch (PluginHandlerNotFoundException ex) {
74             ex.printStackTrace();
75         }
76
77         getTree().setCellRenderer(new SubjectTreeRenderer(this));
78
79         getTree().setLargeModel(true);
80     }
81
82     public boolean getScrollableTracksViewportHeight() {
83         return getPreferredSize().height < getParent().getHeight();
84     }
85
86     public void resetRowHeight() {
87         setRowHeight(defaultRowHeight);
88     }
89
90     /**
91      * Enable/Disable tree renderer for the subject column.
92      * <p>
93      * Note, that this works because {@link TreeTable}sets its
94      * {@link CustomTreeTableCellRenderer}as default renderer for this class.
95      * <br>
96      * When calling TableModel.getColumnClass(column), the model returns
97      * CustomTreeTableCellRenderer.class, if the threaded- view is enabled.
98      * <p>
99      * JTable automatically falls back to the default renderers, if no custom
100      * renderer is applied. <br>
101      * For this reason, we just remove the custom cell renderer for the
102      * "Subject" column.
103      *
104      * @param b
105      * if true, enable tree renderer. False, otherwise
106      */

107     public void enableThreadedView(boolean b) {
108         if (b) {
109             TableColumn JavaDoc tc = null;
110             tc = getColumn("Subject");
111
112             // disable subject column renderer, use tree-cellrenderer instead
113
tc.setCellRenderer(null);
114
115             // tc.setCellEditor(new CustomTreeTableCellEditor());
116
} else {
117             TableColumn JavaDoc tc = null;
118             try {
119                 tc = getColumn("Subject");
120                 // change subject column renderer back to default
121
tc.setCellRenderer(new BasicRenderer("columba.subject"));
122             } catch (IllegalArgumentException JavaDoc e) {
123
124             }
125
126         }
127     }
128
129     /**
130      * Create table column using plugin extension point
131      * <b>org.columba.mail.tablerenderer </b>.
132      *
133      * @param name
134      * name of plugin ID
135      * @param size
136      * size of table column
137      * @return table column object
138      */

139     public TableColumn JavaDoc createTableColumn(String JavaDoc name, int size) {
140         TableColumn JavaDoc c = new TableColumn JavaDoc();
141
142         // set name of column
143
c.setHeaderValue(name);
144         c.setIdentifier(name);
145
146         TableCellRenderer JavaDoc r = null;
147
148         if (handler.exists(name)) {
149             // load plugin
150
try {
151                 IExtension extension = handler.getExtension(name);
152                 r = (TableCellRenderer JavaDoc) extension.instanciateExtension(null);
153             } catch (Exception JavaDoc e) {
154                 if (Logging.DEBUG) {
155                     e.printStackTrace();
156                 }
157
158                 JOptionPane.showMessageDialog(this,
159                         "Error while loading column: " + name + "\n"
160                                 + e.getMessage());
161             }
162         }
163
164         if (r == null) {
165             // no specific renderer found
166
// -> use default renderer
167
r = new BasicRenderer(name);
168
169             registerRenderer(c, name, r, new BasicHeaderRenderer(name, sorter),
170                     size, false);
171         } else {
172             IExtension extension = handler.getExtension(name);
173
174             String JavaDoc image = extension.getMetadata().getAttribute("icon");
175             String JavaDoc fixed = extension.getMetadata().getAttribute( "size");
176             boolean lockSize = false;
177
178             if (fixed != null) {
179                 if (fixed.equals("fixed")) {
180                     size = 23;
181                     lockSize = true;
182                 }
183             }
184
185             if (lockSize) {
186                 registerRenderer(c, name, r, new BooleanHeaderRenderer(
187                         MailImageLoader.getSmallIcon(image)), size, lockSize);
188             } else {
189                 registerRenderer(c, name, r, new BasicHeaderRenderer(name,
190                         sorter), size, lockSize);
191             }
192         }
193
194         return c;
195     }
196
197     /**
198      * Set properties of this column.
199      *
200      * @param tc
201      * table column
202      * @param name
203      * name of table column
204      * @param cell
205      * cell renderer
206      * @param header
207      * header renderer
208      * @param size
209      * width of column
210      * @param lockSize
211      * is this a fixed size column?
212      */

213     protected void registerRenderer(TableColumn JavaDoc tc, String JavaDoc name,
214             TableCellRenderer JavaDoc cell, TableCellRenderer JavaDoc header, int size,
215             boolean lockSize) {
216         if (tc == null) {
217             return;
218         }
219
220         // this is a hack for the multiline column
221
if ( name.equals("MultiLine")) {
222             setRowHeight(getRowHeight()*2);
223         }
224
225         if (cell != null) {
226             tc.setCellRenderer(cell);
227         }
228
229         if (header != null) {
230             tc.setHeaderRenderer(header);
231         }
232
233         if (lockSize) {
234             tc.setMaxWidth(size);
235             tc.setMinWidth(size);
236         } else {
237             // Logging.log.info("setting size =" + size);
238
tc.setPreferredWidth(size);
239         }
240     }
241
242     /**
243      * Get selected message node.
244      *
245      * @return selected message node
246      */

247     public MessageNode getSelectedNode() {
248         MessageNode node = (MessageNode) getTree()
249                 .getLastSelectedPathComponent();
250
251         return node;
252     }
253
254     /**
255      * Get array of selected message nodes.
256      *
257      * @return arrary of selected message nodes
258      */

259     public MessageNode[] getSelectedNodes() {
260         int[] rows = null;
261         MessageNode[] nodes = null;
262
263         rows = getSelectedRows();
264         nodes = new MessageNode[rows.length];
265
266         for (int i = 0; i < rows.length; i++) {
267             TreePath JavaDoc treePath = getTree().getPathForRow(rows[i]);
268
269             if (treePath == null) {
270                 continue;
271             }
272
273             nodes[i] = (MessageNode) treePath.getLastPathComponent();
274         }
275
276         return nodes;
277     }
278
279     /**
280      * Get message node with UID
281      *
282      * @param uid
283      * UID of message node
284      *
285      * @return message node
286      */

287     public MessageNode getMessagNode(Object JavaDoc uid) {
288         return headerTableModel.getMessageNode(uid);
289     }
290
291     /**
292      * Select first row and make it visible.
293      *
294      * @return uid of selected row
295      */

296     public Object JavaDoc selectFirstRow() {
297
298         Object JavaDoc uid = null;
299
300         // if there are entries in the table
301
if (getRowCount() > 0) {
302             // changing the selection to the first row
303
changeSelection(0, 0, true, false);
304
305             // getting the node
306
MessageNode selectedNode = (MessageNode) getValueAt(0, 0);
307
308             // and getting the uid for this node
309
uid = selectedNode.getUid();
310
311             // scrolling to the first row
312
scrollRectToVisible(getCellRect(0, 0, false));
313 // @author: fdietz never request focus
314
//requestFocus();
315

316             return uid;
317         }
318
319         return null;
320     }
321
322     /**
323      * Select last row and make it visible
324      *
325      * @return uid of selected row
326      */

327     public Object JavaDoc selectLastRow() {
328
329         Object JavaDoc uid = null;
330
331         // if there are entries in the table
332
if (getRowCount() > 0) {
333             // changing the selection to the first row
334
changeSelection(getRowCount() - 1, 0, true, false);
335
336             // getting the node
337
MessageNode selectedNode = (MessageNode) getValueAt(
338                     getRowCount() - 1, 0);
339
340             // and getting the uid for this node
341
uid = selectedNode.getUid();
342
343             // scrolling to the first row
344
scrollRectToVisible(getCellRect(getRowCount() - 1, 0, false));
345
346 // @author: fdietz never request focus
347
//requestFocus();
348

349             return uid;
350         }
351
352         return null;
353     }
354
355     /**
356      * Overwritten, because selectAll doesn't also select the nodes of the
357      * underlying JTree, which aren't expanded and therefore not visible.
358      * <p>
359      * Go through all nodes and expand them. Afterwards select all rows in the
360      * JTable.
361      *
362      * @see javax.swing.JTable#selectAll()
363      */

364     public void selectAll() {
365         // expand all rows
366
for (int i = 0; i < getRowCount(); i++) {
367             TreePath JavaDoc path = getTree().getPathForRow(i);
368             getTree().expandPath(path);
369         }
370         // select all rows
371
super.selectAll();
372     }
373
374     /**
375      * Scroll table to row and request focus.
376      *
377      * @param row
378      * selected row
379      */

380     public void makeRowVisible(int row) {
381         scrollRectToVisible(getCellRect(row, 0, false));
382
383 // @author: fdietz never request focus
384
//requestFocus();
385
}
386
387     /**
388      * Change the selection to the specified row
389      *
390      * @param row
391      * row to selected
392      */

393     public void selectRow(int row) {
394
395         if (getRowCount() > 0) {
396             if (row < 0) {
397                 row = 0;
398             }
399
400             if (row >= getRowCount()) {
401                 row = getRowCount() - 1;
402             }
403
404             // changing the selection to the specified row
405
// changeSelection(row, 0, true, false);
406
changeSelection(row, 0, false, false);
407
408             makeRowVisible(row);
409             /*
410              * // scrolling to the first row
411              * scrollRectToVisible(getCellRect(row, 0, false)); requestFocus();
412              */

413         }
414     }
415
416     /**
417      * Yes, this was overwritten on purpose. Updating the table-model (swing's
418      * internals - not Columba related ) always triggers an additional call to
419      * clearSelection. This was the easiest place to circumvent this behaviour.
420      *
421      * @see javax.swing.JTable#clearSelection()
422      */

423     public void clearSelection() {
424         // don't clear selection
425
}
426 }
Popular Tags