package ca.sqlpower.swingui.table;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import org.apache.log4j.Logger;
/**
* This class implements the workarounds for the bugs in the jTable
*
*/
public class EditableJTable extends JTable implements TableTextConverter {
private static final Logger logger = Logger.getLogger(EditableJTable.class);
public EditableJTable() {
this(null);
}
public EditableJTable(TableModel model) {
super(model);
putClientProperty("terminateEditOnFocusLost", true);
setTableHeader(createDefaultTableHeader());
}
@Override
public boolean getScrollableTracksViewportWidth() {
return getPreferredSize().width < getParent().getWidth();
}
@Override
public void removeNotify() {
super.removeNotify();
logger.debug("Table removed from hierarchy. Cleaning up model...");
if (getModel() instanceof CleanupTableModel) {
((CleanupTableModel) getModel()).cleanup();
}
}
@Override
public void columnMarginChanged(ChangeEvent pE) {
if (getEditingColumn() != -1 || getEditingRow() != -1) {
editCellAt(0, 0);
}
super.columnMarginChanged(pE);
}
public String getTextForCell(Object o) {
if (o != null) {
return o.toString();
} else {
return "N/A";
}
}
public int modelIndex(int viewIndex) {
return viewIndex;
}
/**
* Just logs the call and forwards to superclass implementation.
*/
@Override
public void setModel(TableModel dataModel) {
logger.debug("Table Model change for EditableJTable "+this+
". Old model: "+getModel()+" new model: "+dataModel);
super.setModel(dataModel);
}
/**
* Just logs the call and forwards to superclass implementation.
*/
@Override
public void setSelectionModel(ListSelectionModel newModel) {
logger.debug("Table Selection Model change for EditableJTable "+this+
". Old model: "+getSelectionModel()+" new model: "+newModel);
super.setSelectionModel(newModel);
}
@Override
public TableCellEditor getCellEditor() {
TableCellEditor editor = super.getCellEditor();
logger.debug("EditableJTable.getCellEditor(): returning "+editor);
return editor;
}
@Override
public TableCellEditor getCellEditor(int row, int column) {
TableColumn tableColumn = getColumnModel().getColumn(column);
TableCellEditor returnVal = super.getCellEditor(row, column);
logger.debug("EditableJTable.getCellEditor("+row+","+column+"): returning "+returnVal
+" (tableColumn.getCellEditor()="+tableColumn.getCellEditor()+")");
return returnVal;
}
/**
* Taken from the Bug ID: 4292511 of bug parade as a workaround
*
* Thanks milnep1!!
*/
protected JTableHeader createDefaultTableHeader() {
return new JTableHeader(columnModel) {
private int preferredHeight = -1;
private Component getHeaderRenderer(int columnIndex) {
TableColumn aColumn = getColumnModel().getColumn(columnIndex);
TableCellRenderer renderer = aColumn.getHeaderRenderer();
if (renderer == null) {
renderer = getDefaultRenderer();
}
return renderer.getTableCellRendererComponent(getTable(), aColumn.getHeaderValue(), false, false, -1,
columnIndex);
}
private int getPreferredHeight() {
if (preferredHeight == -1) {
preferredHeight = 0;
TableColumnModel columnModel = getColumnModel();
for (int column = 0; column < columnModel.getColumnCount(); column++) {
Component comp = getHeaderRenderer(column);
int rendererHeight = comp.getPreferredSize().height;
preferredHeight = Math.max(preferredHeight, rendererHeight);
}
}
return preferredHeight;
}
public Dimension getPreferredSize() {
return new Dimension(super.getPreferredSize().width, getPreferredHeight());
}
public void columnAdded(TableColumnModelEvent e) {
preferredHeight = -1;
super.columnAdded(e);
}
public void columnRemoved(TableColumnModelEvent e) {
preferredHeight = -1;
super.columnRemoved(e);
}
};
}
}