Все ответы терпят неудачу в одном случае использования: если таблица находится в макете, заполняющем все окно, то изменение размера окна приведет к изменению размера таблицы и, следовательно, ее столбцов. Наблюдая за событиями мыши в заголовках столбцов, мы не получаем событие, когда пользователь изменяет размер окна.
Я посмотрел на исходный код JTable & friends, и метод columnMarginChanged () всегда вызывается в функции sub-sub-sub ...-, вызываемой JTable.doLayout ().
Тогда мое решение состоит в том, чтобы отслеживать вызовы doLayout (), которые инициируют хотя бы один columnMarginChanged ().
Фактически, columnMarginChanged () вызывается для каждого столбца.
Вот мое решение:
private class ResizableJTable extends JTable {
private TableColumnModelListener columnModelListener;
private boolean columnsWereResized;
@Override
public void setColumnModel(TableColumnModel columnModel) {
if (getColumnModel() != null) {
getColumnModel().removeColumnModelListener(columnModelListener);
columnModelListener = null;
}
if (columnModel != null) {
columnModelListener = new TableColumnModelListener() {
public void columnSelectionChanged(ListSelectionEvent e) {
// Nothing to do
}
public void columnRemoved(TableColumnModelEvent e) {
// Nothing to do
}
public void columnMoved(TableColumnModelEvent e) {
// Nothing to do
}
public void columnMarginChanged(ChangeEvent e) {
columnsWereResized = true;
}
public void columnAdded(TableColumnModelEvent e) {
// Nothing to do
}
};
columnModel.addColumnModelListener(columnModelListener);
}
super.setColumnModel(columnModel);
}
@Override
public void doLayout() {
columnsWereResized = false;
super.doLayout();
if (columnsWereResized) {
onColumnsResized();
}
}
/**
* Sub-classes can override this method to
* get the columns-were-resized event.
* By default this method must be empty,
* but here we added debug code.
*/
protected void onColumnsResized() {
int[] columnSizes = getColumnSizes();
String sizes = "";
for (int i : columnSizes) {
sizes += i + " ";
}
System.out.println("COLUMNS RESIZED: [ " + sizes + "]");
}
protected int[] getColumnSizes() {
TableColumnModel columnModel = getTableHeader().getColumnModel();
int columnCount = columnModel.getColumnCount();
int[] columnSizes = new int[columnCount];
for(int i = 0; i < columnCount; i++) {
TableColumn column = columnModel.getColumn(i);
columnSizes[i] = column.getWidth();
}
return columnSizes;
}
}