KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > nqadmin > swingSet > SSDataGrid


1 /* $Id: SSDataGrid.java,v 1.33 2005/03/09 21:59:41 prasanth Exp $
2  *
3  * Tab Spacing = 4
4  *
5  * Copyright (c) 2003-2005, The Pangburn Company and Prasanth R. Pasala
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer. Redistributions in binary
13  * form must reproduce the above copyright notice, this list of conditions and
14  * the following disclaimer in the documentation and/or other materials
15  * provided with the distribution. The names of its contributors may not be
16  * used to endorse or promote products derived from this software without
17  * specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  */

32
33 package com.nqadmin.swingSet;
34
35 import java.awt.*;
36 import java.awt.event.*;
37 import javax.swing.*;
38 import javax.swing.event.*;
39 import javax.swing.table.*;
40 import javax.swing.border.LineBorder JavaDoc;
41 import java.sql.SQLException JavaDoc;
42 import java.sql.Date JavaDoc;
43 import java.util.GregorianCalendar JavaDoc;
44 import java.util.Calendar JavaDoc;
45 import java.util.StringTokenizer JavaDoc;
46 import java.util.EventObject JavaDoc;
47 import java.util.Vector JavaDoc;
48 import com.nqadmin.swingSet.datasources.SSRowSet;
49
50 /**
51  * SSDataGrid.java
52  *<p>
53  * SwingSet - Open Toolkit For Making Swing Controls Database-Aware
54  *<p><pre>
55  * SSDataGrid provides a way to display information from a database in a table
56  * format (aka "spreadsheet" or "datasheet" view). The SSDataGrid takes a SSRowSet
57  * as a source of data. It also provides different cell renderers including a
58  * comboboxes renderer and a date renderer.
59  *
60  * SSDataGrid internally uses the SSTableModel to display the information in a
61  * table format. SSDataGrid also provides an easy means for displaying headers.
62  * Columns can be hidden or made uneditable. In addition, it provides much finer
63  * control over which cells can be edited and which cells can't be edited. It
64  * uses the SSCellEditing interface for achieving this. The implementation of
65  * this interface also provides a way to specify what kind of information is valid
66  * for each cell.
67  *
68  * SSDataGrid uses the isCellEditable() method in SSCellEditing to determine if a
69  * cell is editable or not. The cellUpdateRequested() method of SSCellEditing is
70  * used to notify a user program when an update is requested. While doing so it
71  * provides the present value in the cell and also the new value. Based on this
72  * information the new value can be rejected or accepted by the program.
73  *
74  * SSDataGrid also provides an "extra" row to facilitate the addition of rows to
75  * the table. Default values for various columns can be set programmatically. A
76  * programmer can also specify which column is the primary key column for the
77  * underlying SSRowSet and supply a primary key for that column when a new row is
78  * being added.
79  *
80  * While using the headers always set them before you set the SSRowSet.
81  * Otherwise the headers will not appear.
82  *
83  * Also if you are using column names rather than column numbers for different function
84  * you have to call them only after setting the SSRowSet. Because SSDataGrid uses the
85  * SSRowSet to convert the column names to column numbers. If you specify the column
86  * numbers you can do before or after setting the SSRowSet, it does not matter.
87  *
88  * You can simply remember this order
89  * 1.Set the headers
90  * 2.Set the SSRowSet
91  * 3.Any other function calls.
92  *
93  * Simple Example:
94  *
95  * // SET THE HEADER BEFORE SETTING THE SSROWSET
96  * dataGrid.setHeaders(new String[]{"Part Name", "Color Code", " Weight", "City"});
97  * dataGrid.setSSRowSet(ssRowSet);
98  * // HIDE THE PART ID COLUMN
99  * // THIS SETS THE WIDTH OF THE COLUMN TO 0
100  * //dataGrid.setHiddenColumns(new String[]{"part_id"});
101  * dataGrid.setHiddenColumns(new String[]{"part_id"});
102  *
103  * dataGrid.setMessageWindow(this);
104  * dataGrid.setUneditableColumns(new String[]{"part_id"});
105  *
106  * dataGrid.setComboRenderer("color_code",new String[]{"Red","Green","Blue"},
107  * new Integer[]{new Integer(0),new Integer(1),new Integer(2)});
108  * dataGrid.setDefaultValues(new int[]{1,2,3},new Object[]{new Integer(0),
109  * new Integer(20),new String("New Orleans")});
110  *
111  * dataGrid.setPrimaryColumn("part_id");
112  * dataGrid.setSSDataValue(new SSDataValue(){
113  * public Object getPrimaryColumnValue(){
114  * // YOUR PRIMARY KEY VALUE GENERATION GOES HERE
115  * // IF ITS SOME THING USER ENTERS THEN NO PROBLEM
116  * // IF ITS AN AUTO INCREMENT FIELD THEN IT DEPENDS ON
117  * // THE DATABASE DRIVER YOU ARE USING.
118  * // IF THE UPDATEROW CAN RETRIEVE THE VALUES FOR THE ROW
119  * // WITH OUT KNOWING THE PRIMARY KEY VALUE ITS FINE
120  * // BUT POSTGRES CAN'T UPDATE ROW WITH OUT THE PRIMARY
121  * // COLUMN.
122  *
123  * // YOUR PRIMARY KEY VALUE GENERATION GOES HERE.
124  * ........
125  * ........
126  * ........
127  * }
128  * });
129  *
130  * Also See Examples 5, 6, 7 in the samples.
131  *</pre><p>
132  * @author $Author: prasanth $
133  * @version $Revision: 1.33 $
134  */

135
136 public class SSDataGrid extends JTable {
137
138     /**
139      * Component where messages should be popped up.
140      */

141     protected Component messageWindow = null;
142
143     /**
144      * SSRowSet from which component will get/set values.
145      */

146     protected SSRowSet sSRowSet = null;
147
148     /**
149      * Number of columns in the SSRowSet.
150      */

151     protected int columnCount = -1;
152
153     /**
154      * Number of records retrieved from the SSRowSet.
155      */

156     protected int rowCount = -1;
157
158     /**
159      * Minimum width of the columns in the data grid.
160      */

161     protected int columnWidth = 100;
162
163     /**
164      * Table model to construct the JTable
165      */

166     protected SSTableModel tableModel = new SSTableModel();
167
168     /**
169      * Scrollpane used to scroll datagrid.
170      */

171     protected JScrollPane scrollPane = null; //new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
172

173     /**
174      * Array used to store the column numbers that have to be hidden.
175      */

176     protected int[] hiddenColumns = null;
177
178     /**
179      * Array used to store the column names that have to hidden.
180      */

181     protected String JavaDoc[] hiddenColumnNames = null;
182
183     /**
184      * Variable to indicate if execute() should be called on the SSRowSet.
185      */

186     protected boolean callExecute = true;
187
188     /**
189      * Variable to indicate if the data grid will display an additional row for
190      * inserting new rows.
191      */

192     protected boolean insertion = true;
193
194     /**
195      * Constructs a data grid with the data source set to the given SSRowSet.
196      *
197      * @param _sSRowSet SSRowSet from which values have to be retrieved.
198      */

199     public SSDataGrid(SSRowSet _sSRowSet) {
200         sSRowSet = _sSRowSet;
201         init();
202         bind();
203     }
204
205     /**
206      * Constructs an empty data grid.
207      */

208     public SSDataGrid() {
209         init();
210     }
211
212     /**
213      * Sets the minimum column width for the data grid.
214      *
215      * @param _columnWidth minimum column width of the each column
216      */

217     public void setColumnWidth(int _columnWidth) {
218         int oldValue = columnWidth;
219         columnWidth = _columnWidth;
220         firePropertyChange("columnWidth", oldValue, columnWidth);
221     }
222
223     /**
224      * Returns the minimum column width for the data grid.
225      *
226      * @return minimum column width of the each column
227      */

228     public int getColumnWidth() {
229         return columnWidth;
230     }
231
232     /**
233      * Sets the component on which error messages will be popped up.
234      * The error dialog will use this component as its parent component.
235      *
236      * @param _messageWindow the component that should be used when displaying error messages
237      */

238     public void setMessageWindow(Component _messageWindow) {
239         Component oldValue = messageWindow;
240         messageWindow = _messageWindow;
241         firePropertyChange("messageWindow", oldValue, messageWindow);
242         tableModel.setMessageWindow(messageWindow);
243     }
244
245     /**
246      * Returns the component on which error messages will be popped up.
247      * The error dialog will use this component as its parent component.
248      *
249      * @return the component that should be used when displaying error messages
250      */

251     public Component getMessageWindow() {
252         return messageWindow;
253     }
254
255     /**
256      * Sets the callExecute property.
257      * If set to true causes the navigator to skip the execute function call on the specified SSRowSet.
258      * (See FAQ for further details)
259      *
260      * @param _callExecute true if execute function call has to be skipped else false
261      */

262     public void setCallExecute(boolean _callExecute) {
263         boolean oldValue = callExecute;
264         callExecute = _callExecute;
265         firePropertyChange("callExecute", oldValue, callExecute);
266     }
267
268     /**
269      * Returns the callExecute property.
270      * If set to true causes the navigator to skip the execute function call on the specified SSRowSet.
271      * (See FAQ for further details).
272      *
273      * @return true if execute function call has to be skipped else false
274      */

275     public boolean getCallExecute() {
276         return callExecute;
277     }
278
279     /**
280      * Sets the allowInsertion property of the table.
281      * If set to true an additional row for inserting new rows will be displayed
282      *
283      * @param _insertion true if new rows can be added else false.
284      */

285     public void setInsertion(boolean _insertion) {
286         boolean oldValue = insertion;
287         insertion = _insertion;
288         firePropertyChange("insertion", oldValue, insertion);
289         tableModel.setInsertion(_insertion);
290         updateUI();
291     }
292
293     /**
294      * Returns the allowInsertion property of the table.
295      * If set to true an additional row for inserting new rows will be displayed
296      *
297      * @return true if new rows can be added else false.
298      */

299     public boolean getInsertion() {
300         return insertion;
301     }
302
303     /**
304      * Returns the list of selected columns.
305      * This function gets the list of selected columns from parent class
306      * and removes any columns which are present in hidden columns.
307      *
308      * Currently not a bean property since there is no associated variable
309      *
310      * @return array of selected columns
311      */

312     // THIS IS A STRANGE BEHAVIOUR. FOR SOME REASON SOMETIMES THE
313
// LIST OF SELECTED COLUMNS INCLUDED HIDDEN COLUMNS THIS CAUSES
314
// A PROBLEM WITH COPY AND PASTE OPERATIONS. SO MAKE SURE THAT THIS
315
// LIST DOES NOT CONTAIN HIDDEN COLUMNS
316
public int[] getSelectedColumns() {
317         // IF THERE ARE NO HIDDEN COLUMNS THEN RETURN THE SAME LIST
318
if (hiddenColumns == null) {
319                 return super.getSelectedColumns();
320             }
321
322         // GET THE LIST OF SELECTED COLUMNS FROM SUPER CLASS.
323
int[] selectedColumns = super.getSelectedColumns();
324             Vector JavaDoc filteredColumns = new Vector JavaDoc();
325
326         // FILTER OUT THE HIDDEN COLUMNS FROM THIS LIST.
327
for (int i=0; i<selectedColumns.length; i++) {
328                 boolean found = false;
329                 // CHECK THIS COLUMN NUMBER WITH HIDDEN COLUMNS
330
for (int j=0; j<hiddenColumns.length; j++) {
331                     // IF ITS THERES INDICATE THE SAME AND BREAK OUT.
332
if (selectedColumns[i] == hiddenColumns[j]) {
333                             found = true;
334                             break;
335                         }
336                     }
337                 // IF THIS COLUMN IS NOT IN HIDDEN COLUMNS ADD IT TO FILTERED LIST
338
if (!found) {
339                         filteredColumns.add(new Integer JavaDoc(selectedColumns[i]));
340                     }
341             }
342
343         // CREATE AN INT ARRAY CONTAINING THE FILETED LIST OF COLUMNS
344
int[] result = new int[filteredColumns.size()];
345             for (int i=0; i<filteredColumns.size(); i++) {
346                 result[i] = ((Integer JavaDoc)filteredColumns.elementAt(i)).intValue();
347             }
348
349             return result;
350     }
351
352     /**
353      * Returns number of selected columns.
354      *
355      * Currently not a bean property since there is no associated variable.
356      *
357      * @return number of selected columns
358      */

359     public int getSelectedColumnCount() {
360         int[] selectedColumns = this.getSelectedColumns();
361         if (selectedColumns == null) {
362             return 0;
363         }
364
365         return selectedColumns.length;
366     }
367
368     /**
369      * Binds the SSRowSet to the grid.
370      * Data is taken from the new SSRowSet.
371      *
372      * @param _sSRowSet the SSRowSet which acts as the data source.
373      */

374      public void setSSRowSet(SSRowSet _sSRowSet) {
375         SSRowSet oldValue = sSRowSet;
376         sSRowSet = _sSRowSet;
377         firePropertyChange("sSRowSet", oldValue, sSRowSet);
378         bind();
379      } // end public void setSSRowSet(SSRowSet _sSRowSet) {
380

381     /**
382      * Returns the SSRowSet being used to get the values.
383      *
384      * @return returns the SSRowSet being used.
385      */

386     public SSRowSet getSSRowSet() {
387         return sSRowSet;
388     }
389
390     /**
391      * Returns scroll pane with the JTable embedded in it.
392      *
393      * Currently not a bean property since there is no associated variable.
394      *
395      * @return scroll pane with embedded JTable
396      */

397      public Component getComponent(){
398         return scrollPane;
399      }
400
401     /**
402      * Sets the default values for different columns.
403      * When a new row is added these default values will be added to the columns.
404      * Please make sure that the object specified for each column is of the same type
405      * as that of the column in the database.
406      * Use the getColumnClass function in JTable to determine the exact data type.
407      *
408      * Currently not a bean property since there is no associated variable.
409      *
410      * @param _columnNumbers array containing the column numbers for which the
411      * defaults apply.
412      * @param _values the values for the column numbers specified in _columnNumbers.
413      */

414      public void setDefaultValues(int[] _columnNumbers, Object JavaDoc[] _values) {
415          //if (tableModel == null) {
416
// tableModel = new SSTableModel();
417
//}
418
tableModel.setDefaultValues(_columnNumbers,_values);
419      }
420
421     /**
422      * Sets the default values for different columns.
423      * When a new row is added these default values will be added to the columns.
424      * Please make sure that the object specified for each column is of the same type
425      * as that of the column in the database.
426      * Use the getColumnClass function in JTable to determine the exact data type.
427      *
428      * Currently not a bean property since there is no associated variable.
429      *
430      * @param _columnNames array containing the column names for which the
431      * defaults apply.
432      * @param _values the values for the column names specified in _columnNames.
433      *
434      * @throws SQLException is the specified column name is not present in the SSRowSet
435      */

436      public void setDefaultValues(String JavaDoc[] _columnNames, Object JavaDoc[] _values) throws SQLException JavaDoc {
437
438         int[] columnNumbers = null;
439
440         //if (tableModel == null) {
441
// tableModel = new SSTableModel();
442
//}
443

444         if ( _columnNames != null) {
445             columnNumbers = new int[_columnNames.length];
446
447             for (int i=0; i< _columnNames.length;i++) {
448                 columnNumbers[i] = sSRowSet.getColumnIndex(_columnNames[i]) -1 ;
449             }
450         }
451
452         tableModel.setDefaultValues(columnNumbers, _values);
453      }
454
455     /**
456      * Returns the default value being used for the specified column.
457      * Returns null if a default is not in use.
458      *
459      * Currently not a bean property since there is no associated variable.
460      *
461      * @param _columnNumber the column number for which default value is to be returned.
462      *
463      * @return returns an object containing the default value for the requested column.
464      */

465      public Object JavaDoc getDefaultValue(int _columnNumber) {
466         return tableModel.getDefaultValue(_columnNumber);
467      }
468
469     /**
470      * Returns the default value being used for the specified column.
471      * Returns null if a default is not in use.
472      *
473      * Currently not a bean property since there is no associated variable.
474      *
475      * @param _columnName the column name for which default value is to be returned.
476      *
477      * @return returns an object containing the default value for the requested column.
478      *
479      * @throws SQLException is the specified column name is not present in the SSRowSet
480      */

481      public Object JavaDoc getDefaultValue(String JavaDoc _columnName) throws SQLException JavaDoc {
482         int columnNumber = sSRowSet.getColumnIndex(_columnName);
483         return tableModel.getDefaultValue(columnNumber -1);
484      }
485
486     /**
487      * Sets the column number which is the primary column for the table.
488      * This is required if new rows have to be added to the JTable.
489      * For this to properly work the SSDataValue object should also be provided
490      * SSDataValue is used to get the value for the primary column.
491      *
492      * Currently not a bean property since there is no associated variable.
493      *
494      * @param _columnNumber the column which is the primary column.
495      */

496     public void setPrimaryColumn(int _columnNumber) {
497         tableModel.setPrimaryColumn(_columnNumber);
498     }
499
500     /**
501      * Sets the column number which is the primary column for the table.
502      * This is required if new rows have to be added to the JTable.
503      * For this to properly work the SSDataValue object should also be provided
504      * SSDataValue is used to get the value for the primary column.
505      *
506      * Currently not a bean property since there is no associated variable.
507      *
508      * @param _columnName the column which is the primary column.
509      */

510     public void setPrimaryColumn(String JavaDoc _columnName) throws SQLException JavaDoc {
511         int columnNumber = sSRowSet.getColumnIndex(_columnName) -1;
512         tableModel.setPrimaryColumn(columnNumber);
513     }
514
515     /**
516      * Sets the SSDataValue interface implemention. This interface specifies
517      * function to retrieve primary column values for a new row to be added.
518      *
519      * Currently not a bean property since there is no associated variable.
520      *
521      * @param _dataValue implementation of SSDataValue
522      */

523     public void setSSDataValue(SSDataValue _dataValue) {
524         tableModel.setSSDataValue(_dataValue);
525     }
526
527     /**
528      * Sets a date renderer for the specified column.
529      * The date will be displayed in mm/dd/yyyy format. If a date renderer
530      * is not requested then the date will be displayed in a standard format(yyyy-mm-dd).
531      *
532      * Currently not a bean property since there is no associated variable.
533      *
534      * @param _column column number for which a date renderer is needed.
535      */

536     public void setDateRenderer(int _column) {
537         TableColumnModel columnModel = getColumnModel();
538         TableColumn tableColumn = columnModel.getColumn(_column);
539         tableColumn.setCellRenderer(new DateRenderer());
540         tableColumn.setCellEditor(new DateEditor());
541     }
542
543     /**
544      * Sets a date renderer for the specified column.
545      * The date will be displayed in mm/dd/yyyy format. If a date renderer
546      * is not requested then the date will be displayed in a standard format(yyyy-mm-dd).
547      *
548      * Currently not a bean property since there is no associated variable.
549      *
550      * @param _column column name for which a date renderer is needed.
551      */

552     public void setDateRenderer(String JavaDoc _column) throws SQLException JavaDoc {
553         int column = sSRowSet.getColumnIndex(_column) -1;
554         TableColumnModel columnModel = getColumnModel();
555         TableColumn tableColumn = columnModel.getColumn(column);
556         tableColumn.setCellRenderer(new DateRenderer());
557         tableColumn.setCellEditor(new DateEditor());
558     }
559
560     /**
561      * Sets a combo box renderer for the specified column.
562      * This is use full to limit the values that go with a column or if an underlying code
563      * is do be displayed in a more meaningfull manner.
564      *
565      * Currently not a bean property since there is no associated variable.
566      *
567      * @param _column column number for which combo renderer is to be provided.
568      * @param _displayItems the actual Objects to be displayed in the combo box.
569      * @param _underlyingValues the values that have to be written to the database when an
570      * item in the combo box is selected.
571      */

572     public void setComboRenderer(int _column, Object JavaDoc[] _displayItems, Object JavaDoc[] _underlyingValues) {
573         setComboRenderer(_column, _displayItems, _underlyingValues, 250);
574     }
575
576     /**
577      * Sets a combo box renderer for the specified column.
578      * This is use full to limit the values that go with a column or if an underlying code
579      * is do be displayed in a more meaningfull manner.
580      *
581      * Currently not a bean property since there is no associated variable.
582      *
583      * @param _column column number for which combo renderer is to be provided.
584      * @param _displayItems the actual Objects to be displayed in the combo box.
585      * @param _underlyingValues the values that have to be written to the database when an
586      * item in the combo box is selected.
587      */

588     public void setComboRenderer(int _column, Object JavaDoc[] _displayItems, Object JavaDoc[] _underlyingValues, int _columnWidth) {
589         setRowHeight(20);
590         TableColumnModel columnModel = getColumnModel();
591         TableColumn tableColumn = columnModel.getColumn(_column);
592         tableColumn.setCellRenderer(new ComboRenderer(_displayItems, _underlyingValues));
593         tableColumn.setCellEditor(new ComboEditor(_displayItems, _underlyingValues));
594         tableColumn.setMinWidth(_columnWidth);
595     }
596
597     /**
598      * Sets a combo box renderer for the specified column.
599      * This is use full to limit the values that go with a column or if an underlying code
600      * is do be displayed in a more meaningfull manner.
601      *
602      * Currently not a bean property since there is no associated variable.
603      *
604      * @param _column column name for which combo renderer is to be provided.
605      * @param _displayItems the actual Objects to be displayed in the combo box.
606      * @param _underlyingValues the values that have to be written to the database when an
607      * item in the combo box is selected.
608      */

609     public void setComboRenderer(String JavaDoc _column, Object JavaDoc[] _displayItems, Object JavaDoc[] _underlyingValues) throws SQLException JavaDoc {
610         setComboRenderer(_column, _displayItems, _underlyingValues, 250);
611     }
612
613     /**
614      * Sets a combo box renderer for the specified column.
615      * This is use full to limit the values that go with a column or if an underlying code
616      * is do be displayed in a more meaningfull manner.
617      *
618      * Currently not a bean property since there is no associated variable.
619      *
620      * @param _column column name for which combo renderer is to be provided.
621      * @param _displayItems the actual Objects to be displayed in the combo box.
622      * @param _underlyingValues the values that have to be written to the database when an
623      * item in the combo box is selected.
624      * @param _columnWidth required minimum width for this column
625      */

626     public void setComboRenderer(String JavaDoc _column, Object JavaDoc[] _displayItems, Object JavaDoc[] _underlyingValues, int _columnWidth) throws SQLException JavaDoc {
627         int column = sSRowSet.getColumnIndex(_column)-1;
628         setComboRenderer(column, _displayItems, _underlyingValues, _columnWidth);
629     }
630
631     /**
632      * Sets a check box renderer for the specified column.
633      *
634      * Currently not a bean property since there is no associated variable.
635      *
636      * @param _column - name ofthe column for which check box rendering is needed.
637      */

638     public void setCheckBoxRenderer(String JavaDoc _column) throws SQLException JavaDoc{
639         int column = sSRowSet.getColumnIndex(_column) - 1;
640         setCheckBoxRenderer(column);
641     }
642
643     /**
644      * Sets a check box renderer for the specified column.
645      *
646      * Currently not a bean property since there is no associated variable.
647      *
648      * @param _column - column number for which check box rendering is needed.
649      */

650     public void setCheckBoxRenderer(int _column) throws SQLException JavaDoc{
651         TableColumnModel columnModel = getColumnModel();
652         TableColumn tableColumn = columnModel.getColumn(_column);
653         tableColumn.setCellRenderer(new CheckBoxRenderer());
654         tableColumn.setCellEditor(new CheckBoxEditor());
655     }
656
657     /**
658      * Sets the header for the JTable.
659      * This function has to be called before setting the SSRowSet for SSDataGrid.
660      *
661      * Currently not a bean property since there is no associated variable.
662      *
663      * @param _headers array of string objects representing the header of each column.
664      */

665     public void setHeaders(String JavaDoc[] _headers) {
666         tableModel.setHeaders(_headers);
667     }
668
669     /**
670      * Sets the uneditable columns.
671      * The columns specified as uneditable will not be available for user to edit.
672      * This overrides the isCellEditable function in SSCellEditing.
673      *
674      * Currently not a bean property since there is no associated variable.
675      *
676      * @param _columnNumbers array specifying the column numbers which should be
677      * uneditable.
678      */

679     public void setUneditableColumns(int[] _columnNumbers) {
680         tableModel.setUneditableColumns(_columnNumbers);
681     }
682
683     /**
684      * Sets the uneditable columns.
685      * The columns specified as uneditable will not be available for user to edit.
686      * This overrides the isCellEditable function in SSCellEditing.
687      *
688      * Currently not a bean property since there is no associated variable.
689      *
690      * @param _columnNames array specifying the column names which should be
691      * uneditable.
692      */

693     public void setUneditableColumns(String JavaDoc[] _columnNames) throws SQLException JavaDoc {
694         int[] columnNumbers = null;
695         if (_columnNames != null) {
696             columnNumbers = new int[_columnNames.length];
697
698             for (int i=0;i<_columnNames.length;i++) {
699                 columnNumbers[i] = sSRowSet.getColumnIndex(_columnNames[i]) -1;
700             }
701         }
702
703         tableModel.setUneditableColumns(columnNumbers);
704     }
705
706     /**
707      * Sets the column numbers that should be hidden.
708      * The SSDataGrid sets the column width of these columns to 0.
709      * The columns are set to zero width rather than removing the column from the table.
710      * Thus preserving the column numbering.If a column is removed then the column numbers
711      * for columns after the removed column will change.
712      * Even if the column is specified as hidden user will be seeing a tiny strip.
713      * Make sure that you specify the hidden column numbers in the uneditable column
714      * list.
715      *
716      * Currently not a bean property since there is no associated variable.
717      *
718      * @param _columnNumbers array specifying the column numbers which should be
719      * hidden
720      */

721     public void setHiddenColumns(int[] _columnNumbers) {
722         hiddenColumns = _columnNumbers;
723         tableModel.setHiddenColumns(_columnNumbers);
724         hideColumns();
725     }
726
727     /**
728      * Sets the column numbers that should be hidden.
729      * The SSDataGrid sets the column width of these columns to 0.
730      * The columns are set to zero width rather than removing the column from the table.
731      * Thus preserving the column numbering.If a column is removed then the column numbers
732      * for columns after the removed column will change.
733      * Even if the column is specified as hidden user will be seeing a tiny strip.
734      * Make sure that you specify the hidden column numbers in the uneditable column
735      * list.
736      *
737      * Currently not a bean property since there is no associated variable.
738      *
739      * @param _columnNames array specifying the column names which should be
740      * hidden
741      */

742     public void setHiddenColumns(String JavaDoc[] _columnNames) throws SQLException JavaDoc {
743         hiddenColumns = null;
744         tableModel.setHiddenColumns(hiddenColumns);
745         if (_columnNames != null) {
746             hiddenColumns = new int[_columnNames.length];
747             for(int i=0; i<_columnNames.length; i++) {
748                 hiddenColumns[i] = sSRowSet.getColumnIndex(_columnNames[i]) -1;
749             }
750         }
751         hideColumns();
752     }
753
754     /**
755      * If the user has to decide on which cell has to be editable and which is not
756      * then SSCellEditable interface has to be implemented and set it for the SSTableModel.
757      *
758      * Currently not a bean property since there is no associated variable.
759      *
760      * @param _cellEditing implementation of SSCellEditable interface.
761      */

762     public void setSSCellEditing(SSCellEditing _cellEditing) {
763         tableModel.setSSCellEditing( _cellEditing );
764     }
765     
766     /**
767      * This is the default editor for Numeric, String & Object column types.
768      */

769     class DefaultEditor extends DefaultCellEditor{
770         /**
771          * Value of the editor.
772          */

773         Object JavaDoc value;
774         
775         /**
776          * Constructor to instanciate an object of column type from a string.
777          */

778         java.lang.reflect.Constructor JavaDoc constructor;
779         
780               
781         /**
782          * Constructs Default Editor.
783          */

784         public DefaultEditor() {
785             super(new SSTextField());
786             MyListener listener = new MyListener();
787             getComponent().addFocusListener(listener);
788             getComponent().addKeyListener(listener);
789         }
790         
791         /**
792          * Implementation of KeyListener & FocusListener for the editor component.
793          */

794         private class MyListener implements KeyListener, FocusListener{
795             
796             int keyPressed = 0;
797             boolean hasFocus = false;
798             
799         // ASSUMPTION HERE IS THAT THE EDITOR WILL NOT GET THE KEY PRESSED EVENT
800
// FOR THE FIRST KEY (WHICH TRIGGERS THE EDITOR, EVENT IS CONSUMED BY JTABLE)
801
/**
802              * Increment the key pressed variable when ever there is a key pressed event.
803              *only exception is tab key.
804              */

805             public void keyPressed(KeyEvent ke){
806                 if(ke.getKeyCode() != KeyEvent.VK_TAB)
807                     keyPressed++;
808             }
809             
810             /**
811              * Based on if this is first key release event the contents will be cleared
812              */

813             public void keyReleased(KeyEvent ke){
814                 JComponent editor = (JComponent)DefaultEditor.this.getComponent();
815                 if(editor instanceof JTextField){
816                     if(keyPressed == 0 && Character.isLetterOrDigit(ke.getKeyChar())){
817                         ((JTextField)editor).setText(String.valueOf(ke.getKeyChar()));
818                     }
819                 }
820                 keyPressed--;
821                 if(keyPressed < 0)
822                     keyPressed = 0;
823                 
824             }
825             
826             public void keyTyped(KeyEvent ke){
827             }
828             
829             /**
830              *
831              */

832             public void focusGained(FocusEvent fe){
833                 ((SSTextField)getComponent()).selectAll();
834                 hasFocus = true;
835             }
836             
837             /**
838              * sets the keyPressed variable to zero.
839              */

840             public void focusLost(FocusEvent fe){
841             // SET THE KEYPRESSED TO ZERO AS THE EDITOR HAS LOST THE FOCUS.
842
hasFocus = false;
843                 keyPressed = 0;
844             }
845         }
846
847         public boolean stopCellEditing() {
848             String JavaDoc s = (String JavaDoc)super.getCellEditorValue();
849             
850             if (s.trim().equals("")){
851                 if (constructor.getDeclaringClass() == String JavaDoc.class) {
852                     value = s;
853                 }
854                 super.stopCellEditing();
855             }
856     
857             try {
858                 value = constructor.newInstance(new Object JavaDoc[]{s});
859             }catch (Exception JavaDoc e) {
860             // DRAW A RED BORDER IF THE VALUE OBJECT CAN'T BE CREATED.
861
// PROBABLY THE DATA ENTERED IS NOT RIGHT (STRING IN NUMBER FIELD OR VICE-VERSA)
862
((JComponent)getComponent()).setBorder(new LineBorder JavaDoc(Color.red));
863                 return false;
864             }
865             
866             return super.stopCellEditing();
867         }
868     
869         public Component getTableCellEditorComponent(JTable table, Object JavaDoc value,
870                              boolean isSelected, int row, int column) {
871         // SET INITIAL VALUE TO NULL.
872
this.value = null;
873             
874             ((JComponent)getComponent()).setBorder(new LineBorder JavaDoc(Color.black));
875             
876         // GET A CONSTRUCTOR FOR AN OBJECT OF THE CURRENT COLUMN TYPE.
877
// THIS IS NEEDED FOR RETURNING THE VALUE IN COLUMN CLASS OBJECT
878
try {
879                 Class JavaDoc type = table.getColumnClass(column);
880                 if (type == Object JavaDoc.class) {
881                     type = String JavaDoc.class;
882                 }
883                 constructor = type.getConstructor(new Class JavaDoc[]{String JavaDoc.class});
884             }catch (Exception JavaDoc e) {
885                 return null;
886             }
887             
888             return super.getTableCellEditorComponent(table, value, isSelected, row, column);
889         }
890     
891         /**
892          * Returns the cell value.
893          */

894         public Object JavaDoc getCellEditorValue() {
895             return value;
896         }
897     
898     }
899
900     
901     /**
902      * Initialization code.
903      */

904     protected void init() {
905         
906         // FORCE JTABLE TO SURRENDER TO THE EDITOR WHEN KEYSTROKES CAUSE THE EDITOR TO BE ACTIVATED
907
setSurrendersFocusOnKeystroke(true);
908             setDefaultEditor(Number JavaDoc.class, new DefaultEditor());
909             setDefaultEditor(String JavaDoc.class, new DefaultEditor());
910             setDefaultEditor(Object JavaDoc.class, new DefaultEditor());
911             
912         // ADD KEY LISTENER TO JTABLE.
913
// THIS IS USED FOR DELETING THE ROWS
914
// ALLOWS MULTIPLE ROW DELETION.
915
// KEY SEQUENCE FOR DELETING ROWS IS CTRL-X.
916
this.addKeyListener(new KeyAdapter() {
917                 private boolean controlPressed = false;
918
919             // IF THE KEY PRESSED IS CONTROL STORE THAT INFO.
920
public void keyPressed(KeyEvent ke) {
921                     if (ke.getKeyCode() == KeyEvent.VK_CONTROL) {
922                         controlPressed = true;
923                     }
924                 }
925
926             // HANDLE KEY RELEASES
927
public void keyReleased(KeyEvent ke) {
928                 // IF CONTROL KEY IS RELEASED SET THAT CONTROL IS NOT PRESSED.
929
if (ke.getKeyCode() == KeyEvent.VK_CONTROL) {
930                         controlPressed = false;
931                     }
932                 // IF X IS PRESSED WHILE THE CONTROL KEY IS STILL PRESSED
933
// DELETE THE SELECTED ROWS.
934
if (ke.getKeyCode() == KeyEvent.VK_X) {
935                         if (! controlPressed) {
936                             return;
937                         }
938                     // GET THE NUMBER OF ROWS SELECTED
939
int numRows = getSelectedRowCount();
940                         if (numRows == 0) {
941                             return;
942                         }
943                     // GET LIST OF ROWS SELECTED
944
int[] rows = getSelectedRows();
945                     // IF USER HAS PROVIDED A PARENT COMPONENT FOR ERROR MESSAGES
946
// CONFIRM THE DELETION
947
if (messageWindow != null) {
948                             int returnValue = JOptionPane.showConfirmDialog(messageWindow,"You are about to delete " + rows.length + " rows. " +
949                                 "\nAre you sure you want to delete the rows?");
950                             if (returnValue != JOptionPane.YES_OPTION) {
951                                 return;
952                             }
953                         }
954                     // START DELETING THE ROWS IN BOTTON UP FASHION
955
// IN DOING SO YOU RETAIN THE ROW NUMBERS THAT HAVE TO BE DELETED
956
// IF YOU DO IT TOP DOWN THE ROW NUMBERING CHANGES AS SOON AS A
957
// ROW IS DELETED AS A RESULT LOT OF CARE HAS TO BE TAKEN
958
// TO IDENTIFY THE NEW ROW NUMBERS AND THEN DELETE THE ROWS
959
// INSTEAD OF THAT ITS MUCH EASIER IF YOU DO IT BOTTOM UP.
960
for (int i=rows.length -1;i>=0;i--) {
961                             tableModel.deleteRow(rows[i]);
962                         }
963                         updateUI();
964                     }
965                 }
966             });
967
968         // CREATE AN INSTANCE OF KEY ADAPTER ADD PROVIDE THE PRESET GRID TO THE ADAPTER.
969
// THIS IS FOR COPY AND PASTE SUPPORT
970
SSTableKeyAdapter keyAdapter = new SSTableKeyAdapter(this);
971             keyAdapter.setAllowInsertion(true);
972
973         // SET THE TABLE MODEL FOR JTABLE
974
// this.setModel(tableModel);
975

976         // SPECIFY THE MESSAGE WINDOW TO WHICH THE TABLE MODEL HAS TO POP UP
977
// ERROR MESSAGES.
978
tableModel.setMessageWindow(messageWindow);
979             tableModel.setJTable(this);
980
981         // THIS CAUSES THE JTABLE TO DISPLAY THE HORIZONTAL SCROLL BAR AS NEEDED.
982
this.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
983
984         // ADD THE JTABLE TO A SCROLL BAR
985
scrollPane = new JScrollPane(this,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );
986
987     } // end protected void init() {
988

989     /**
990      * Initializes the data grid control. Collects metadata information about the
991      * given SSRowSet.
992      */

993     protected void bind() {
994
995         try {
996         // EXECUTE THE QUERY
997
if (callExecute) {
998                 sSRowSet.execute();
999             }
1000
1001        // SPECIFY THE SSROWSET TO THE TABLE MODEL.
1002
// if (tableModel == null) {
1003
// tableModel = new SSTableModel(sSRowSet);
1004
// } else {
1005
tableModel.setSSRowSet(sSRowSet);
1006        // }
1007

1008        // SET THE TABLE MODEL FOR JTABLE
1009
this.setModel(tableModel);
1010
1011        // GET THE ROW COUNT
1012
rowCount = tableModel.getRowCount();
1013
1014        // GET THE COLUMN COUNT
1015
columnCount = tableModel.getColumnCount();
1016
1017        } catch(SQLException JavaDoc se) {
1018            se.printStackTrace();
1019        }
1020
1021        // THIS IS NEEDED IF THE NUMBER OF COLUMNS IN THE NEW SSROWSET
1022
// DOES NOT MATCH WITH THE OLD COLUMNS.
1023
createDefaultColumnModel();
1024
1025        // HIDE COLUMNS AS NEEDED - ALSO CALLS updateUI()
1026
hideColumns();
1027
1028        // UPDATE DISPLAY
1029
// updateUI();
1030

1031    } // end protected void bind() {
1032

1033    /**
1034     * Hides the columns specified in the hidden columns list.
1035     */

1036    protected void hideColumns(){
1037    // SET THE MINIMUM WIDTH OF COLUMNS
1038
TableColumnModel columnModel = this.getColumnModel();
1039        TableColumn column;
1040        for (int i=columnModel.getColumnCount()-1;i>=0;i--) {
1041            column = columnModel.getColumn(i);
1042            int j = -1;
1043
1044            if (hiddenColumns != null) {
1045            // SET THE WIDTH OF HIDDEN COLUMNS AS 0
1046
for (j=0; j<hiddenColumns.length;j++) {
1047                    if (hiddenColumns[j] == i) {
1048                        column.setMaxWidth(0);
1049                        column.setMinWidth(0);
1050                        column.setPreferredWidth(0);
1051                        break;
1052                    }
1053                }
1054                if (j == hiddenColumns.length) {
1055                    column.setMinWidth(columnWidth);
1056                }
1057            } else {
1058            // SET OTHER COLUMNS MIN WIDTH TO 100
1059
column.setMinWidth(columnWidth);
1060            }
1061        }
1062        updateUI();
1063    }
1064
1065    /**
1066     * Editor for date fields. Used the SSTextField as the editor, but changes
1067     * the format to mm/dd/yyy from yyyy-mm-dd.
1068     */

1069    protected class DateEditor extends DefaultCellEditor {
1070
1071        // CONSTRUCTOR FOR THE EDITOR CLASS
1072
public DateEditor(){
1073            super(new SSTextField(SSTextField.MMDDYYYY));
1074            getComponent().addKeyListener(new KeyAdapter(){
1075                int keyPressed = 0;
1076                public void keyPressed(KeyEvent ke){
1077                    if(ke.getKeyCode() != KeyEvent.VK_TAB)
1078                        keyPressed++;
1079                    System.out.println("Key Pressed true");
1080                }
1081                public void keyReleased(KeyEvent ke){
1082                    System.out.println("Key Released number editor");
1083                    JComponent editor = (JComponent)DateEditor.this.getComponent();
1084                    if(editor instanceof JTextField){
1085                        System.out.println("Instance of JTextField");
1086                        if(keyPressed == 0){
1087                            ((JTextField)editor).setText(String.valueOf(ke.getKeyChar()));
1088                        }
1089                    }
1090                    System.out.println("Key Pressed is false");
1091                    keyPressed--;
1092                    if(keyPressed < 0)
1093                        keyPressed = 0;
1094                }
1095            });
1096        }
1097
1098        // RETURNS THE TEXTFIELD WITH THE GIVEN DATE IN THE TEXTFIELD
1099
// (AFTER THE FORMAT IS CHANGED TO MM/DD/YYYY
1100
public synchronized Component getTableCellEditorComponent(JTable table, Object JavaDoc value, boolean isSelected, int row, int column) {
1101
1102            if (value instanceof Date JavaDoc) {
1103                Date JavaDoc date = (Date JavaDoc)value;
1104                GregorianCalendar JavaDoc calendar = new GregorianCalendar JavaDoc();
1105                calendar.setTime(date);
1106                String JavaDoc strDate = "" + (calendar.get(Calendar.MONTH) + 1) + "/" +
1107                     calendar.get(Calendar.DAY_OF_MONTH) + "/" + calendar.get(Calendar.YEAR);
1108                    return super.getTableCellEditorComponent(table, strDate, isSelected, row, column);
1109            }
1110
1111            return super.getTableCellEditorComponent(table, value, isSelected, row, column);
1112
1113        }
1114
1115        // RETURNS A DATE OBJECT REPRESENTING THE VALUE IN THE CELL.
1116
public Object JavaDoc getCellEditorValue(){
1117            String JavaDoc strDate = ((JTextField)(DateEditor.this.getComponent())).getText();
1118            StringTokenizer JavaDoc strtok = new StringTokenizer JavaDoc(strDate, "/", false);
1119            Calendar JavaDoc calendar = Calendar.getInstance();
1120            calendar.set(Calendar.MONTH, Integer.parseInt(strtok.nextToken())-1);
1121            calendar.set(Calendar.DATE, Integer.parseInt(strtok.nextToken()));
1122            calendar.set(Calendar.YEAR, Integer.parseInt(strtok.nextToken()));
1123            return new Date JavaDoc(calendar.getTimeInMillis());
1124        }
1125
1126        public boolean isCellEditable(EventObject JavaDoc event){
1127            // IF NUMBER OF CLICKS IS LESS THAN THE CLICKCOUNTTOSTART RETURN FALSE
1128
// FOR CELL EDITING.
1129
if (event instanceof MouseEvent) {
1130                return ((MouseEvent)event).getClickCount() >= getClickCountToStart();
1131            }
1132
1133            return true;
1134        }
1135    }
1136
1137    /**
1138     * Renderer for check box fields.
1139     */

1140    protected class CheckBoxRenderer extends JCheckBox implements TableCellRenderer {
1141
1142        public CheckBoxRenderer(){
1143            super();
1144        }
1145
1146        public Component getTableCellRendererComponent(JTable _table, Object JavaDoc _value,
1147            boolean _selected, boolean _hasFocus, int _row, int _column){
1148
1149            if(_value instanceof Boolean JavaDoc){
1150                if(((Boolean JavaDoc)_value).booleanValue()){
1151                    this.setSelected(true);
1152                }
1153                else{
1154                    this.setSelected(false);
1155                }
1156            }
1157            else if(_value instanceof Integer JavaDoc){
1158                if( ((Integer JavaDoc)_value).intValue() != 0){
1159                    this.setSelected(true);
1160                }
1161                else{
1162                    this.setSelected(false);
1163                }
1164            }
1165            else{
1166                System.out.println("Can't set check box value. Unknown data type.");
1167                System.out.println("Column type should be Boolean or Integer for check box columns.");
1168            }
1169
1170            return this;
1171        }
1172
1173    }
1174
1175    /**
1176     * Editor for check box fields.
1177     */

1178    protected class CheckBoxEditor extends DefaultCellEditor {
1179    // VARIABLE TO STORE THE COLUMN CLASS.
1180
protected int columnClass = 0;
1181
1182        public CheckBoxEditor(){
1183            super(new JCheckBox());
1184        }
1185
1186        public Component getTableCellEditorComponent(JTable _table, Object JavaDoc _value,
1187            boolean _selected, int _row, int _column) {
1188
1189        // GET THE COMPONENT RENDERING THE VALUE.
1190
JCheckBox checkBox = (JCheckBox)getComponent();
1191
1192        // CHECK THE TYPE OF COLUMN, IT SHOULD BE THE SAME AS THE TYPE OF _VALUE.
1193
if(_value instanceof Boolean JavaDoc){
1194            // STORE THE TYPE OF COLUMN WE NEED THIS WHEN EDITOR HAS TO RETURN
1195
// VALUE BACK.
1196
columnClass = java.sql.Types.BOOLEAN;
1197            // BASED ON THE VALUE CHECK THE BOX OR UNCHECK IT.
1198
if(((Boolean JavaDoc)_value).booleanValue()){
1199                    checkBox.setSelected(true);
1200                }
1201                else{
1202                    checkBox.setSelected(false);
1203                }
1204            }
1205        // IF THE COLUMN CLASS IS INTEGER
1206
else if(_value instanceof Integer JavaDoc){
1207            // STORE THE COLUMN CLASS.
1208
columnClass = java.sql.Types.INTEGER;
1209            // BASED ON THE INTEGER VALUE CHECK OR UNCHECK THE CHECK BOX.
1210
// A VALUE OF 0 IS CONSIDERED TRUE - CHECK BOX IS CHECKED.
1211
// ANY OTHER VALUE IS CONSIDERED FALSE - UNCHECK THE CHECK BOX.
1212
if( ((Integer JavaDoc)_value).intValue() != 0){
1213                    checkBox.setSelected(true);
1214                }
1215                else{
1216                    checkBox.setSelected(false);
1217                }
1218            }
1219        // IF THE COLUMN CLASS IS NOT BOOLEAN OR INTEGER
1220
// PRINT OUT ERROR MESSAGE.
1221
else{
1222                System.out.println("Can't set check box value. Unknown data type.");
1223                System.out.println("Column type should be Boolean or Integer for check box columns.");
1224            }
1225        // RETURN THE EDITOR COMPONENT
1226
return checkBox;
1227        }
1228
1229        public Object JavaDoc getCellEditorValue() {
1230        // GET THE COMPONENT AND CHECK IF IT IS CHECKED OR NOT.
1231
if(((JCheckBox)getComponent()).isSelected()){
1232            // CHECK THE COLUMN TYPE AND RETURN CORRESPONDING OBJECT.
1233
// IF IT IS INTEGER THEN 1 IS CONSIDERED TRUE & 0 FALSE.
1234
if(columnClass == java.sql.Types.BOOLEAN){
1235                    return new Boolean JavaDoc(true);
1236                }
1237                else{
1238                    return new Integer JavaDoc(1);
1239                }
1240            }
1241            else{
1242                if(columnClass == java.sql.Types.BOOLEAN){
1243                    return new Boolean JavaDoc(false);
1244                }
1245                else{
1246                    return new Integer JavaDoc(0);
1247                }
1248            }
1249        }
1250    }
1251
1252    /**
1253     * Renderer for date fields. Displays dates using mm/dd/yyyy format.
1254     */

1255    protected class DateRenderer extends DefaultTableCellRenderer {
1256
1257        public void setValue(Object JavaDoc value) {
1258            if (value instanceof java.sql.Date JavaDoc) {
1259                Date JavaDoc date = (Date JavaDoc)value;
1260                GregorianCalendar JavaDoc calendar = new GregorianCalendar JavaDoc();
1261                calendar.setTime(date);
1262                String JavaDoc strDate = "" + (calendar.get(Calendar.MONTH)+1) + "/" +
1263                    calendar.get(Calendar.DAY_OF_MONTH) + "/" + calendar.get(Calendar.YEAR);
1264                setHorizontalAlignment(SwingConstants.CENTER);
1265                setText(strDate);
1266            } else {
1267                super.setValue(value);
1268            }
1269        }
1270    }
1271
1272    /**
1273     * Renderer for combo box fields.
1274     */

1275// protected class ComboRenderer extends JComboBox implements TableCellRenderer {
1276
protected class ComboRenderer extends DefaultTableCellRenderer.UIResource {
1277        Object JavaDoc[] underlyingValues = null;
1278// JLabel label = new JLabel();
1279
Object JavaDoc[] displayValues = null;
1280
1281        public ComboRenderer(Object JavaDoc[] _items, Object JavaDoc[] _underlyingValues) {
1282// super(_items);
1283
underlyingValues = _underlyingValues;
1284            displayValues = _items;
1285        }
1286
1287        public Component getTableCellRendererComponent(JTable _table, Object JavaDoc _value,
1288            boolean _selected, boolean _hasFocus, int _row, int _column){
1289                
1290            JLabel label = (JLabel)super.getTableCellRendererComponent(_table, _value, _selected, _hasFocus, _row, _column);
1291            
1292            int index = -1;
1293            if (displayValues.length > 0) {
1294// setSelectedIndex(getIndexOf(_value));
1295
index = getIndexOf(_value);
1296            } else {
1297                System.out.println("Combo Renderer: No item in combo that corresponds to " + _value );
1298            }
1299// return this;
1300

1301            if (index == -1) {
1302                label.setText("");
1303            } else {
1304                label.setText(displayValues[index].toString());
1305            }
1306            return label;
1307        }
1308
1309        protected int getIndexOf(Object JavaDoc _value) {
1310            if (_value == null) {
1311                return -1;
1312            }
1313            if (underlyingValues == null) {
1314                return ((Integer JavaDoc)_value).intValue();
1315            }
1316            for (int i=0;i<underlyingValues.length;i++) {
1317                if (underlyingValues[i].equals(_value)) {
1318                    return i;
1319                }
1320            }
1321            return 0;
1322        }
1323    }
1324
1325    /**
1326     * Editor for combo box fields.
1327     */

1328    protected class ComboEditor extends DefaultCellEditor {
1329        Object JavaDoc[] underlyingValues = null;
1330        // SET THE CLICK COUNT TO EDIT THE COMBO AS 2
1331
int clickCountToStart = 2;
1332// JComboBox comboBox = null;
1333

1334        public ComboEditor(Object JavaDoc[] _items, Object JavaDoc[] _underlyingValues) {
1335            super(new JComboBox(_items));
1336            underlyingValues = _underlyingValues;
1337        }
1338
1339        public boolean isCellEditable(EventObject JavaDoc event) {
1340            if (event instanceof MouseEvent) {
1341                return ((MouseEvent)event).getClickCount() >= clickCountToStart;
1342            }
1343            return true;
1344        }
1345
1346        public Component getTableCellEditorComponent(JTable _table, Object JavaDoc _value,
1347            boolean _selected, int _row, int _column) {
1348
1349            JComboBox comboBox = (JComboBox)getComponent();
1350            comboBox.setSelectedIndex(getIndexOf(_value));
1351            return comboBox;
1352        }
1353
1354        public Object JavaDoc getCellEditorValue() {
1355            if (underlyingValues == null) {
1356                return new Integer JavaDoc( ((JComboBox)getComponent()).getSelectedIndex());
1357            }
1358
1359            int index = ((JComboBox)getComponent()).getSelectedIndex();
1360// System.out.println("Index is "+ index);
1361
if (index == -1) {
1362                return underlyingValues[0];
1363            }
1364
1365            return underlyingValues[index];
1366        }
1367
1368        protected int getIndexOf(Object JavaDoc _value) {
1369            if (underlyingValues == null) {
1370                return ((Integer JavaDoc)_value).intValue();
1371            }
1372            for (int i=0;i<underlyingValues.length;i++) {
1373                if (underlyingValues[i].equals(_value)) {
1374                    return i;
1375                }
1376            }
1377
1378            return -1;
1379        }
1380    }
1381
1382
1383
1384// DEPRECATED STUFF....................
1385

1386    /**
1387     * Sets the new SSRowSet for the combo box.
1388     *
1389     * @param _sSRowSet SSRowSet to which the combo has to update values.
1390     *
1391     * @deprecated
1392     * @see #setSSRowSet
1393     */

1394    public void setRowSet(SSRowSet _sSRowSet) {
1395        setSSRowSet(_sSRowSet);
1396    }
1397
1398} // end public class SSDataGrid extends JTable {
1399

