1 7 8 package org.jdesktop.swing.data; 9 10 import org.jdesktop.swing.data.MetaData; 11 12 import org.jdesktop.swing.event.MessageEvent; 13 import org.jdesktop.swing.event.MessageListener; 14 import org.jdesktop.swing.event.ProgressEvent; 15 import org.jdesktop.swing.event.ProgressListener; 16 17 import java.beans.PropertyChangeEvent ; 18 import java.beans.PropertyChangeListener ; 19 import java.beans.PropertyChangeSupport ; 20 21 import java.io.InputStream ; 22 import java.io.IOException ; 23 24 import java.net.MalformedURLException ; 25 import java.net.URL ; 26 27 import java.util.List ; 28 import java.util.Vector ; 29 30 import javax.swing.event.TableModelEvent ; 31 import javax.swing.event.TableModelListener ; 32 import javax.swing.table.AbstractTableModel ; 33 34 35 150 public class DefaultTableModelExt extends AbstractTableModel implements MetaDataProvider { 151 152 private URL sourceURL; 153 154 private DataLoader loader; 156 157 private MetaData[] columnMetaData; 158 private Vector rows; 159 160 private boolean loading = false; 161 private boolean readOnly = false; 162 163 private PropertyChangeListener columnMetaDataListener; 164 165 private PropertyChangeSupport pcs; 166 167 170 public DefaultTableModelExt() { 171 this(0); 172 } 173 174 181 public DefaultTableModelExt(int columnCount) { 182 init(); 183 setColumnCount(columnCount); 184 } 185 186 193 public DefaultTableModelExt(String urlName) throws MalformedURLException { 194 this(); 195 setSource(urlName); 196 } 197 198 203 public DefaultTableModelExt(URL sourceURL) { 204 this(); 205 setSource(sourceURL); 206 } 207 208 219 public DefaultTableModelExt(String urlName, int columnCount) throws MalformedURLException { 220 this(columnCount); 221 setSource(urlName); 222 } 223 224 private void init() { 225 columnMetaDataListener = new MetaDataChangeListener(); 226 pcs = new PropertyChangeSupport (this); 227 setLoader(new TableModelExtTextLoader()); 228 } 229 230 238 public void setSource(String urlName) throws MalformedURLException { 239 setSource(new URL (urlName)); 240 } 241 242 247 public void setSource(URL sourceURL) { 248 URL oldSource = this.sourceURL; 249 this.sourceURL = sourceURL; 250 pcs.firePropertyChange("source", oldSource, sourceURL); 251 } 252 253 257 public URL getSource() { 258 return sourceURL; 259 } 260 261 267 public void setLoader(DataLoader loader) { 268 DataLoader oldLoader = this.loader; 269 this.loader = loader; 270 pcs.firePropertyChange("loader", oldLoader, loader); 271 } 272 273 283 public DataLoader getLoader() { 284 return loader; 285 } 286 287 295 public int getColumnCount() { 296 synchronized(this) { 297 ensureMetaDataInitialized(); 298 return columnMetaData.length; 299 } 300 } 301 302 313 public void setColumnCount(int columnCount) { 314 if (columnCount < 0) { 315 throw new IllegalArgumentException ("column count, " + columnCount + 316 " is < 0"); 317 } 318 int oldColumnCount = columnMetaData != null ? columnMetaData.length : 319 0; 320 synchronized(this) { 321 if (columnMetaData != null) { 322 for (int i = 0; i < columnMetaData.length; i++) { 323 columnMetaData[i].removePropertyChangeListener( 324 columnMetaDataListener); 325 } 326 } 327 columnMetaData = new MetaData[columnCount]; 328 for (int i = 0; i < columnMetaData.length; i++) { 329 columnMetaData[i] = new MetaData("column" + i); 330 columnMetaData[i].addPropertyChangeListener( 331 columnMetaDataListener); 332 } 333 rows = new Vector (); 334 } 335 fireTableStructureChanged(); 336 pcs.firePropertyChange("columnCount", oldColumnCount, columnCount); 337 } 338 339 350 public MetaData getColumnMetaData(int columnIndex) { 351 synchronized(this) { 352 ensureMetaDataInitialized(); 353 return columnMetaData[columnIndex]; 354 } 355 } 356 357 363 public MetaData getMetaData(String columnName) { 364 int columnIndex = getColumnIndex(columnName); 365 return getColumnMetaData(columnIndex); 366 } 367 368 376 public MetaData[] getMetaData() { 377 ensureMetaDataInitialized(); 378 MetaData metaDataCopy[] = new MetaData[columnMetaData.length]; 379 System.arraycopy(columnMetaData, 0, metaDataCopy, 0, columnMetaData.length); 380 return metaDataCopy; 381 } 382 383 384 public String [] getFieldNames() { 385 ensureMetaDataInitialized(); 386 String [] names = new String [getFieldCount()]; 387 for (int i = 0; i < names.length; i++) { 388 names[i] = getColumnMetaData(i).getName(); 389 } 390 return names; 391 } 392 393 public int getFieldCount() { 394 return getColumnCount(); 395 } 396 397 405 public void setColumnMetaData(int columnIndex, MetaData metaData) { 406 synchronized(this) { 407 if (columnMetaData[columnIndex] != null) { 408 columnMetaData[columnIndex].removePropertyChangeListener( 409 columnMetaDataListener); 410 } 411 columnMetaData[columnIndex] = metaData; 412 metaData.addPropertyChangeListener(columnMetaDataListener); 413 } 414 fireTableStructureChanged(); 415 } 416 417 private void ensureMetaDataInitialized() { 418 if (columnMetaData == null || columnMetaData.length == 0) { 419 initializeMetaData(); 420 } 421 } 422 423 private boolean initializeMetaData() { 424 if (sourceURL != null && loader != null) { 425 try { 426 final InputStream is = sourceURL.openStream(); 427 loader.loadMetaData(this, is); 428 is.close(); 429 return true; 430 } catch (Exception e) { 431 return false; 432 } 433 } 434 return false; 435 } 436 437 446 public Class getColumnClass(int columnIndex) { 447 ensureMetaDataInitialized(); 448 return columnMetaData[columnIndex].getElementClass(); 449 } 450 451 461 public String getColumnName(int columnIndex) { 462 ensureMetaDataInitialized(); 463 return columnMetaData[columnIndex].getLabel(); 464 } 465 466 478 public boolean isCellEditable(int rowIndex, int columnIndex) { 479 ensureMetaDataInitialized(); 480 return !columnMetaData[columnIndex].isReadOnly(); 481 } 482 483 487 public int getRowCount() { 488 return rows.size(); 489 } 490 491 500 public Object getValueAt(int rowIndex, int columnIndex) { 501 Object row[] = (Object [])rows.get(rowIndex); 502 return row[columnIndex]; 503 } 504 505 519 public void setValueAt(Object value, int rowIndex, int columnIndex) { 520 if (isCellEditable(rowIndex, columnIndex)) { 521 synchronized(this.rows) { 522 Object row[] = (Object []) rows.get(rowIndex); 523 row[columnIndex] = value; 524 fireTableCellUpdated(rowIndex, columnIndex); 525 } 526 } else { 527 throw new RuntimeException ("row " + rowIndex +" column " + columnIndex + 528 " is not editable"); 529 } 530 } 531 532 538 public void deleteRow(int rowIndex) { 539 synchronized(this.rows) { 540 rows.remove(rowIndex); 541 fireTableRowsDeleted(rowIndex, rowIndex); 542 } 543 } 544 545 556 public void deleteRows(int firstRowIndex, int lastRowIndex) { 557 if (lastRowIndex < firstRowIndex) { 558 throw new IllegalArgumentException ("lastRowIndex, " + lastRowIndex + 559 " cannot be less than firstRowIndex, "+ 560 firstRowIndex); 561 } 562 synchronized(this.rows) { 563 int deletedRowCount = lastRowIndex - firstRowIndex + 1; 564 for(int i = 0; i < deletedRowCount; i++) { 565 rows.remove(firstRowIndex); 566 } 567 fireTableRowsDeleted(firstRowIndex, lastRowIndex); 568 } 569 } 570 571 572 573 583 public void insertRow(int rowIndex, Object row[]) { 584 insertRowImpl(rowIndex, row); 585 fireTableRowsInserted(rowIndex, rowIndex); 586 } 587 588 601 public void insertRows(int rowIndex, List rows) { 602 synchronized(this.rows) { 603 for (int i = 0; i < rows.size(); i++) { 604 Object row[] = (Object []) rows.get(i); 605 insertRowImpl(rowIndex + i, row); 606 } 607 fireTableRowsInserted(rowIndex, rowIndex+rows.size()-1); 608 } 609 } 610 611 618 public void addRow(Object row[]) { 619 int rowIndex = rows.size(); 620 insertRowImpl(rowIndex, row); 621 fireTableRowsInserted(rowIndex, rowIndex); 622 } 623 624 633 public void addRows(List rows) { 634 insertRows(this.rows.size(), rows); 635 } 636 637 638 void loadRows(List rows) { 639 synchronized(this.rows) { 640 int rowIndex = this.rows.size(); 641 this.rows.addAll(rows); 642 fireTableRowsInserted(rowIndex, rowIndex+rows.size()); 643 } 644 } 645 646 private void insertRowImpl(int rowIndex, Object [] row) { 647 int rowLength = getColumnCount(); 648 Object [] newRow = new Object [rowLength]; 649 System.arraycopy(row, 0, newRow, 0, rowLength); 650 rows.insertElementAt(newRow, rowIndex); 651 } 652 653 654 663 public void startLoading() throws IOException { 664 if (sourceURL == null) { 665 throw new IllegalStateException ( 666 "data cannot be loaded when source URL is null"); 667 } 668 if (isLoading()) { 669 return; 670 } 671 ensureMetaDataInitialized(); 672 final InputStream is = sourceURL.openStream(); 674 675 setLoading(true); 676 rows.clear(); 677 678 MessageAdapter a = new MessageAdapter(is); 680 loader.addProgressListener(a); 681 loader.addMessageListener(a); 682 683 loader.startLoading(this, is); 684 } 685 686 private class MessageAdapter implements ProgressListener, MessageListener { 687 688 private InputStream is; 689 690 693 public MessageAdapter(InputStream is) { 694 this.is = is; 695 } 696 697 public void progressStarted(ProgressEvent event) { 698 } 699 700 public void progressIncremented(ProgressEvent event) { 701 } 702 703 public void progressEnded(ProgressEvent event) { 704 cleanup((DataLoader) event.getSource()); 705 } 706 707 public void message(MessageEvent event) { 708 if (event.getThrowable() != null) { 709 cleanup((DataLoader) event.getSource()); 710 } 711 System.out.println(event); 714 715 } 716 717 private void cleanup(DataLoader loader) { 718 loader.removeProgressListener(this); 719 setLoading(false); 720 try { 721 is.close(); 722 } 723 catch (IOException e) { 724 } 725 } 726 } 727 728 732 public boolean isLoading() { 733 return loading; 734 } 735 736 private void setLoading(boolean loading) { 737 boolean oldLoading = this.loading; 738 this.loading = loading; 739 pcs.firePropertyChange("loading", oldLoading, loading); 740 } 741 742 755 public Object [] getRow(int rowIndex) { 756 int columnCount = getColumnCount(); 757 Object row[] = new Object [columnCount]; 758 System.arraycopy((Object [])rows.get(rowIndex), 0, 759 row, 0, columnCount); 760 return row; 761 762 } 763 764 776 public int getColumnIndex(String columnName) { 777 for (int i = 0; i < columnMetaData.length; i++) { 778 if (columnMetaData[i].getName().equals(columnName)) { 779 return i; 780 } 781 } 782 throw new IllegalArgumentException ("\""+columnName+"\" not found in tabular data object"); 783 } 784 785 790 public void addPropertyChangeListener(PropertyChangeListener pcl) { 791 pcs.addPropertyChangeListener(pcl); 792 } 793 794 799 public void removePropertyChangeListener(PropertyChangeListener pcl) { 800 pcs.removePropertyChangeListener(pcl); 801 } 802 803 808 public PropertyChangeListener [] getPropertyChangeListeners() { 809 return pcs.getPropertyChangeListeners(); 810 } 811 812 private class MetaDataChangeListener implements PropertyChangeListener { 813 public void propertyChange(PropertyChangeEvent e) { 814 String propertyName = e.getPropertyName(); 815 if (propertyName.equals("elementClass") || 816 propertyName.equals("name")) { 817 DefaultTableModelExt.this.fireTableStructureChanged(); 818 } 819 } 820 } 821 822 } 823 | Popular Tags |