Thread: [Ejtools-cvs] libraries/common/src/main/org/ejtools/swing/table package.html,NONE,1.1 TableModelDeco
Brought to you by:
letiemble
Update of /cvsroot/ejtools/libraries/common/src/main/org/ejtools/swing/table In directory sc8-pr-cvs1:/tmp/cvs-serv18971/common/src/main/org/ejtools/swing/table Modified Files: TableModelDecorator.java TableModelFilter.java TableModelIndexed.java TableModelMatchFilter.java TableModelSorter.java Added Files: package.html Log Message: Add more javadocs. Add package.html files. --- NEW FILE: package.html --- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <!-- EJTools, the Enterprise Java Tools Distributable under LGPL license. See terms of license at www.gnu.org. $Revision: 1.1 $ --> <html> <head/> <body> Provides decorators for javax.swing.TableModel. Allows filtering, indexing and sorting. </body> </html> Index: TableModelDecorator.java =================================================================== RCS file: /cvsroot/ejtools/libraries/common/src/main/org/ejtools/swing/table/TableModelDecorator.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** TableModelDecorator.java 15 Sep 2003 22:23:45 -0000 1.8 --- TableModelDecorator.java 13 Dec 2003 21:27:49 -0000 1.9 *************** *** 1,143 **** ! /* ! * EJTools, the Enterprise Java Tools ! * ! * Distributable under LGPL license. ! * See terms of license at www.gnu.org. ! */ ! package org.ejtools.swing.table; ! ! import javax.swing.event.TableModelEvent; ! import javax.swing.event.TableModelListener; ! import javax.swing.table.AbstractTableModel; ! import javax.swing.table.TableModel; ! ! /** ! * @author Laurent Etiemble ! * @version $Revision$ ! */ ! public abstract class TableModelDecorator extends AbstractTableModel implements TableModelListener ! { ! /** Description of the Field */ ! protected TableModel model = null; ! ! ! /** ! * Constructor for TableFilter. ! * ! * @param model Description of the Parameter ! */ ! public TableModelDecorator(TableModel model) ! { ! this.model = model; ! this.model.addTableModelListener(this); ! } ! ! ! /** Constructor for TableModelDecorator. */ ! protected TableModelDecorator() ! { ! super(); ! } ! ! ! /** ! * @param column Description of the Parameter ! * @return The columnClass value ! */ ! public Class getColumnClass(int column) ! { ! return this.model.getColumnClass(column); ! } ! ! ! /** ! * @return The columnCount value ! */ ! public int getColumnCount() ! { ! return this.model.getColumnCount(); ! } ! ! ! /** ! * @param column Description of the Parameter ! * @return The columnName value ! */ ! public String getColumnName(int column) ! { ! return this.model.getColumnName(column); ! } ! ! ! /** ! * Returns the model. ! * ! * @return TableModel ! */ ! public TableModel getModel() ! { ! return this.model; ! } ! ! ! /** ! * @return The rowCount value ! */ ! public int getRowCount() ! { ! return this.model.getRowCount(); ! } ! ! ! /** ! * @param row Description of the Parameter ! * @param column Description of the Parameter ! * @return The valueAt value ! */ ! public Object getValueAt(int row, int column) ! { ! return this.model.getValueAt(row, column); ! } ! ! ! /** ! * @param row Description of the Parameter ! * @param column Description of the Parameter ! * @return The cellEditable value ! */ ! public boolean isCellEditable(int row, int column) ! { ! return this.model.isCellEditable(row, column); ! } ! ! ! /** ! * Sets the model. ! * ! * @param model The model to set ! */ ! public void setModel(TableModel model) ! { ! this.model = model; ! } ! ! ! /** ! * @param o The new valueAt value ! * @param row The new valueAt value ! * @param column The new valueAt value ! */ ! public void setValueAt(Object o, int row, int column) ! { ! this.model.setValueAt(o, row, column); ! } ! ! ! /** ! * @param event Description of the Parameter ! */ ! public void tableChanged(TableModelEvent event) ! { ! this.fireTableChanged(event); ! } ! } --- 1,143 ---- ! /* ! * EJTools, the Enterprise Java Tools ! * ! * Distributable under LGPL license. ! * See terms of license at www.gnu.org. ! */ ! package org.ejtools.swing.table; ! ! import javax.swing.event.TableModelEvent; ! import javax.swing.event.TableModelListener; ! import javax.swing.table.AbstractTableModel; ! import javax.swing.table.TableModel; ! ! /** ! * @author Laurent Etiemble ! * @version $Revision$ ! */ ! public abstract class TableModelDecorator extends AbstractTableModel implements TableModelListener ! { ! /** Description of the Field */ ! protected TableModel model = null; ! ! ! /** ! * Constructor for TableFilter. ! * ! * @param model Description of the Parameter ! */ ! public TableModelDecorator(TableModel model) ! { ! this.model = model; ! this.model.addTableModelListener(this); ! } ! ! ! /** Constructor for TableModelDecorator. */ ! protected TableModelDecorator() ! { ! super(); ! } ! ! ! /** ! * @param column Description of the Parameter ! * @return The columnClass value ! */ ! public Class getColumnClass(int column) ! { ! return this.model.getColumnClass(column); ! } ! ! ! /** ! * @return The columnCount value ! */ ! public int getColumnCount() ! { ! return this.model.getColumnCount(); ! } ! ! ! /** ! * @param column Description of the Parameter ! * @return The columnName value ! */ ! public String getColumnName(int column) ! { ! return this.model.getColumnName(column); ! } ! ! ! /** ! * Returns the model. ! * ! * @return TableModel ! */ ! public TableModel getModel() ! { ! return this.model; ! } ! ! ! /** ! * @return The rowCount value ! */ ! public int getRowCount() ! { ! return this.model.getRowCount(); ! } ! ! ! /** ! * @param row Description of the Parameter ! * @param column Description of the Parameter ! * @return The valueAt value ! */ ! public Object getValueAt(int row, int column) ! { ! return this.model.getValueAt(row, column); ! } ! ! ! /** ! * @param row Description of the Parameter ! * @param column Description of the Parameter ! * @return The cellEditable value ! */ ! public boolean isCellEditable(int row, int column) ! { ! return this.model.isCellEditable(row, column); ! } ! ! ! /** ! * Sets the model. ! * ! * @param model The model to set ! */ ! public void setModel(TableModel model) ! { ! this.model = model; ! } ! ! ! /** ! * @param o The new valueAt value ! * @param row The new valueAt value ! * @param column The new valueAt value ! */ ! public void setValueAt(Object o, int row, int column) ! { ! this.model.setValueAt(o, row, column); ! } ! ! ! /** ! * @param event Description of the Parameter ! */ ! public void tableChanged(TableModelEvent event) ! { ! this.fireTableChanged(event); ! } ! } Index: TableModelFilter.java =================================================================== RCS file: /cvsroot/ejtools/libraries/common/src/main/org/ejtools/swing/table/TableModelFilter.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** TableModelFilter.java 15 Sep 2003 22:23:45 -0000 1.6 --- TableModelFilter.java 13 Dec 2003 21:27:49 -0000 1.7 *************** *** 1,86 **** ! /* ! * EJTools, the Enterprise Java Tools ! * ! * Distributable under LGPL license. ! * See terms of license at www.gnu.org. ! */ ! package org.ejtools.swing.table; ! ! import javax.swing.event.TableModelEvent; ! import javax.swing.table.TableModel; ! ! /** ! * @author Laurent Etiemble ! * @version $Revision$ ! */ ! public abstract class TableModelFilter extends TableModelIndexed ! { ! /** Description of the Field */ ! protected int column = -1; ! /** Description of the Field */ ! protected Object[] values; ! ! ! /** ! * Constructor for TableModelFilter. ! * ! * @param model ! */ ! public TableModelFilter(TableModel model) ! { ! super(model); ! } ! ! ! /** ! * Description of the Method ! * ! * @param column Description of the Parameter ! * @param value Description of the Parameter ! */ ! public void filter(int column, Object value) ! { ! this.filter(column, new Object[]{value}); ! } ! ! ! /** Description of the Method */ ! public abstract void filter(); ! ! ! /** ! * Description of the Method ! * ! * @param column Description of the Parameter ! * @param values Description of the Parameter ! */ ! public void filter(int column, Object[] values) ! { ! this.column = column; ! this.values = values; ! this.filter(); ! super.tableChanged(new TableModelEvent(this)); ! } ! ! ! /** ! * Gets the column attribute of the TableModelFilter object ! * ! * @return The column value ! */ ! public int getColumn() ! { ! return column; ! } ! ! ! /** ! * Gets the values attribute of the TableModelFilter object ! * ! * @return The values value ! */ ! public Object[] getValues() ! { ! return values; ! } ! } --- 1,86 ---- ! /* ! * EJTools, the Enterprise Java Tools ! * ! * Distributable under LGPL license. ! * See terms of license at www.gnu.org. ! */ ! package org.ejtools.swing.table; ! ! import javax.swing.event.TableModelEvent; ! import javax.swing.table.TableModel; ! ! /** ! * @author Laurent Etiemble ! * @version $Revision$ ! */ ! public abstract class TableModelFilter extends TableModelIndexed ! { ! /** Description of the Field */ ! protected int column = -1; ! /** Description of the Field */ ! protected Object[] values; ! ! ! /** ! * Constructor for TableModelFilter. ! * ! * @param model ! */ ! public TableModelFilter(TableModel model) ! { ! super(model); ! } ! ! ! /** ! * Description of the Method ! * ! * @param column Description of the Parameter ! * @param value Description of the Parameter ! */ ! public void filter(int column, Object value) ! { ! this.filter(column, new Object[]{value}); ! } ! ! ! /** Description of the Method */ ! public abstract void filter(); ! ! ! /** ! * Description of the Method ! * ! * @param column Description of the Parameter ! * @param values Description of the Parameter ! */ ! public void filter(int column, Object[] values) ! { ! this.column = column; ! this.values = values; ! this.filter(); ! super.tableChanged(new TableModelEvent(this)); ! } ! ! ! /** ! * Gets the column attribute of the TableModelFilter object ! * ! * @return The column value ! */ ! public int getColumn() ! { ! return column; ! } ! ! ! /** ! * Gets the values attribute of the TableModelFilter object ! * ! * @return The values value ! */ ! public Object[] getValues() ! { ! return values; ! } ! } Index: TableModelIndexed.java =================================================================== RCS file: /cvsroot/ejtools/libraries/common/src/main/org/ejtools/swing/table/TableModelIndexed.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** TableModelIndexed.java 15 Sep 2003 22:23:45 -0000 1.7 --- TableModelIndexed.java 13 Dec 2003 21:27:49 -0000 1.8 *************** *** 1,90 **** ! /* ! * EJTools, the Enterprise Java Tools ! * ! * Distributable under LGPL license. ! * See terms of license at www.gnu.org. ! */ ! package org.ejtools.swing.table; ! ! import javax.swing.table.TableModel; ! ! /** ! * @author Laurent Etiemble ! * @version $Revision$ ! */ ! public abstract class TableModelIndexed extends TableModelDecorator ! { ! /** Description of the Field */ ! protected int[] indexes = new int[0]; ! ! ! /** ! * Constructor for TableFilter. ! * ! * @param model ! */ ! public TableModelIndexed(TableModel model) ! { ! super(model); ! } ! ! ! /** ! * Gets the rowCount attribute of the TableFilter object ! * ! * @return The rowCount value ! */ ! public int getRowCount() ! { ! return this.indexes.length; ! } ! ! ! /** ! * Gets the valueAt attribute of the TableFilter object ! * ! * @param row Description of the Parameter ! * @param column Description of the Parameter ! * @return The valueAt value ! */ ! public Object getValueAt(int row, int column) ! { ! return this.model.getValueAt(this.indexes[row], column); ! } ! ! ! /** ! * @param model The new model value ! */ ! public void setModel(TableModel model) ! { ! super.setModel(model); ! } ! ! ! /** ! * Sets the valueAt attribute of the TableFilter object ! * ! * @param newValue The new valueAt value ! * @param row The new valueAt value ! * @param column The new valueAt value ! */ ! public void setValueAt(Object newValue, int row, int column) ! { ! this.model.setValueAt(newValue, this.indexes[row], column); ! } ! ! ! /** ! * Description of the Method ! * ! * @param i Description of the Parameter ! * @param j Description of the Parameter ! */ ! protected void swap(int i, int j) ! { ! int tmp = indexes[i]; ! indexes[i] = indexes[j]; ! indexes[j] = tmp; ! } ! } --- 1,90 ---- ! /* ! * EJTools, the Enterprise Java Tools ! * ! * Distributable under LGPL license. ! * See terms of license at www.gnu.org. ! */ ! package org.ejtools.swing.table; ! ! import javax.swing.table.TableModel; ! ! /** ! * @author Laurent Etiemble ! * @version $Revision$ ! */ ! public abstract class TableModelIndexed extends TableModelDecorator ! { ! /** Description of the Field */ ! protected int[] indexes = new int[0]; ! ! ! /** ! * Constructor for TableFilter. ! * ! * @param model ! */ ! public TableModelIndexed(TableModel model) ! { ! super(model); ! } ! ! ! /** ! * Gets the rowCount attribute of the TableFilter object ! * ! * @return The rowCount value ! */ ! public int getRowCount() ! { ! return this.indexes.length; ! } ! ! ! /** ! * Gets the valueAt attribute of the TableFilter object ! * ! * @param row Description of the Parameter ! * @param column Description of the Parameter ! * @return The valueAt value ! */ ! public Object getValueAt(int row, int column) ! { ! return this.model.getValueAt(this.indexes[row], column); ! } ! ! ! /** ! * @param model The new model value ! */ ! public void setModel(TableModel model) ! { ! super.setModel(model); ! } ! ! ! /** ! * Sets the valueAt attribute of the TableFilter object ! * ! * @param newValue The new valueAt value ! * @param row The new valueAt value ! * @param column The new valueAt value ! */ ! public void setValueAt(Object newValue, int row, int column) ! { ! this.model.setValueAt(newValue, this.indexes[row], column); ! } ! ! ! /** ! * Description of the Method ! * ! * @param i Description of the Parameter ! * @param j Description of the Parameter ! */ ! protected void swap(int i, int j) ! { ! int tmp = indexes[i]; ! indexes[i] = indexes[j]; ! indexes[j] = tmp; ! } ! } Index: TableModelMatchFilter.java =================================================================== RCS file: /cvsroot/ejtools/libraries/common/src/main/org/ejtools/swing/table/TableModelMatchFilter.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** TableModelMatchFilter.java 15 Sep 2003 22:23:45 -0000 1.7 --- TableModelMatchFilter.java 13 Dec 2003 21:27:49 -0000 1.8 *************** *** 1,68 **** ! /* ! * EJTools, the Enterprise Java Tools ! * ! * Distributable under LGPL license. ! * See terms of license at www.gnu.org. ! */ ! package org.ejtools.swing.table; ! ! import java.util.ArrayList; ! ! import javax.swing.table.TableModel; ! ! /** ! * @author Laurent Etiemble ! * @version $Revision$ ! */ ! public class TableModelMatchFilter extends TableModelFilter ! { ! /** Description of the Field */ ! protected ArrayList tempIndexes = new ArrayList(); ! ! ! /** ! * Constructor for TableModelMatchFilter. ! * ! * @param model ! */ ! public TableModelMatchFilter(TableModel model) ! { ! super(model); ! } ! ! ! /** */ ! public synchronized void filter() ! { ! this.tempIndexes.clear(); ! int rows = this.model.getRowCount(); ! ! if (this.column < 0) ! { ! for (int row = 0; row < rows; row++) ! { ! this.tempIndexes.add(new Integer(row)); ! } ! } ! else ! { ! for (int row = 0; row < rows; row++) ! { ! Object value = model.getValueAt(row, column); ! for (int i = 0; i < values.length; i++) ! { ! if (values[i].equals(value)) ! { ! tempIndexes.add(new Integer(row)); ! } ! } ! } ! } ! ! this.indexes = new int[this.tempIndexes.size()]; ! for (int i = 0; i < this.indexes.length; i++) ! { ! this.indexes[i] = ((Integer) this.tempIndexes.get(i)).intValue(); ! } ! } ! } --- 1,68 ---- ! /* ! * EJTools, the Enterprise Java Tools ! * ! * Distributable under LGPL license. ! * See terms of license at www.gnu.org. ! */ ! package org.ejtools.swing.table; ! ! import java.util.ArrayList; ! ! import javax.swing.table.TableModel; ! ! /** ! * @author Laurent Etiemble ! * @version $Revision$ ! */ ! public class TableModelMatchFilter extends TableModelFilter ! { ! /** Description of the Field */ ! protected ArrayList tempIndexes = new ArrayList(); ! ! ! /** ! * Constructor for TableModelMatchFilter. ! * ! * @param model ! */ ! public TableModelMatchFilter(TableModel model) ! { ! super(model); ! } ! ! ! /** */ ! public synchronized void filter() ! { ! this.tempIndexes.clear(); ! int rows = this.model.getRowCount(); ! ! if (this.column < 0) ! { ! for (int row = 0; row < rows; row++) ! { ! this.tempIndexes.add(new Integer(row)); ! } ! } ! else ! { ! for (int row = 0; row < rows; row++) ! { ! Object value = model.getValueAt(row, column); ! for (int i = 0; i < values.length; i++) ! { ! if (values[i].equals(value)) ! { ! tempIndexes.add(new Integer(row)); ! } ! } ! } ! } ! ! this.indexes = new int[this.tempIndexes.size()]; ! for (int i = 0; i < this.indexes.length; i++) ! { ! this.indexes[i] = ((Integer) this.tempIndexes.get(i)).intValue(); ! } ! } ! } Index: TableModelSorter.java =================================================================== RCS file: /cvsroot/ejtools/libraries/common/src/main/org/ejtools/swing/table/TableModelSorter.java,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** TableModelSorter.java 15 Sep 2003 22:23:45 -0000 1.7 --- TableModelSorter.java 13 Dec 2003 21:27:49 -0000 1.8 *************** *** 1,487 **** ! /* ! * EJTools, the Enterprise Java Tools ! * ! * Distributable under LGPL license. ! * See terms of license at www.gnu.org. ! */ ! package org.ejtools.swing.table; ! ! import java.awt.event.InputEvent; ! import java.awt.event.MouseAdapter; ! import java.awt.event.MouseEvent; ! import java.util.Date; ! import java.util.Vector; ! ! import javax.swing.JTable; ! import javax.swing.event.TableModelEvent; ! import javax.swing.table.JTableHeader; ! import javax.swing.table.TableColumnModel; ! import javax.swing.table.TableModel; ! ! /** ! * @author Laurent Etiemble ! * @version $Revision$ ! */ ! public class TableModelSorter extends TableModelIndexed ! { ! /** Description of the Field */ ! protected boolean ascending = true; ! /** Description of the Field */ ! protected int column = -1; ! /** Description of the Field */ ! protected int compares; ! /** Description of the Field */ ! protected Vector sortingColumns = new Vector(); ! ! ! /** ! * Constructor for TableModelSorter. ! * ! * @param model ! */ ! public TableModelSorter(TableModel model) ! { ! super(model); ! this.reallocateIndexes(); ! } ! ! ! /** ! * Add a mouse listener to the Table to trigger a table sort when a column ! * heading is clicked in the JTable. ! * ! * @param table The feature to be added to the MouseListenerToHeaderInTable ! * attribute ! */ ! public void addMouseListenerToHeaderInTable(JTable table) ! { ! final TableModelSorter tableSorter = this; ! final JTable tableView = table; ! tableView.setColumnSelectionAllowed(false); ! MouseAdapter listMouseListener = ! new MouseAdapter() ! { ! public void mouseClicked(MouseEvent e) ! { ! TableColumnModel columnModel = tableView.getColumnModel(); ! int viewColumn = columnModel.getColumnIndexAtX(e.getX()); ! int column = tableView.convertColumnIndexToModel(viewColumn); ! if (e.getClickCount() == 1 && column != -1) ! { ! int shiftPressed = e.getModifiers() & InputEvent.SHIFT_MASK; ! boolean ascending = (shiftPressed == 0); ! tableSorter.sortByColumn(column, ascending); ! } ! } ! }; ! JTableHeader th = tableView.getTableHeader(); ! th.addMouseListener(listMouseListener); ! } ! ! ! /** Description of the Method */ ! public void checkModel() ! { ! if (indexes.length != model.getRowCount()) ! { ! System.err.println("Sorter not informed of a change in model."); ! } ! } ! ! ! /** ! * Description of the Method ! * ! * @param row1 Description of the Parameter ! * @param row2 Description of the Parameter ! * @return Description of the Return Value ! */ ! public int compare(int row1, int row2) ! { ! this.compares++; ! for (int level = 0; level < this.sortingColumns.size(); level++) ! { ! Integer column = (Integer) this.sortingColumns.elementAt(level); ! int result = this.compareRowsByColumn(row1, row2, column.intValue()); ! if (result != 0) ! { ! return this.ascending ? result : -result; ! } ! } ! return 0; ! } ! ! ! ! /** ! * Description of the Method ! * ! * @param row1 Description of the Parameter ! * @param row2 Description of the Parameter ! * @param column Description of the Parameter ! * @return Description of the Return Value ! */ ! public int compareRowsByColumn(int row1, int row2, int column) ! { ! Class type = this.model.getColumnClass(column); ! TableModel data = this.model; ! ! // Check for nulls. ! Object o1 = data.getValueAt(row1, column); ! Object o2 = data.getValueAt(row2, column); ! ! // If both values are null, return 0. ! if (o1 == null && o2 == null) ! { ! return 0; ! } ! else if (o1 == null) ! { ! // Define null less than everything. ! return -1; ! } ! else if (o2 == null) ! { ! return 1; ! } ! ! /* ! * We copy all returned values from the getValue call in case ! * an optimised model is reusing one object to return many ! * values. The Number subclasses in the JDK are immutable and ! * so will not be used in this way but other subclasses of ! * Number might want to do this to save space and avoid ! * unnecessary heap allocation. ! */ ! if (Comparable.class.isAssignableFrom(type)) ! { ! Comparable n1 = (Comparable) data.getValueAt(row1, column); ! Comparable n2 = (Comparable) data.getValueAt(row2, column); ! ! int result = n1.compareTo(n2); ! ! if (result < 0) ! { ! return -1; ! } ! else if (result > 0) ! { ! return 1; ! } ! else ! { ! return 0; ! } ! } ! else if (Number.class.isAssignableFrom(type)) ! { ! Number n1 = (Number) data.getValueAt(row1, column); ! double d1 = n1.doubleValue(); ! Number n2 = (Number) data.getValueAt(row2, column); ! double d2 = n2.doubleValue(); ! ! if (d1 < d2) ! { ! return -1; ! } ! else if (d1 > d2) ! { ! return 1; ! } ! else ! { ! return 0; ! } ! } ! else if (type == Date.class) ! { ! Date d1 = (Date) data.getValueAt(row1, column); ! long n1 = d1.getTime(); ! Date d2 = (Date) data.getValueAt(row2, column); ! long n2 = d2.getTime(); ! ! if (n1 < n2) ! { ! return -1; ! } ! else if (n1 > n2) ! { ! return 1; ! } ! else ! { ! return 0; ! } ! } ! else if (type == String.class) ! { ! String s1 = (String) data.getValueAt(row1, column); ! String s2 = (String) data.getValueAt(row2, column); ! int result = s1.compareTo(s2); ! ! if (result < 0) ! { ! return -1; ! } ! else if (result > 0) ! { ! return 1; ! } ! else ! { ! return 0; ! } ! } ! else if (type == Boolean.class) ! { ! Boolean bool1 = (Boolean) data.getValueAt(row1, column); ! boolean b1 = bool1.booleanValue(); ! Boolean bool2 = (Boolean) data.getValueAt(row2, column); ! boolean b2 = bool2.booleanValue(); ! ! if (b1 == b2) ! { ! return 0; ! } ! else if (b1) ! { ! // Define false < true ! return 1; ! } ! else ! { ! return -1; ! } ! } ! else ! { ! String comp1 = o1.toString(); ! String comp2 = o2.toString(); ! ! int result = comp1.compareTo(comp2); ! ! if (result < 0) ! { ! return -1; ! } ! else if (result > 0) ! { ! return 1; ! } ! else ! { ! return 0; ! } ! } ! } ! ! ! /** ! * Gets the column attribute of the TableModelSorter object ! * ! * @return The column value ! */ ! public int getColumn() ! { ! return this.column; ! } ! ! ! /** ! * Gets the valueAt attribute of the TableModelSorter object ! * ! * @param aRow Description of the Parameter ! * @param aColumn Description of the Parameter ! * @return The valueAt value ! */ ! public Object getValueAt(int aRow, int aColumn) ! { ! this.checkModel(); ! return super.getValueAt(aRow, aColumn); ! } ! ! ! /** ! * Gets the ascending attribute of the TableModelSorter object ! * ! * @return The ascending value ! */ ! public boolean isAscending() ! { ! return this.ascending; ! } ! ! ! /** Description of the Method */ ! public void n2sort() ! { ! for (int i = 0; i < getRowCount(); i++) ! { ! for (int j = i + 1; j < getRowCount(); j++) ! { ! if (compare(indexes[i], indexes[j]) == -1) ! { ! this.swap(i, j); ! } ! } ! } ! } ! ! ! ! /** Description of the Method */ ! public void reallocateIndexes() ! { ! int rowCount = model.getRowCount(); ! this.indexes = new int[rowCount]; ! ! // Initialise with the identity mapping. ! for (int row = 0; row < rowCount; row++) ! { ! indexes[row] = row; ! } ! } ! ! ! /** ! * Sets the valueAt attribute of the TableModelSorter object ! * ! * @param aValue The new valueAt value ! * @param aRow The new valueAt value ! * @param aColumn The new valueAt value ! */ ! public void setValueAt(Object aValue, int aRow, int aColumn) ! { ! this.checkModel(); ! super.setValueAt(aValue, aRow, aColumn); ! } ! ! ! ! /** ! * This is a home-grown implementation which we have not had time to research ! * - it may perform poorly in some circumstances. It requires twice the space ! * of an in-place algorithm and makes NlogN assigments shuttling the values ! * between the two arrays. The number of compares appears to vary between N-1 ! * and NlogN depending on the initial order but the main reason for using it ! * here is that, unlike qsort, it is stable. ! * ! * @param from Description of the Parameter ! * @param to Description of the Parameter ! * @param low Description of the Parameter ! * @param high Description of the Parameter ! */ ! public void shuttlesort(int from[], int to[], int low, int high) ! { ! if (high - low < 2) ! { ! return; ! } ! int middle = (low + high) / 2; ! ! this.shuttlesort(to, from, low, middle); ! this.shuttlesort(to, from, middle, high); ! ! int p = low; ! int q = middle; ! ! /* ! * This is an optional short-cut; at each recursive call, ! * check to see if the elements in this subset are already ! * ordered. If so, no further comparisons are needed; the ! * sub-array can just be copied. The array must be copied rather ! * than assigned otherwise sister calls in the recursion might ! * get out of sinc. When the number of elements is three they ! * are partitioned so that the first set, [low, mid), has one ! * element and and the second, [mid, high), has two. We skip the ! * optimisation when the number of elements is three or less as ! * the first compare in the normal merge will produce the same ! * sequence of steps. This optimisation seems to be worthwhile ! * for partially ordered lists but some analysis is needed to ! * find out how the performance drops to Nlog(N) as the initial ! * order diminishes - it may drop very quickly. ! */ ! if (high - low >= 4 && this.compare(from[middle - 1], from[middle]) <= 0) ! { ! for (int i = low; i < high; i++) ! { ! to[i] = from[i]; ! } ! return; ! } ! ! // A normal merge. ! for (int i = low; i < high; i++) ! { ! if (q >= high || (p < middle && this.compare(from[p], from[q]) <= 0)) ! { ! to[i] = from[p++]; ! } ! else ! { ! to[i] = from[q++]; ! } ! } ! } ! ! ! /** ! * Description of the Method ! * ! * @param sender Description of the Parameter ! */ ! public void sort(Object sender) ! { ! this.checkModel(); ! ! this.compares = 0; ! // n2sort(); ! // qsort(0, indexes.length-1); ! this.shuttlesort((int[]) indexes.clone(), indexes, 0, indexes.length); ! //System.out.println("Compares: "+compares); ! } ! ! ! ! /** ! * Description of the Method ! * ! * @param column Description of the Parameter ! */ ! public void sortByColumn(int column) ! { ! this.sortByColumn(column, true); ! } ! ! ! /** ! * Description of the Method ! * ! * @param column Description of the Parameter ! * @param ascending Description of the Parameter ! */ ! public void sortByColumn(int column, boolean ascending) ! { ! this.ascending = ascending; ! this.sortingColumns.removeAllElements(); ! this.sortingColumns.addElement(new Integer(column)); ! this.sort(this); ! super.tableChanged(new TableModelEvent(this)); ! } ! ! ! /** ! * Description of the Method ! * ! * @param event Description of the Parameter ! */ ! public void tableChanged(TableModelEvent event) ! { ! this.reallocateIndexes(); ! // if (column >= 0) ! // { ! // this.sortByColumn(column, ascending); ! // } ! super.tableChanged(event); ! } ! } --- 1,487 ---- ! /* ! * EJTools, the Enterprise Java Tools ! * ! * Distributable under LGPL license. ! * See terms of license at www.gnu.org. ! */ ! package org.ejtools.swing.table; ! ! import java.awt.event.InputEvent; ! import java.awt.event.MouseAdapter; ! import java.awt.event.MouseEvent; ! import java.util.Date; ! import java.util.Vector; ! ! import javax.swing.JTable; ! import javax.swing.event.TableModelEvent; ! import javax.swing.table.JTableHeader; ! import javax.swing.table.TableColumnModel; ! import javax.swing.table.TableModel; ! ! /** ! * @author Laurent Etiemble ! * @version $Revision$ ! */ ! public class TableModelSorter extends TableModelIndexed ! { ! /** Description of the Field */ ! protected boolean ascending = true; ! /** Description of the Field */ ! protected int column = -1; ! /** Description of the Field */ ! protected int compares; ! /** Description of the Field */ ! protected Vector sortingColumns = new Vector(); ! ! ! /** ! * Constructor for TableModelSorter. ! * ! * @param model ! */ ! public TableModelSorter(TableModel model) ! { ! super(model); ! this.reallocateIndexes(); ! } ! ! ! /** ! * Add a mouse listener to the Table to trigger a table sort when a column ! * heading is clicked in the JTable. ! * ! * @param table The feature to be added to the MouseListenerToHeaderInTable ! * attribute ! */ ! public void addMouseListenerToHeaderInTable(JTable table) ! { ! final TableModelSorter tableSorter = this; ! final JTable tableView = table; ! tableView.setColumnSelectionAllowed(false); ! MouseAdapter listMouseListener = ! new MouseAdapter() ! { ! public void mouseClicked(MouseEvent e) ! { ! TableColumnModel columnModel = tableView.getColumnModel(); ! int viewColumn = columnModel.getColumnIndexAtX(e.getX()); ! int column = tableView.convertColumnIndexToModel(viewColumn); ! if (e.getClickCount() == 1 && column != -1) ! { ! int shiftPressed = e.getModifiers() & InputEvent.SHIFT_MASK; ! boolean ascending = (shiftPressed == 0); ! tableSorter.sortByColumn(column, ascending); ! } ! } ! }; ! JTableHeader th = tableView.getTableHeader(); ! th.addMouseListener(listMouseListener); ! } ! ! ! /** Description of the Method */ ! public void checkModel() ! { ! if (indexes.length != model.getRowCount()) ! { ! System.err.println("Sorter not informed of a change in model."); ! } ! } ! ! ! /** ! * Description of the Method ! * ! * @param row1 Description of the Parameter ! * @param row2 Description of the Parameter ! * @return Description of the Return Value ! */ ! public int compare(int row1, int row2) ! { ! this.compares++; ! for (int level = 0; level < this.sortingColumns.size(); level++) ! { ! Integer column = (Integer) this.sortingColumns.elementAt(level); ! int result = this.compareRowsByColumn(row1, row2, column.intValue()); ! if (result != 0) ! { ! return this.ascending ? result : -result; ! } ! } ! return 0; ! } ! ! ! ! /** ! * Description of the Method ! * ! * @param row1 Description of the Parameter ! * @param row2 Description of the Parameter ! * @param column Description of the Parameter ! * @return Description of the Return Value ! */ ! public int compareRowsByColumn(int row1, int row2, int column) ! { ! Class type = this.model.getColumnClass(column); ! TableModel data = this.model; ! ! // Check for nulls. ! Object o1 = data.getValueAt(row1, column); ! Object o2 = data.getValueAt(row2, column); ! ! // If both values are null, return 0. ! if (o1 == null && o2 == null) ! { ! return 0; ! } ! else if (o1 == null) ! { ! // Define null less than everything. ! return -1; ! } ! else if (o2 == null) ! { ! return 1; ! } ! ! /* ! * We copy all returned values from the getValue call in case ! * an optimised model is reusing one object to return many ! * values. The Number subclasses in the JDK are immutable and ! * so will not be used in this way but other subclasses of ! * Number might want to do this to save space and avoid ! * unnecessary heap allocation. ! */ ! if (Comparable.class.isAssignableFrom(type)) ! { ! Comparable n1 = (Comparable) data.getValueAt(row1, column); ! Comparable n2 = (Comparable) data.getValueAt(row2, column); ! ! int result = n1.compareTo(n2); ! ! if (result < 0) ! { ! return -1; ! } ! else if (result > 0) ! { ! return 1; ! } ! else ! { ! return 0; ! } ! } ! else if (Number.class.isAssignableFrom(type)) ! { ! Number n1 = (Number) data.getValueAt(row1, column); ! double d1 = n1.doubleValue(); ! Number n2 = (Number) data.getValueAt(row2, column); ! double d2 = n2.doubleValue(); ! ! if (d1 < d2) ! { ! return -1; ! } ! else if (d1 > d2) ! { ! return 1; ! } ! else ! { ! return 0; ! } ! } ! else if (type == Date.class) ! { ! Date d1 = (Date) data.getValueAt(row1, column); ! long n1 = d1.getTime(); ! Date d2 = (Date) data.getValueAt(row2, column); ! long n2 = d2.getTime(); ! ! if (n1 < n2) ! { ! return -1; ! } ! else if (n1 > n2) ! { ! return 1; ! } ! else ! { ! return 0; ! } ! } ! else if (type == String.class) ! { ! String s1 = (String) data.getValueAt(row1, column); ! String s2 = (String) data.getValueAt(row2, column); ! int result = s1.compareTo(s2); ! ! if (result < 0) ! { ! return -1; ! } ! else if (result > 0) ! { ! return 1; ! } ! else ! { ! return 0; ! } ! } ! else if (type == Boolean.class) ! { ! Boolean bool1 = (Boolean) data.getValueAt(row1, column); ! boolean b1 = bool1.booleanValue(); ! Boolean bool2 = (Boolean) data.getValueAt(row2, column); ! boolean b2 = bool2.booleanValue(); ! ! if (b1 == b2) ! { ! return 0; ! } ! else if (b1) ! { ! // Define false < true ! return 1; ! } ! else ! { ! return -1; ! } ! } ! else ! { ! String comp1 = o1.toString(); ! String comp2 = o2.toString(); ! ! int result = comp1.compareTo(comp2); ! ! if (result < 0) ! { ! return -1; ! } ! else if (result > 0) ! { ! return 1; ! } ! else ! { ! return 0; ! } ! } ! } ! ! ! /** ! * Gets the column attribute of the TableModelSorter object ! * ! * @return The column value ! */ ! public int getColumn() ! { ! return this.column; ! } ! ! ! /** ! * Gets the valueAt attribute of the TableModelSorter object ! * ! * @param aRow Description of the Parameter ! * @param aColumn Description of the Parameter ! * @return The valueAt value ! */ ! public Object getValueAt(int aRow, int aColumn) ! { ! this.checkModel(); ! return super.getValueAt(aRow, aColumn); ! } ! ! ! /** ! * Gets the ascending attribute of the TableModelSorter object ! * ! * @return The ascending value ! */ ! public boolean isAscending() ! { ! return this.ascending; ! } ! ! ! /** Description of the Method */ ! public void n2sort() ! { ! for (int i = 0; i < getRowCount(); i++) ! { ! for (int j = i + 1; j < getRowCount(); j++) ! { ! if (compare(indexes[i], indexes[j]) == -1) ! { ! this.swap(i, j); ! } ! } ! } ! } ! ! ! ! /** Description of the Method */ ! public void reallocateIndexes() ! { ! int rowCount = model.getRowCount(); ! this.indexes = new int[rowCount]; ! ! // Initialise with the identity mapping. ! for (int row = 0; row < rowCount; row++) ! { ! indexes[row] = row; ! } ! } ! ! ! /** ! * Sets the valueAt attribute of the TableModelSorter object ! * ! * @param aValue The new valueAt value ! * @param aRow The new valueAt value ! * @param aColumn The new valueAt value ! */ ! public void setValueAt(Object aValue, int aRow, int aColumn) ! { ! this.checkModel(); ! super.setValueAt(aValue, aRow, aColumn); ! } ! ! ! ! /** ! * This is a home-grown implementation which we have not had time to research ! * - it may perform poorly in some circumstances. It requires twice the space ! * of an in-place algorithm and makes NlogN assigments shuttling the values ! * between the two arrays. The number of compares appears to vary between N-1 ! * and NlogN depending on the initial order but the main reason for using it ! * here is that, unlike qsort, it is stable. ! * ! * @param from Description of the Parameter ! * @param to Description of the Parameter ! * @param low Description of the Parameter ! * @param high Description of the Parameter ! */ ! public void shuttlesort(int from[], int to[], int low, int high) ! { ! if (high - low < 2) ! { ! return; ! } ! int middle = (low + high) / 2; ! ! this.shuttlesort(to, from, low, middle); ! this.shuttlesort(to, from, middle, high); ! ! int p = low; ! int q = middle; ! ! /* ! * This is an optional short-cut; at each recursive call, ! * check to see if the elements in this subset are already ! * ordered. If so, no further comparisons are needed; the ! * sub-array can just be copied. The array must be copied rather ! * than assigned otherwise sister calls in the recursion might ! * get out of sinc. When the number of elements is three they ! * are partitioned so that the first set, [low, mid), has one ! * element and and the second, [mid, high), has two. We skip the ! * optimisation when the number of elements is three or less as ! * the first compare in the normal merge will produce the same ! * sequence of steps. This optimisation seems to be worthwhile ! * for partially ordered lists but some analysis is needed to ! * find out how the performance drops to Nlog(N) as the initial ! * order diminishes - it may drop very quickly. ! */ ! if (high - low >= 4 && this.compare(from[middle - 1], from[middle]) <= 0) ! { ! for (int i = low; i < high; i++) ! { ! to[i] = from[i]; ! } ! return; ! } ! ! // A normal merge. ! for (int i = low; i < high; i++) ! { ! if (q >= high || (p < middle && this.compare(from[p], from[q]) <= 0)) ! { ! to[i] = from[p++]; ! } ! else ! { ! to[i] = from[q++]; ! } ! } ! } ! ! ! /** ! * Description of the Method ! * ! * @param sender Description of the Parameter ! */ ! public void sort(Object sender) ! { ! this.checkModel(); ! ! this.compares = 0; ! // n2sort(); ! // qsort(0, indexes.length-1); ! this.shuttlesort((int[]) indexes.clone(), indexes, 0, indexes.length); ! //System.out.println("Compares: "+compares); ! } ! ! ! ! /** ! * Description of the Method ! * ! * @param column Description of the Parameter ! */ ! public void sortByColumn(int column) ! { ! this.sortByColumn(column, true); ! } ! ! ! /** ! * Description of the Method ! * ! * @param column Description of the Parameter ! * @param ascending Description of the Parameter ! */ ! public void sortByColumn(int column, boolean ascending) ! { ! this.ascending = ascending; ! this.sortingColumns.removeAllElements(); ! this.sortingColumns.addElement(new Integer(column)); ! this.sort(this); ! super.tableChanged(new TableModelEvent(this)); ! } ! ! ! /** ! * Description of the Method ! * ! * @param event Description of the Parameter ! */ ! public void tableChanged(TableModelEvent event) ! { ! this.reallocateIndexes(); ! // if (column >= 0) ! // { ! // this.sortByColumn(column, ascending); ! // } ! super.tableChanged(event); ! } ! } |