// Example from http://www.crionics.com/products/opensource/faq/swing_ex/SwingExamples.html
import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.EventObject;
import javax.swing.DefaultCellEditor;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.basic.BasicTableHeaderUI;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
/**
* @version 1.0 08/22/99
*/
public class EditableHeaderTableExample extends JFrame {
public EditableHeaderTableExample() {
super("EditableHeader Example");
JTable table = new JTable(7, 5);
TableColumnModel columnModel = table.getColumnModel();
table.setTableHeader(new EditableHeader(columnModel));
JScrollPane pane = new JScrollPane(table);
getContentPane().add(pane);
}
public static void main(String[] args) {
EditableHeaderTableExample frame = new EditableHeaderTableExample();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setSize(300, 100);
frame.setVisible(true);
}
}
class EditableHeader extends JTableHeader implements CellEditorListener {
public final int HEADER_ROW = -10;
transient protected int editingColumn;
transient protected TableCellEditor cellEditor;
transient protected Component editorComp;
public EditableHeader(TableColumnModel columnModel) {
super(columnModel);
setReorderingAllowed(false);
cellEditor = null;
recreateTableColumn(columnModel);
}
public void updateUI() {
setUI(new EditableHeaderUI());
resizeAndRepaint();
invalidate();
}
protected void recreateTableColumn(TableColumnModel columnModel) {
int n = columnModel.getColumnCount();
EditableHeaderTableColumn[] newCols = new EditableHeaderTableColumn[n];
TableColumn[] oldCols = new TableColumn[n];
for (int i = 0; i < n; i++) {
oldCols[i] = columnModel.getColumn(i);
newCols[i] = new EditableHeaderTableColumn();
newCols[i].copyValues(oldCols[i]);
}
for (int i = 0; i < n; i++) {
columnModel.removeColumn(oldCols[i]);
}
for (int i = 0; i < n; i++) {
columnModel.addColumn(newCols[i]);
}
}
public boolean editCellAt(int index) {
return editCellAt(index);
}
public boolean editCellAt(int index, EventObject e) {
if (cellEditor != null && !cellEditor.stopCellEditing()) {
return false;
}
if (!isCellEditable(index)) {
return false;
}
TableCellEditor editor = getCellEditor(index);
if (editor != null && editor.isCellEditable(e)) {
editorComp = prepareEditor(editor, index);
editorComp.setBounds(getHeaderRect(index));
add(editorComp);
editorComp.validate();
setCellEditor(editor);
setEditingColumn(index);
editor.addCellEditorListener(this);
return true;
}
return false;
}
public boolean isCellEditable(int index) {
if (getReorderingAllowed()) {
return false;
}
int columnIndex = columnModel.getColumn(index).getModelIndex();
EditableHeaderTableColumn col = (EditableHeaderTableColumn) columnModel
.getColumn(columnIndex);
return col.isHeaderEditable();
}
public TableCellEditor getCellEditor(int index) {
int columnIndex = columnModel.getColumn(index).getModelIndex();
EditableHeaderTableColumn col = (EditableHeaderTableColumn) columnModel
.getColumn(columnIndex);
return col.getHeaderEditor();
}
public void setCellEditor(TableCellEditor newEditor) {
TableCellEditor oldEditor = cellEditor;
cellEditor = newEditor;
// firePropertyChange
if (oldEditor != null && oldEditor instanceof TableCellEditor) {
((TableCellEditor) oldEditor)
.removeCellEditorListener((CellEditorListener) this);
}
if (newEditor != null && newEditor instanceof TableCellEditor) {
((TableCellEditor) newEditor)
.addCellEditorListener((CellEditorListener) this);
}
}
public Component prepareEditor(TableCellEditor editor, int index) {
Object value = columnModel.getColumn(index).getHeaderValue();
boolean isSelected = true;
int row = HEADER_ROW;
JTable table = getTable();
Component comp = editor.getTableCellEditorComponent(table, value,
isSelected, row, index);
if (comp instanceof JComponent) {
((JComponent) comp).setNextFocusableComponent(this);
}
return comp;
}
public TableCellEditor getCellEditor() {
return cellEditor;
}
public Component getEditorComponent() {
return editorComp;
}
public void setEditingColumn(int aColumn) {
editingColumn = aColumn;
}
public int getEditingColumn() {
return editingColumn;
}
public void removeEditor() {
TableCellEditor editor = getCellEditor();
if (editor != null) {
editor.removeCellEditorListener(this);
requestFocus();
remove(editorComp);
int index = getEditingColumn();
Rectangle cellRect = getHeaderRect(index);
setCellEditor(null);
setEditingColumn(-1);
editorComp = null;
repaint(cellRect);
}
}
public boolean isEditing() {
return (cellEditor == null) ? false : true;
}
//
// CellEditorListener
//
public void editingStopped(ChangeEvent e) {
TableCellEditor editor = getCellEditor();
if (editor != null) {
Object value = editor.getCellEditorValue();
int index = getEditingColumn();
columnModel.getColumn(index).setHeaderValue(value);
removeEditor();
}
}
public void editingCanceled(ChangeEvent e) {
removeEditor();
}
//
// public void setReorderingAllowed(boolean b) {
// reorderingAllowed = false;
// }
}
class EditableHeaderUI extends BasicTableHeaderUI {
protected MouseInputListener createMouseInputListener() {
return new MouseInputHandler((EditableHeader) header);
}
public class MouseInputHandler extends BasicTableHeaderUI.MouseInputHandler {
private Component dispatchComponent;
protected EditableHeader header;
public MouseInputHandler(EditableHeader header) {
this.header = header;
}
private void setDispatchComponent(MouseEvent e) {
Component editorComponent = header.getEditorComponent();
Point p = e.getPoint();
Point p2 = SwingUtilities.convertPoint(header, p, editorComponent);
dispatchComponent = SwingUtilities.getDeepestComponentAt(
editorComponent, p2.x, p2.y);
}
private boolean repostEvent(MouseEvent e) {
if (dispatchComponent == null) {
return false;
}
MouseEvent e2 = SwingUtilities.convertMouseEvent(header, e,
dispatchComponent);
dispatchComponent.dispatchEvent(e2);
return true;
}
public void mousePressed(MouseEvent e) {
if (!SwingUtilities.isLeftMouseButton(e)) {
return;
}
super.mousePressed(e);
if (header.getResizingColumn() == null) {
Point p = e.getPoint();
TableColumnModel columnModel = header.getColumnModel();
int index = columnModel.getColumnIndexAtX(p.x);
if (index != -1) {
if (header.editCellAt(index, e)) {
setDispatchComponent(e);
repostEvent(e);
}
}
}
}
public void mouseReleased(MouseEvent e) {
super.mouseReleased(e);
if (!SwingUtilities.isLeftMouseButton(e)) {
return;
}
repostEvent(e);
dispatchComponent = null;
}
}
}
class EditableHeaderTableColumn extends TableColumn {
protected TableCellEditor headerEditor;
protected boolean isHeaderEditable;
public EditableHeaderTableColumn() {
setHeaderEditor(createDefaultHeaderEditor());
isHeaderEditable = true;
}
public void setHeaderEditor(TableCellEditor headerEditor) {
this.headerEditor = headerEditor;
}
public TableCellEditor getHeaderEditor() {
return headerEditor;
}
public void setHeaderEditable(boolean isEditable) {
isHeaderEditable = isEditable;
}
public boolean isHeaderEditable() {
return isHeaderEditable;
}
public void copyValues(TableColumn base) {
modelIndex = base.getModelIndex();
identifier = base.getIdentifier();
width = base.getWidth();
minWidth = base.getMinWidth();
setPreferredWidth(base.getPreferredWidth());
maxWidth = base.getMaxWidth();
headerRenderer = base.getHeaderRenderer();
headerValue = base.getHeaderValue();
cellRenderer = base.getCellRenderer();
cellEditor = base.getCellEditor();
isResizable = base.getResizable();
}
protected TableCellEditor createDefaultHeaderEditor() {
return new DefaultCellEditor(new JTextField());
}
}