/*!
* 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.ui.datasources.table;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.libraries.designtime.swing.FormattingTableCellRenderer;
import org.pentaho.reporting.libraries.designtime.swing.GenericCellEditor;
import org.pentaho.reporting.libraries.designtime.swing.GenericCellRenderer;
import org.pentaho.reporting.libraries.designtime.swing.date.DateCellEditor;
import org.pentaho.reporting.libraries.designtime.swing.date.TimeCellEditor;
import org.pentaho.reporting.libraries.designtime.swing.settings.LocaleSettings;
import javax.swing.*;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TableEditor extends JTable {
private static final Log logger = LogFactory.getLog( TableEditor.class );
private TableEditorModel tableModel;
private TableColumn selectedColumn;
private EditableHeader tableHeader;
public TableEditor() {
tableModel = new TableEditorModel();
tableHeader = new EditableHeader( getColumnModel(), tableModel );
setTableHeader( tableHeader );
setModel( tableModel );
setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION );
final SimpleDateFormat isoDateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS" );
setDefaultRenderer( Date.class, new FormattingTableCellRenderer( isoDateFormat ) );
setDefaultRenderer( java.sql.Date.class, new FormattingTableCellRenderer( new SimpleDateFormat( "yyyy-MM-dd" ) ) );
setDefaultRenderer( Time.class, new FormattingTableCellRenderer( new SimpleDateFormat( "HH:mm:ss.SSS" ) ) );
setDefaultRenderer( Timestamp.class, new FormattingTableCellRenderer( isoDateFormat ) );
setDefaultRenderer( String.class, new GenericCellRenderer() );
setDefaultRenderer( Object.class, new GenericCellRenderer() );
setDefaultEditor( Number.class, new GenericCellEditor( BigDecimal.class ) );
setDefaultEditor( Integer.class, new GenericCellEditor( Integer.class ) );
setDefaultEditor( Float.class, new GenericCellEditor( Float.class ) );
setDefaultEditor( Double.class, new GenericCellEditor( Double.class ) );
setDefaultEditor( Short.class, new GenericCellEditor( Short.class ) );
setDefaultEditor( Byte.class, new GenericCellEditor( Byte.class ) );
setDefaultEditor( Long.class, new GenericCellEditor( Long.class ) );
setDefaultEditor( BigInteger.class, new GenericCellEditor( BigInteger.class ) );
setDefaultEditor( BigDecimal.class, new GenericCellEditor( BigDecimal.class ) );
setDefaultEditor( String.class, new GenericCellEditor( String.class, true ) );
setDefaultEditor( Object.class, new GenericCellEditor( String.class, false ) );
setDefaultEditor( Date.class, new DateCellEditor( Date.class ) );
setDefaultEditor( java.sql.Date.class, new DateCellEditor( java.sql.Date.class ) );
setDefaultEditor( Time.class, new TimeCellEditor( Time.class ) );
setDefaultEditor( Timestamp.class, new DateCellEditor( Timestamp.class ) );
updateUI();
}
public void applyLocaleSettings( final LocaleSettings localeSettings ) {
try {
final SimpleDateFormat isoDateFormat =
new SimpleDateFormat( localeSettings.getDatetimeFormatPattern(), localeSettings.getLocale() );
isoDateFormat.setTimeZone( localeSettings.getTimeZone() );
setDefaultRenderer( Date.class, new FormattingTableCellRenderer( isoDateFormat ) );
setDefaultRenderer( Timestamp.class, new FormattingTableCellRenderer( isoDateFormat ) );
final DateCellEditor dateCellEditor = new DateCellEditor( Date.class );
dateCellEditor.setDateFormat( isoDateFormat );
setDefaultEditor( Date.class, dateCellEditor );
final DateCellEditor timestampEditor = new DateCellEditor( Timestamp.class );
timestampEditor.setDateFormat( isoDateFormat );
setDefaultEditor( Timestamp.class, timestampEditor );
} catch ( Exception e ) {
logger.warn( "Invalid format string found in locale settings", e );
}
try {
final SimpleDateFormat dateFormat =
new SimpleDateFormat( localeSettings.getDateFormatPattern(), localeSettings.getLocale() );
dateFormat.setTimeZone( localeSettings.getTimeZone() );
setDefaultRenderer( java.sql.Date.class, new FormattingTableCellRenderer( dateFormat ) );
final DateCellEditor dateCellEditor = new DateCellEditor( java.sql.Date.class );
dateCellEditor.setDateFormat( dateFormat );
setDefaultEditor( java.sql.Date.class, dateCellEditor );
} catch ( Exception e ) {
logger.warn( "Invalid format string found in locale settings", e );
}
try {
final SimpleDateFormat timeFormat =
new SimpleDateFormat( localeSettings.getTimeFormatPattern(), localeSettings.getLocale() );
timeFormat.setTimeZone( localeSettings.getTimeZone() );
setDefaultRenderer( Time.class, new FormattingTableCellRenderer( timeFormat ) );
final TimeCellEditor timeCellEditor = new TimeCellEditor( Time.class );
timeCellEditor.setDateFormat( timeFormat );
setDefaultEditor( Time.class, timeCellEditor );
} catch ( Exception e ) {
logger.warn( "Invalid format string found in locale settings", e );
}
}
/**
* Creates default columns for the table from the data model using the <code>getColumnCount</code> method defined in
* the <code>TableModel</code> interface.
* <p/>
* Clears any existing columns before creating the new columns based on information from the model.
*
* @see #getAutoCreateColumnsFromModel
*/
public void createDefaultColumnsFromModel() {
final TableModel m = getModel();
if ( m != null ) {
// Remove any current columns
final TableColumnModel cm = getColumnModel();
while ( cm.getColumnCount() > 0 ) {
cm.removeColumn( cm.getColumn( 0 ) );
}
// Create new columns from the data model info
for ( int i = 0; i < m.getColumnCount(); i++ ) {
if ( i == 0 ) {
final TableColumn column = new TableColumn( i );
column.setCellRenderer( tableHeader.getDefaultRenderer() );
addColumn( column );
continue;
}
final EditableHeaderTableColumn newColumn = new EditableHeaderTableColumn( i );
newColumn.setHeaderEditor( new TypedHeaderCellEditor() );
addColumn( newColumn );
}
}
}
public void addColumn( final TableColumn column ) {
stopEditing();
if ( column.getHeaderValue() == null ) {
final int modelColumn = column.getModelIndex();
final String columnName = getModel().getColumnName( modelColumn );
if ( modelColumn == 0 ) {
column.setResizable( false );
column.setHeaderValue( columnName );
column.setPreferredWidth( 30 );
column.setMaxWidth( 30 );
column.setMinWidth( 30 );
} else {
final Class columnType = getModel().getColumnClass( modelColumn );
column.setHeaderValue( new TypedHeaderInformation( columnType, columnName ) );
}
}
getColumnModel().addColumn( column );
}
public void addColumn( final String aHeaderName ) {
stopEditing();
tableHeader.removeEditor();
tableModel.addColumn( aHeaderName, String.class );
}
public void addRow() {
stopEditing();
final int row = getSelectedRow();
if ( row == -1 ) {
tableModel.addRow();
setRowSelectionInterval( getRowCount() - 1, getRowCount() - 1 );
} else {
tableModel.addRow( row + 1 );
setRowSelectionInterval( row + 1, row + 1 );
}
}
public void removeRow() {
stopEditing();
final int[] rows = getSelectedRows();
for ( int i = rows.length - 1; i >= 0; i -= 1 ) {
final int row = rows[ i ];
tableModel.removeRow( row );
}
tableModel.fireTableDataChanged();
}
public void removeColumn() {
stopEditing();
tableHeader.removeEditor();
final int modelIndex = selectedColumn.getModelIndex();
if ( modelIndex == 0 ) {
return;
}
tableModel.removeColumn( modelIndex - 1 );
}
public void setSelectedColumn( final TableColumn aSelectedColumn ) {
selectedColumn = aSelectedColumn;
}
public void setTableEditorModel( final TableModel model ) {
tableModel.copyInto( model );
}
public TableModel getTableEditorModel() {
return tableModel.createModel();
}
public void stopEditing() {
final TableCellEditor cellEditor = getCellEditor();
if ( cellEditor != null ) {
cellEditor.stopCellEditing();
}
}
}