View Javadoc
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