Implementing a Column Model

Here’s a custom column model that keeps all of its columns in alphabetical order as they are added:

import javax.swing.table.*;

public class SortingColumnModel extends DefaultTableColumnModel {

  public void addColumn(TableColumn tc) {
    super.addColumn(tc);
    int newIndex = sortedIndexOf(tc);
    if (newIndex != tc.getModelIndex( )) {
      moveColumn(tc.getModelIndex( ), newIndex);
    }
  }

  protected int sortedIndexOf(TableColumn tc) {
    // Just do a linear search for now.
    int stop = getColumnCount( );
    String name = tc.getHeaderValue( ).toString( );

    for (int i = 0; i < stop; i++) {
      if (name.compareTo(getColumn(i).getHeaderValue( ).toString( )) <= 0) {
        return i;
      }
    }
    return stop;
  }
}

Implementing the model is simple. We override addColumn( ) to add the column to the superclass and then move it into the appropriate position. You can use this column model with any data model. The next section goes into much more detail on the table model used to store the real data, so for this simple example, we’ll use the DefaultTableModel class to hold the data. Once we have our table model and our column model, we can build a JTable with them. Then, any columns we add are listed in alphabetical order (by the header), regardless of the order in which they were added.

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

class SortingColumnModel extends DefaultTableColumnModel {

	public void addColumn(TableColumn tc) {
		super.addColumn(tc);
		int newIndex = sortedIndexOf(tc);
		if (newIndex != tc.getModelIndex()) {
			moveColumn(tc.getModelIndex(), newIndex);
		}
	}

	protected int sortedIndexOf(TableColumn tc) {
		// Just do a linear search for now.
		int stop = getColumnCount();
		String name = tc.getHeaderValue().toString();

		for (int i = 0; i < stop; i++) {
			if (name.compareTo(getColumn(i).getHeaderValue().toString()) <= 0) {
				return i;
			}
		}
		return stop;
	}
}

public class ColumnExample extends JFrame {

	public ColumnExample() {
		super("Abstract Model JTable Test");
		setSize(300, 200);
		setDefaultCloseOperation(EXIT_ON_CLOSE);

		DefaultTableModel dtm = new DefaultTableModel(new String[][] { 
				{ "1", "2", "3" }, { "4", "5", "6" } },
				new String[] { "Names", "In", "Order" });
		SortingColumnModel scm = new SortingColumnModel();
		JTable jt = new JTable(dtm, scm);
		jt.createDefaultColumnsFromModel();

		JScrollPane jsp = new JScrollPane(jt);
		getContentPane().add(jsp, BorderLayout.CENTER);
	}

	public static void main(String args[]) {
		ColumnExample ce = new ColumnExample();
		ce.setVisible(true);
	}
}