1 package edu.psu.geovista.app.spreadsheet.table;
2
3 /***
4 * <p>Title: </p>
5 * <p>Description: </p>
6 * <p>Copyright: Copyright (c) 2003</p>
7 * <p>Company: </p>
8 * @author jin chen
9 * @version 1.0
10 */
11 import edu.psu.geovista.app.spreadsheet.formula.Formula;
12 import edu.psu.geovista.app.spreadsheet.formula.Cell;
13
14 import javax.swing.*;
15 import javax.swing.table.AbstractTableModel;
16 import javax.swing.table.DefaultTableModel;
17 import javax.swing.table.TableModel;
18 import java.awt.*;
19 import java.awt.event.WindowEvent;
20 import java.awt.event.WindowAdapter;
21 import java.util.*;
22
23 import edu.psu.geovista.app.spreadsheet.util.Debug;
24 import edu.psu.geovista.app.spreadsheet.exception.ParserException;
25 import edu.psu.geovista.app.spreadsheet.event.SSTableModelEvent;
26
27 public class SSTableModel extends DefaultTableModel{
28
29 public static final int NUM_ROW=40;//initial number of rows
30 public static final int NUM_COL=10;//initial number of columns
31 public static final int BASE_ROW=0;// The number of rows that not count by index
32 public static final int BASE_COL=1; //The number of columns that not count by index
33
34 // private static SSTableModel tbm;
35 private TableColumnSort sortModel;
36 private SSTable table;
37
38 public SSTableModel() {
39 super ((NUM_ROW+ BASE_ROW),(NUM_COL+BASE_COL));
40 sortModel=new TableColumnSort(this);
41
42
43 }
44 public void removeColumn(int colIndex){
45 int rowSize=dataVector.size() ;
46 for(int i = 0; i < rowSize; i++) {
47 Vector row = (Vector)dataVector.elementAt(i);
48 Cell c=(Cell)row.elementAt(colIndex);
49 if (c!=null){ //
50 c.setDeleted(true);
51 }
52 else{
53 //Can't garantee each Cell is not-null since Cell is initial by Model.getValueAt()
54 // It is called only when cell (is visible) is painted. Those hidden Cell not painted at beginning
55 Debug.println("Cell:"+i+","+colIndex+" is null");
56 }
57 row.remove(colIndex);
58 }
59 fireTableStructureChanged(); //talbe.tableChanged() will act
60
61 }
62
63
64 public Object getRealModelValueAt( int row, int column){
65 System.out.println("getValueAt:"+row+","+column);
66
67 Object o= super.getValueAt(row,column) ;
68 Cell cell;
69 if (o==null||!(o instanceof Cell) ){
70 cell=this.processValueAt(o,row,column);
71
72 }
73 else{
74 cell=(Cell)o;
75 }
76
77
78 return cell;
79 }
80 public Object getValueAt( int srow, int scolumn){
81 //Can't garantee each Cell is not-null since Cell is initial by Model.getValueAt()
82 // It is called only when cell (is visible) is painted. Those hidden Cell not painted at beginning
83 int row,column;// row, column index in real edu.psu.geovista.app.spreadsheet.model
84 //sort->
85 if (this.sortModel.isTableSort() ){
86 Point cellP=sortModel.getCellPointAt(srow,scolumn);
87 row=(int)cellP.getX() ;
88 column=(int)cellP.getY();
89 }
90 else{
91 row=srow;column=scolumn;
92 }
93 //Now row,column are index of real model
94 Object o= super.getValueAt(row,column) ;
95 Cell cell;
96 if (o==null||!(o instanceof Cell) ){
97 cell=this.processValueAt(o,row,column);
98
99 }
100 else{
101 cell=(Cell)o;
102 }
103 return cell;
104 }
105 /***
106 * @param row index in Model(for outside point view)
107 */
108 public void setValueAt(Object data, int row, int col){
109 if (this.sortModel.isTableSort() ){
110 Point cellP=sortModel.getCellPointAt(row,col); //return address in real model
111 row=(int)cellP.getX() ;
112 col=(int)cellP.getY();
113
114 }
115 // Transfer row, col to indexs of real Model
116 //wrapper everything(edu.psu.geovista.app.spreadsheet.formula/number/string) in cell object
117 Cell cell= processValueAt(data,row,col);
118 super.setValueAt(cell,row,col);
119
120 }
121
122 /***************************************************************************
123 * Process value
124 ************************************************************************/
125 private Cell createCell(int row, int col) {
126 Vector rowV=(Vector)this.dataVector.elementAt(row);
127 int r=this.dataVector.indexOf(rowV);
128 Cell cell=new Cell(rowV,this);
129 super.setValueAt(cell,row,col);
130 return cell;
131 }
132 /*** This method sets the value of the cell specified with these coordinates
133 * to aValue. It does the parsing of string objects to see if they are
134 * numbers or formulas. If you do not want any parsing at all, use
135 * setCellAt.
136 * @param aValue value to set cell to
137 * @param row index of REAL model, not sort model
138 * @param col index of REAL model, not sort model
139 */
140 private Cell processValueAt(Object aValue, int row, int col) {
141 //Wrapper raw data in Cell, make sure each obj in table's cell is a Cell obj
142 if (aValue == null){
143 Cell cell=this.createCell(row,col);
144 Vector v=cell.getContainer() ;
145
146 super.setValueAt(cell,row,col);
147 return cell;
148 //super.getValueAt(row,col);//set a edu.psu.geovista.app.spreadsheet.formula.Cell with null value
149 //aValue = new String("");
150 //super.setValueAt(aValue,row,col);
151 //return null;
152 }
153 //assert (aValue !=null ): "Null input found";
154 Cell cell;
155 Object o=super.getValueAt(row,col);
156 if (o instanceof Cell){
157 cell=(Cell)o;
158 }
159 else{
160 cell=this.createCell(row,col);
161 }
162 //Wrapper raw data in Cell<--
163
164
165 if (aValue instanceof String) {//Always String ???
166
167 String input = (String)aValue;
168 /* try making it a edu.psu.geovista.app.spreadsheet.formula */
169 /*if(input.trim().equals("")){
170 }
171 else */
172 if (input.startsWith("=")) {//1. edu.psu.geovista.app.spreadsheet.formula.Formula
173 Formula form = null;
174 try { //create edu.psu.geovista.app.spreadsheet.formula and its value and put in a cell
175
176 form = new Formula(cell,input.substring(1),
177 row, col); //may throw edu.psu.geovista.app.spreadsheet.exception.ParserException if get invalid edu.psu.geovista.app.spreadsheet.formula
178
179 cell.setFormula(form);
180 cell.setAsFormula(true); //Must call it explicitly, can't include in setFormula()
181 //cell.evaluate();//
182 }
183 catch (ParserException e) { //if enter a invalid edu.psu.geovista.app.spreadsheet.formula
184 // Still keep the fomula, so user can correct it later no parsing
185 form = new Formula(input.substring(1), row, col,e);
186 cell.setFormula(form);
187 cell.setValue(e); //used for disply error message
188 cell.setAsFormula(true); //still it is a edu.psu.geovista.app.spreadsheet.formula, but invalid(e.g.:#REF!)
189
190 }
191
192
193
194 }
195 else { //2. Number
196 try{
197 Float number=new Float(input);
198 cell.setValue(number);
199 cell.setAsFormula(false);
200
201 }catch (NumberFormatException e2) {
202 /* 3. all else fails treat as string */
203 //setCellAt(aValue, aRow, aColumn);
204 cell.setValue(input) ;
205 cell.setAsFormula(false);
206 }
207 }//if
208
209 }
210 else{ //integer, Float ....
211 cell.setValue(aValue);
212 }
213 return cell;
214
215 } //method
216
217 /***
218 * Jin: Even you use table.setDefaultEditor(edu.psu.geovista.app.spreadsheet.formula.Cell.class, new CellFomulaEditor(new JTextField()));
219 * It still not work since JTable.getDefaultEditor(Class columnClass) is passed in a Object.class, not edu.psu.geovista.app.spreadsheet.formula.Cell.class
220 * This is how getDefaultEditor() called:
221 * editor = getDefaultEditor(getColumnClass(column));
222 * By default(in AbstractTableModel):getColumnClass return a Object.class. you MUST overide it and return a edu.psu.geovista.app.spreadsheet.formula.Cell.class
223 * This is same for setting edu.psu.geovista.app.spreadsheet.formula.Cell Render
224 *
225 * JTable uses this method to determine the default renderer
226 * editor for each cell. This method tells JTable to use
227 * CellRender and CellFormulaEditor.
228 *
229 * @param c the column for which we need to determine the class
230 * @return edu.psu.geovista.app.spreadsheet.formula.Cell class
231 */
232 public Class getColumnClass(int c) {
233
234 /* only cell objects in this TableModel */
235 return Cell.class;
236 }
237
238
239
240 /***
241 *
242 * It is for get the position of the cell in the table
243 */
244 private Point getPosition(Cell cell){
245 return null;
246 }
247 /***
248 * All Cells other than those in column 0( which is index) are editable.
249 *
250 * @param row the row coordinate
251 * @param column the column coordinate
252 * @return true if cell is editable
253 */
254 public boolean isCellEditable(int row, int column) {
255 // return !((row == 0) || (column == 0));
256 return column != 0;
257 //return true;
258 }
259
260 public String getColumnName(int col) {
261 //Debug.println("name of column " + col);
262 //String viewIndex=Cell.translateColumn(col);
263 SSTable table=this.getTable();
264 String modelIndex=null;
265 String cn=null;
266
267 if (col < BASE_COL)
268 return "";
269 else {
270 if(table!=null){
271 boolean useDefaultName=false;
272 modelIndex=SSTable.translateVVColumn(col);
273 cn=super.getColumnName(col-BASE_COL);
274 if(cn.equalsIgnoreCase("y") )
275 Debug.println("cn=Y");
276 if (modelIndex.equalsIgnoreCase(cn)){
277 useDefaultName=true;//means no customerized column name, thus use system-created column name
278 }
279
280 if (cn!=null&&cn.trim().length() >0){
281 int viewIndex=this.getTable().transColModelToView(col);
282 String colName=SSTable.translateVVColumn(viewIndex);
283 if (useDefaultName){
284
285 return colName;
286 }
287 else{
288 cn=super.getColumnName(col-BASE_COL+1);
289 return colName+" : "+cn;
290 }
291 }
292 else{
293 return "";//String.valueOf(edu.psu.geovista.app.spreadsheet.formula.Cell.translateColumn(col));
294 }
295 }
296 else{
297 return "";
298 }
299
300 }
301 }
302
303 public void reCalHeader(){
304 System.out.println("Column Name");
305 for (int i=1;i< columnIdentifiers.size();i++){
306 //String colName=Cell.translateColumn(i) ;
307 String colName=this.getTable().translateColumn(i) ;
308 System.out.print(colName+" ");
309
310 try {
311 columnIdentifiers.set(i,colName );
312 } catch (Exception e) {
313 System.out.println("edu.psu.geovista.app.spreadsheet.exception happen i="+i);
314 e.printStackTrace() ;
315 }
316
317 }
318 System.out.println("Column Name");
319 fireTableStructureChanged();
320 }
321
322 public void addColumn(Object columnName, Vector columnData) {
323 super.addColumn(columnName, columnData) ;
324 }
325
326 public void addColumn(Object columnName) {
327 addColumn(columnName, (Vector)null);
328 }
329
330 /*********************************************************************
331 * sort *
332 ********************************************************************/
333 /***
334 * sort entire table
335 */
336 public void sortTable(int col,boolean ascending){
337
338 this.sortModel.sortTable(col,ascending) ;
339
340 }
341 /***
342 * sort rows
343 *
344 */
345 public void sortRows(int col,int[] rows, boolean ascending){
346
347 this.sortModel.sortRows(col,rows,ascending);
348
349 }
350
351 public void sortColumns(int col,int[] cols,boolean ascending){
352 this.sortModel.sortColumns(col,cols,ascending);
353 }
354 public void sortRange(int col,int[] rows,int[] cols,boolean ascending){
355 this.sortModel.sortRange(col,rows, cols,ascending) ;
356 }
357 public void insertRow(int row, Vector rowData) {
358 //super.insertRow(row,rowData);
359 this.insertSortModel(row,rowData);
360
361 }
362 public void insertRow(int row, Object[] rowData) {
363 this.insertSortModel(row,convertToVector(rowData));
364 }
365 /***
366 * Insert a row
367 */
368 private void insertSortModel(int row, Vector rowData) {
369 if (!sortModel.isTableSort()){//no sort
370 super.insertRow(row,rowData);
371 return;
372 }
373 //System.out.println("test");
374 if (row==0){
375 super.insertRow(row,rowData);
376 Vector sorts=sortModel.getSorts();
377 for (int i=0;i<sorts.size() ;i++){
378 Vector column=(Vector)sorts.elementAt(i);
379 if (column!=null){
380 column.insertElementAt(new Integer(row),row);
381 for (int j=row+1;j<column.size();j++){
382 int mx=((Integer)column.elementAt(j)).intValue() ;
383 mx++;
384 Integer newIndex=new Integer(mx);//updated edu.psu.geovista.app.spreadsheet.model index
385 column.setElementAt(newIndex,j);
386 }
387 //edu.psu.geovista.app.spreadsheet.model.TableColumnSort.showVector(column);
388 //System.out.println("");
389 }
390 }
391 }
392 else{
393 Vector sorts=sortModel.getSorts();
394 Vector sortColumn=null;//a column in SortModel that contain sorting info(index) for a column in real edu.psu.geovista.app.spreadsheet.model
395 boolean foundSort=false;
396 //1. find any valid (not null) column !!! May not work for multi-level sort
397 for (int k=0;k<sorts.size() ;k++){
398 sortColumn=(Vector)sorts.elementAt(k); //column before a row is insert to real edu.psu.geovista.app.spreadsheet.model
399 if (sortColumn!=null){
400 foundSort=true;
401 //2. Get and the reference to real edu.psu.geovista.app.spreadsheet.model rows, store the reference.
402 Vector tempCol=(Vector)sortColumn.clone() ;//new Vector(sortColumn.size() );
403 for (int i=0;i<sortColumn.size() ;i++){
404 int mx=((Integer)sortColumn.elementAt(i)).intValue() ;//row's index in real edu.psu.geovista.app.spreadsheet.model
405
406 Vector mrow=(Vector)this.getDataVector().elementAt(mx);//the row vector
407 tempCol.setElementAt(mrow,i);
408 }
409
410 //3. insert row to real edu.psu.geovista.app.spreadsheet.model
411 super.insertRow(row,rowData);
412
413 //4.re-evaluate the index of those rows(which obtained in step 2) in real edu.psu.geovista.app.spreadsheet.model after inserting
414 for (int i=0;i<tempCol.size() ;i++){
415 Vector mrow=(Vector)tempCol.elementAt(i);
416 int newX=this.getDataVector().indexOf(mrow);//re-evaluted index
417 Integer newRow=new Integer(newX);
418 sortColumn.setElementAt(newRow,i);
419 }
420
421 //5. Insert a row to sortColumn. Doesn't matter do it before step 4 or not
422 sortColumn.insertElementAt(new Integer(row),row) ;
423
424 }
425
426
427 }
428 if (!foundSort){
429 assert false: "SortModel does not contain a not-null column";
430 return;
431 }
432
433
434 }//else
435 }
436 /***
437 * @param row edu.psu.geovista.app.spreadsheet.model's row index
438 * if sort, it will be the index for sort edu.psu.geovista.app.spreadsheet.model.
439 * real edu.psu.geovista.app.spreadsheet.model index is transparent to outside
440 */
441 public void removeRow(int row) {
442 if (!sortModel.isTableSort()){//no sort
443 super.removeRow(row);
444 return;
445 }
446 Vector sorts=sortModel.getSorts();
447 Vector sortColumn=null;//a column in SortModel that contain sorting info(index) for a column in real edu.psu.geovista.app.spreadsheet.model
448 boolean foundSort=false;
449 //1. find a valid (not null) column
450 for (int k=0;k<sorts.size() ;k++){//!!! May not work for multi-level sort
451 sortColumn=(Vector)sorts.elementAt(k); //column before a row is insert to real edu.psu.geovista.app.spreadsheet.model
452 if (sortColumn!=null){
453 foundSort=true;
454 //2. Get and the reference to real edu.psu.geovista.app.spreadsheet.model rows, store the reference.
455 Vector tempCol=(Vector)sortColumn.clone() ;//new Vector(sortColumn.size() );
456 for (int i=0;i<sortColumn.size() ;i++){
457 int mx=((Integer)sortColumn.elementAt(i)).intValue() ;//row's index in real edu.psu.geovista.app.spreadsheet.model
458
459 Vector mrow=(Vector)this.getDataVector().elementAt(mx);//the row vector
460 tempCol.setElementAt(mrow,i);
461 }
462 int mx=((Integer)sortColumn.elementAt(row)).intValue() ;//real edu.psu.geovista.app.spreadsheet.model row index
463 super.removeRow(mx);
464 sortColumn.remove(row);
465 tempCol.remove(row);
466 //4.re-evaluate the index of those rows(which obtained in step 2) in real edu.psu.geovista.app.spreadsheet.model after inserting
467 for (int i=0;i<tempCol.size() ;i++){
468 Vector mrow=(Vector)tempCol.elementAt(i);
469 int newX=this.getDataVector().indexOf(mrow);//re-evaluted index
470 if (newX==-1){//
471 assert false:"All tempCol's element should be in real Model ";
472 }
473 else{
474 Integer newRow=new Integer(newX);
475 sortColumn.setElementAt(newRow,i);
476 }
477 } //for
478 } //if
479
480 } //for
481 if (!foundSort){
482 assert false: "SortModel does not contain a not-null column";
483 return;
484 }
485
486
487 }
488 /***
489 * return a cell's edu.psu.geovista.app.spreadsheet.model address.
490 * If table is sort, only return the sort edu.psu.geovista.app.spreadsheet.model address
491 * real edu.psu.geovista.app.spreadsheet.model address is transparent to outside
492 */
493 public Point getCellAddress(Cell cell) {
494 Vector container=cell.getContainer() ;
495 //SSTableModel tmd=SSTableModel.getInstance() ;
496 int mrow=getDataVector().indexOf(container ); //real edu.psu.geovista.app.spreadsheet.model x
497 int mcol=container.indexOf(cell);//real edu.psu.geovista.app.spreadsheet.model y
498 int smrow=mrow;//sort edu.psu.geovista.app.spreadsheet.model's row index
499 if (mrow<0||mcol<0){
500 //!!! happen when you delete a column which is referenced by other columns
501 return null;
502 }
503 if (this.sortModel.isTableSort() ){
504 Vector sorts=this.sortModel.getSorts() ;
505 //Vector columnSort=(Vector)sorts.elementAt(mcol); */
506 Vector columnSort=this.sortModel.getColumnSort(mcol);
507
508 if (columnSort==null){ //no individual column sort on the column, use table sort
509 columnSort=(Vector)sorts.elementAt(0);
510 if (columnSort==null){
511 //No entire-table sort, only have individual-column sort on other column
512 smrow=mrow;
513
514 }
515 else{//entire-table sort
516 Debug.showVector(columnSort, "columnSort "+mrow) ;
517 smrow=columnSort.indexOf(new Integer(mrow));
518 }
519
520 }
521 else{ //individual column sort on the column
522 Debug.showVector(columnSort, "columnSort "+mcol) ;
523 smrow=columnSort.indexOf(new Integer(mrow));
524
525 }
526 }
527
528 return new Point(smrow,mcol);
529
530 }
531
532 /*********************************************************************
533 * Set data
534 ********************************************************************/
535 public void setDataVector(Vector dataVector, Vector columnIdentifiers) {
536
537
538
539 if (Debug.isDebug() ){
540 Debug.showVector(columnIdentifiers, "columnIdentifiers");
541 }
542 super.setDataVector(dataVector,columnIdentifiers);
543 Vector fst=(Vector)dataVector.elementAt(0) ;
544 Object o=fst.elementAt(fst.size()-1);
545 Debug.println("o:"+o);
546 if (o!=null)
547 Debug.println("o type:"+o.getClass().getName() );
548 //!!! make Table update view and create corresponding tableColumns for Model column
549 fireTableChanged(new SSTableModelEvent(this, SSTableModelEvent.RESET_DATA ));
550 }
551
552 public void clearSort() {
553 this.sortModel.clearSort() ;
554 }
555
556 public SSTable getTable() {
557 return table;
558 }
559
560 public void setTable(SSTable table) {
561 this.table = table;
562 }
563 }
This page was automatically generated by Maven