1400
1401
1402/*
1403 * $Log: SSDataGrid.java,v $
1404 * Revision 1.33 2005/03/09 21:59:41 prasanth
1405 * 1. Using DefaultTableCellRenderer.UIResource as parent class for ComboRenderer.
1406 * 2. Added custom editor for Numeric, String, & Object class types.
1407 *
1408 * Revision 1.32 2005/03/03 15:04:44 yoda2
1409 * Added setSurrendersFocusOnKeystroke(true); to init() to force the JTable to surrender the focus to the editor following keystroke-based navigation. This seems to fix the problem with editors not working in the DataGrid following tab-based cell navigation.
1410 *
1411 * Revision 1.31 2005/02/22 15:16:09 yoda2
1412 * Removed preferredSize datamember along with setter & getter. These all exist in the parent class.
1413 *
1414 * Revision 1.30 2005/02/13 15:38:20 yoda2
1415 * Removed redundant PropertyChangeListener and VetoableChangeListener class variables and methods from components with JComponent as an ancestor.
1416 *
1417 * Revision 1.29 2005/02/12 03:29:26 yoda2
1418 * Added bound properties (for beans).
1419 *
1420 * Revision 1.28 2005/02/11 22:59:28 yoda2
1421 * Imported PropertyVetoException and added some bound properties.
1422 *
1423 * Revision 1.27 2005/02/11 20:16:02 yoda2
1424 * Added infrastructure to support property & vetoable change listeners (for beans).
1425 *
1426 * Revision 1.26 2005/02/10 20:13:00 yoda2
1427 * Setter/getter cleanup & method reordering for consistency.
1428 *
1429 * Revision 1.25 2005/02/07 22:47:14 yoda2
1430 * Replaced internal calls to setRowSet() with calls to setSSRowSet().
1431 *
1432 * Revision 1.24 2005/02/07 22:34:10 yoda2
1433 * Fixed infinite loop in deprecated setRowSet() which was calling setRowSet() rather than setSSRowSet()
1434 *
1435 * Revision 1.23 2005/02/07 22:20:32 yoda2
1436 * JavaDoc cleanup.
1437 *
1438 * Revision 1.22 2005/02/04 22:48:53 yoda2
1439 * API cleanup & updated Copyright info.
1440 *
1441 * Revision 1.21 2005/02/01 17:32:37 yoda2
1442 * API cleanup.
1443 *
1444 * Revision 1.20 2004/12/10 18:59:47 prasanth
1445 * Modified the getCellEditorValue function of CheckBoxEditor inner class.
1446 *
1447 * Revision 1.19 2004/12/09 18:36:04 prasanth
1448 * Added CheckBox rendering support.
1449 *
1450 * Revision 1.18 2004/11/11 14:45:33 yoda2
1451 * Using TextPad, converted all tabs to "soft" tabs comprised of four actual spaces.
1452 *
1453 * Revision 1.17 2004/11/01 15:53:30 yoda2
1454 * Fixed various JavaDoc errors.
1455 *
1456 * Revision 1.16 2004/10/25 22:03:17 yoda2
1457 * Updated JavaDoc for new datasource abstraction layer in 0.9.0 release.
1458 *
1459 * Revision 1.15 2004/10/25 19:51:02 prasanth
1460 * Modified to use the new SSRowSet instead of RowSet.
1461 *
1462 * Revision 1.14 2004/10/22 17:38:56 prasanth
1463 * Using SSTextField for date mask.
1464 *
1465 * Revision 1.13 2004/10/19 21:14:36 prasanth
1466 * Added getCellEditorValue function for date cell editor class.
1467 * This way the editor will return a Date object rather than a string as value
1468 * of the cell.
1469 *
1470 * Revision 1.12 2004/10/06 23:14:12 prasanth
1471 * Added function to set minimum column widths.
1472 * Added function to set combo box column widths.
1473 *
1474 * Revision 1.11 2004/09/27 15:47:19 prasanth
1475 * Added hideColumns function.
1476 * Calling createDefaultColumnModel function in setRowSet if the sSRowSet is not null.
1477 *
1478 * Revision 1.10 2004/08/10 22:06:59 yoda2
1479 * Added/edited JavaDoc, made code layout more uniform across classes, made various small coding improvements suggested by PMD.
1480 *
1481 * Revision 1.9 2004/08/09 21:29:44 prasanth
1482 * The default selection of first item in combo box renderer is removed.
1483 * If a default value is specified it will be selected else no selected item.
1484 *
1485 * Revision 1.8 2004/08/02 14:48:39 prasanth
1486 * 1. Added getSelectedColumnCount and getSelectedColumns functions.
1487 * 2. Added the SSTableKeyAdapter instance for copy and paste support.
1488 *
1489 * Revision 1.7 2004/03/08 16:59:32 prasanth
1490 * Added callExecute function to let users decide whether execute should
1491 * be called or not.
1492 *
1493 * Revision 1.6 2004/03/08 16:43:37 prasanth
1494 * Updated copy right year.
1495 *
1496 * Revision 1.5 2004/02/23 16:47:41 prasanth
1497 * Println statements are commented out.
1498 *
1499 * Revision 1.4 2003/12/18 20:12:01 prasanth
1500 * Update class description.
1501 *
1502 * Revision 1.3 2003/12/16 18:01:40 prasanth
1503 * Documented versions for release 0.6.0
1504 *
1505 */
Popular Tags