package com.link_intersystems.swing;
import java.math.BigInteger;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import com.link_intersystems.math.Aggregate;
import com.link_intersystems.math.BigIntegerSum;
public class SumTableModel extends AbstractTableModel {
private static final long serialVersionUID = -3604774516854551825L;
/**
* {@value}
*/
private static final String SUM_SYMBOL = "\u03A3";
private static final String DEFAULT_SUMMARY_COLUMN_NAME_FORMAT = "%s %s";
private TableModelSync tableModelSync = new TableModelSync();
private TableModel tableModel;
private Aggregate<? extends Number>[] aggregateColumns;
private String columnNameFormat = DEFAULT_SUMMARY_COLUMN_NAME_FORMAT;
public SumTableModel(TableModel tableModel) {
setTableModel(tableModel);
}
public void setTableModel(TableModel tableModel) {
if (this.tableModel != null) {
this.tableModel.removeTableModelListener(tableModelSync);
}
this.tableModel = tableModel;
if (this.tableModel != null) {
this.tableModel.addTableModelListener(tableModelSync);
tableModelUpdated();
}
}
@Override
public int getRowCount() {
return 1;
}
@Override
public String getColumnName(int column) {
String columnName = tableModel.getColumnName(column);
String summaryColumnName = String.format(columnNameFormat, SUM_SYMBOL,
columnName);
return summaryColumnName;
}
@Override
public int getColumnCount() {
return tableModel.getColumnCount();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Aggregate<? extends Number> columnAggregate = getColumnAggregate(columnIndex);
return columnAggregate.getValue();
}
private Aggregate<? extends Number> getColumnAggregate(int columnIndex) {
Aggregate<? extends Number> aggregate = this.aggregateColumns[columnIndex];
if (aggregate == null) {
Class<?> columnClass = tableModel.getColumnClass(columnIndex);
Aggregate<? extends Number> columnAggregate = createAggregate(columnClass);
createSummary(columnAggregate, columnIndex);
aggregateColumns[columnIndex] = columnAggregate;
aggregate = columnAggregate;
}
return aggregate;
}
private void createSummary(Aggregate<? extends Number> columnAggregate,
int columnIndex) {
int rowCount = tableModel.getRowCount();
if (BigInteger.class.equals(tableModel.getColumnClass(columnIndex))) {
for (int i = 0; i < rowCount; i++) {
BigInteger columnValue = (BigInteger) tableModel.getValueAt(i,
columnIndex);
columnAggregate.addValue(columnValue);
}
} else {
columnAggregate.addValue(rowCount);
}
}
private Aggregate<? extends Number> createAggregate(Class<?> columnClass) {
return new BigIntegerSum();
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return tableModel.getColumnClass(columnIndex);
}
@SuppressWarnings("unchecked")
private void tableModelUpdated() {
this.aggregateColumns = new Aggregate[getColumnCount()];
}
private class TableModelSync implements TableModelListener {
@Override
public void tableChanged(TableModelEvent e) {
tableModelUpdated();
}
}
}