Search This Blog

Friday, June 6, 2008

SortableJTableModel

Here is a code example for a sortable JTableModel. In the future I intend to build upon it and design a simple framework.
This was re-factored from a work implementation because the code was coupled with a certain object that seems to be pervasive. Anyway's here is the result.

import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Vector;

import javax.swing.JTable;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

public class SortableJTableModel extends DefaultTableModel implements SortableTableModel {
private static class Compare implements Comparator {
int sortKey;
int sortOrder;

Compare(int sortKey, int sortOrder) {
this.sortKey = sortKey;
this.sortOrder = sortOrder;
}

public int compare(Object o1, Object o2) {
Vector v1 = (Vector) o1;
Vector v2 = (Vector) o2;
Comparable s1 = (Comparable) v1.get(sortKey);
Comparable s2 = (Comparable) v2.get(sortKey);
int ans = s1.compareTo(s2);
if (sortOrder==DESCENDING) {
ans *= -1;
}
return (ans);
}

public boolean equals(Object obj) {
return (false);
}
}
// private class HeaderMouseAdapter extends MouseAdapter {
// public void mousePressed(MouseEvent e) {
// Point mousePoint = new Point(e.getX(), e.getY());
// selectedHeaderColumn = header.columnAtPoint(mousePoint);
// DefaultTableColumnModel cmodel = (DefaultTableColumnModel) table.getColumnModel();
// backupTableColumnAttr(cmodel);
//
// clickCount++;
// boolean reverseOrder = false;
// if(clickCount>0 && (clickCount % 2) == 0) {
// sort(new int[] {selectedHeaderColumn}, DESCENDING);
// }
// else {
// sort(new int[] {selectedHeaderColumn}, ASCENDING);
// }
// restoreTableColumnAttr(cmodel);
// }
//
// void backupTableColumnAttr(DefaultTableColumnModel cmodel) {
// for (int i = 0; i < cmodel.getColumnCount(); i++) {
// TableColumn column = cmodel.getColumn(i);
// minWidth[i] = column.getWidth();
// cellRenderer[i] = column.getCellRenderer();
// headerRenderer[i] = column.getHeaderRenderer();
// }
// }
//
// void restoreTableColumnAttr(DefaultTableColumnModel cmodel) {
// for (int i = 0; i < cmodel.getColumnCount(); i++) {
// TableColumn column = cmodel.getColumn(i);
// column.setMinWidth(minWidth[i]);
// column.setCellRenderer(cellRenderer[i]);
// column.setHeaderRenderer(headerRenderer[i]);
// }
// }
// }
private int currentSortColumn = -1;
private int currentSortDirection = NOT_SORTED;
private JTable table;
private JTableHeader header;
private Vector columnNames;
private int selectedHeaderColumn;
private int[] minWidth;
private TableCellRenderer[] cellRenderer;
private TableCellRenderer[] headerRenderer;
private int clickCount = 0;

public SortableJTableModel(JTable table, String[] columnNames, int rowCount) {
this(table, DefaultTableModel.convertToVector(columnNames), rowCount);
}
public SortableJTableModel(JTable table, Vector columnNames, int rowCount) {
super(columnNames, rowCount);
this.table = table;
this.columnNames = columnNames;
dataVector = ((DefaultTableModel) table.getModel()).getDataVector();
header = table.getTableHeader();
header.setReorderingAllowed(false);
//header.addMouseListener(new HeaderMouseAdapter());
minWidth = new int[columnNames.size()];
cellRenderer = new TableCellRenderer[columnNames.size()];
headerRenderer = new TableCellRenderer[columnNames.size()];
}



public void setCurrentSortColumn(int column, int direction) {
if (column < 0 || column >= getColumnCount()) {
throw new IllegalArgumentException("column " + column + " is outside column numbers");
}
if (direction != ASCENDING && direction != DESCENDING) {
throw new IllegalArgumentException("direction " + direction + " is not a valid sort direction");
}
currentSortColumn = column;
currentSortDirection = direction;
}

public int getCurrentSortDirection(int column) {
return (currentSortColumn != column) ? NOT_SORTED : currentSortDirection;
}

public int getCurrentSortColumn() {
return currentSortColumn;
}

public int getRowCount() {
return dataVector.size();
}

public String getColumnNameNoNewLine(int column) {
String hvalue = (String) columnNames.get(column);
return hvalue.replace('\n', ' ');
}
public void sort(int sortColumns[], int direction) {
DefaultTableColumnModel cmodel = (DefaultTableColumnModel) table.getColumnModel();
backupTableColumnAttr(cmodel);
Object[] array = dataVector.toArray();
Arrays.sort(array, new Compare(sortColumns[0], direction));
dataVector = DefaultTableModel.convertToVector(array);
setDataVector(dataVector, columnNames);
restoreTableColumnAttr(cmodel);
}
void backupTableColumnAttr(DefaultTableColumnModel cmodel) {
for (int i = 0; i < cmodel.getColumnCount(); i++) {
TableColumn column = cmodel.getColumn(i);
minWidth[i] = column.getWidth();
cellRenderer[i] = column.getCellRenderer();
headerRenderer[i] = column.getHeaderRenderer();
}
}

void restoreTableColumnAttr(DefaultTableColumnModel cmodel) {
for (int i = 0; i < cmodel.getColumnCount(); i++) {
TableColumn column = cmodel.getColumn(i);
column.setMinWidth(minWidth[i]);
column.setCellRenderer(cellRenderer[i]);
column.setHeaderRenderer(headerRenderer[i]);
}
}
// void sort(boolean reverseOrder) {
// Object[] array = dataVector.toArray();
// Arrays.sort(array, new Compare(selectedHeaderColumn, reverseOrder));
// dataVector = DefaultTableModel.convertToVector(array);
// setDataVector(dataVector, columnNames);
// }
}

No comments: