/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.reporting.engine.classic.core.util; import org.pentaho.reporting.libraries.base.util.GenericObjectTable; import javax.swing.table.AbstractTableModel; import java.util.ArrayList; public class TypedTableModel extends AbstractTableModel { private ArrayList<String> columnNames; private ArrayList<Class<?>> columnClasses; private GenericObjectTable<Object> data; public TypedTableModel() { this( 10, 10 ); } public TypedTableModel( final int rowIncrement, final int columnIncrement ) { data = new GenericObjectTable<Object>( Math.max( 1, rowIncrement ), Math.max( 1, columnIncrement ) ); columnNames = new ArrayList<String>( columnIncrement ); columnClasses = new ArrayList<Class<?>>( columnIncrement ); } public TypedTableModel( final String[] columnNames ) { this( 10, columnNames.length ); for ( int i = 0; i < columnNames.length; i++ ) { final String columnName = columnNames[i]; this.columnNames.add( columnName ); this.columnClasses.add( Object.class ); } } public TypedTableModel( final String[] columnNames, final Class<?>[] columnClasses ) { this( columnNames, columnClasses, 10 ); } public TypedTableModel( final String[] columnNames, final Class<?>[] columnClasses, final int rowCount ) { this( rowCount, columnNames.length ); if ( columnNames.length != columnClasses.length ) { throw new IllegalArgumentException(); } for ( int i = 0; i < columnNames.length; i++ ) { final String columnName = columnNames[i]; this.columnNames.add( columnName ); this.columnClasses.add( columnClasses[i] ); } } public void addColumn( final String name, final Class<?> type ) { if ( name == null ) { throw new NullPointerException(); } if ( type == null ) { throw new NullPointerException(); } this.columnNames.add( name ); this.columnClasses.add( type ); } /** * Returns the number of rows in the model. A <code>JTable</code> uses this method to determine how many rows it * should display. This method should be quick, as it is called frequently during rendering. * * @return the number of rows in the model * @see #getColumnCount */ public int getRowCount() { return data.getRowCount(); } /** * Returns the number of columns in the model. A <code>JTable</code> uses this method to determine how many columns it * should create and display by default. * * @return the number of columns in the model * @see #getRowCount */ public int getColumnCount() { return columnNames.size(); } /** * Returns the name of the column at <code>columnIndex</code>. This is used to initialize the table's column header * name. Note: this name does not need to be unique; two columns in a table can have the same name. * * @param columnIndex * the index of the column * @return the name of the column */ public String getColumnName( final int columnIndex ) { return columnNames.get( columnIndex ); } /** * Returns the most specific superclass for all the cell values in the column. This is used by the <code>JTable</code> * to set up a default renderer and editor for the column. * * @param columnIndex * the index of the column * @return the common ancestor class of the object values in the model. */ public Class<?> getColumnClass( final int columnIndex ) { return (Class) columnClasses.get( columnIndex ); } /** * Returns true if the cell at <code>rowIndex</code> and <code>columnIndex</code> is editable. Otherwise, * <code>setValueAt</code> on the cell will not change the value of that cell. * * @param rowIndex * the row whose value to be queried * @param columnIndex * the column whose value to be queried * @return true if the cell is editable */ public boolean isCellEditable( final int rowIndex, final int columnIndex ) { return true; } /** * Returns the value for the cell at <code>columnIndex</code> and <code>rowIndex</code>. * * @param rowIndex * the row whose value is to be queried * @param columnIndex * the column whose value is to be queried * @return the value Object at the specified cell */ public Object getValueAt( final int rowIndex, final int columnIndex ) { return data.getObject( rowIndex, columnIndex ); } /** * Sets the value in the cell at <code>columnIndex</code> and <code>rowIndex</code> to <code>aValue</code>. * * @param aValue * the new value * @param rowIndex * the row whose value is to be changed * @param columnIndex * the column whose value is to be changed */ public void setValueAt( final Object aValue, final int rowIndex, final int columnIndex ) { data.setObject( rowIndex, columnIndex, aValue ); fireTableCellUpdated( rowIndex, columnIndex ); } public void setColumnType( final int colIndex, final Class<?> type ) { if ( type == null ) { throw new NullPointerException(); } columnClasses.set( colIndex, type ); fireTableStructureChanged(); } public void setColumnName( final int colIndex, final String name ) { if ( name == null ) { throw new NullPointerException(); } columnNames.set( colIndex, name ); fireTableStructureChanged(); } public void addRow( final Object... objects ) { final int row = getRowCount(); if ( objects.length == 0 ) { setValueAt( null, row, 0 ); } else { final int maxCols = Math.min( objects.length, getColumnCount() ); for ( int i = 0; i < maxCols; i++ ) { setValueAt( objects[i], row, i ); } } fireTableDataChanged(); } public String toString() { final StringBuilder sb = new StringBuilder(); sb.append( "TypedTableModel" ); sb.append( "{columnNames=" ).append( columnNames ); sb.append( ", columnClasses=" ).append( columnClasses ); sb.append( ", rowCount=" ).append( getRowCount() ); sb.append( '}' ); return sb.toString(); } }