package com.onaro.util.jfc;
import com.onaro.util.jfc.tables.SortingHeaderRenderer;
import javax.swing.*;
import javax.swing.table.TableModel;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* A sorted JTable
letting the user choose the sorting column and
* order by clicking the table header.
*/
public class SortedTable extends JTable implements EncapsulatingTable {
private static final long serialVersionUID = 1L;
/**
* The sorted table model that does the actual sorting.
*/
private SortedTableModel sortedModel;
private SortingHeaderRenderer headerRenderer;
/**
* Constructs a sorted table for the given model.
*
* @param sourceModel the data model that is sorted and than is displayed
* in the table
*/
public SortedTable(TableModel sourceModel) {
super(sourceModel);
getTableHeader().addMouseListener(new SortAndWidthMouseListener());
headerRenderer = new SortingHeaderRenderer(sortedModel); // sourted model is initilized bu the super constructor
getTableHeader().setDefaultRenderer(headerRenderer);
}
/**
* Constructs a table with the defualt model.
*/
public SortedTable() {
this(null);
}
/**
* Sets the new model as the source model of the sorted table model.
*
* @param newModel the new table model
*/
public void setModel(TableModel newModel) {
assert newModel != null : "The data model cannot be null"; //$NON-NLS-1$
sortedModel = new SortedTableModel(newModel);
if (headerRenderer != null) headerRenderer.setSortingInfo(sortedModel);
super.setModel(sortedModel);
}
/**
* Returns the TableModel
that provides the data displayed by this
* JTable
which is the sorted model.
*
* @return the TableModel
that provides the data displayed by this JTable
*/
public TableModel getModel() {
return sortedModel;
}
/**
* Gets the encapsulated table-model.
*
* @return the encapsulated table-model
*/
public TableModel getEncapsulatedTableModel() {
return sortedModel.getSourceModel();
}
/**
* Sets the encapsulated table-model.
*
* @param tableModel the encapsulated table-model
*/
public void setEncapsulatedTableModel(TableModel tableModel) {
setModel(tableModel);
}
/**
* Get the row number in the encapsulated model of a row in the sorting
* model.
*
* @param row row number in the sorting model
* @return row number in the encapsulated model or -1 the row cannot be
* mapped into a row in the encapsulated model
*/
public int getRowInEncapsulatedModel(int row) {
return sortedModel.translateSortedToSource(row);
}
/**
* Sets the sorting column and order.
*
* @param sortingColumn the new sorting column
* @param ascending true id the sorting order is ascending
*/
public void setSortingColumn(int sortingColumn, boolean ascending) {
sortedModel.setSortingColumn(sortingColumn, ascending);
}
/**
* Returns the index of the sorting column, or NO_SORTING_COLUMN
* if the DATA is not sorted on any column.
*
* @return the column used for sorting
*/
public int getSortingColumn() {
return sortedModel.getSortingColumn();
}
/**
* Returns true if the DATA is sorted in ascending order, and false otherwise.
*
* @return true if the DATA is sorted in ascending order, and false otherwise
*/
public boolean getAscending() {
return sortedModel.getAscending();
}
/**
* Adds a listener to the model that is notified each the sorting has changed.
*
* @param l the listener
*/
public void addSortingListener(SortedTableModel.SortingListener l) {
sortedModel.addSortingListener(l);
}
/**
* Removes a listener from the list that is notified each the sorting had changed.
*
* @param l the listener
*/
public void removeSortingListener(SortedTableModel.SortingListener l) {
sortedModel.removeSortingListener(l);
}
/**
* A mouse click listener with the table header which changes the
* sorting according to the user clicks on the column headers.
*/
private class SortAndWidthMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1 ) {
Point point = e.getPoint();
int edge = 4;
Point leftPoint = new Point(point.x-edge, point.y);
Point rightPoint = new Point(point.x+edge, point.y);
int col = tableHeader.columnAtPoint(point);
int colLeft = tableHeader.columnAtPoint(leftPoint);
int colRight = tableHeader.columnAtPoint(rightPoint);
boolean isEdge = col != colLeft || col != colRight;
if( e.getClickCount() == 1 && !isEdge) {
int colInModel = convertColumnIndexToModel(col);
if (sortedModel.getSortingColumn() != colInModel) {
sortedModel.setSortingColumn(colInModel, true);
} else {
sortedModel.setAscending(!sortedModel.getAscending());
}
tableHeader.repaint();
} else if( e.getClickCount() == 2 && isEdge && colLeft != -1 ) {
TableUtils.setColumnPreferredWidth(colLeft, SortedTable.this);
}
}
}
}
}