708 lines · 25.4 KB · Java
RawDownload
/* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.swing.table; import java.io.Serializable;import java.util.Vector;import java.util.Enumeration;import javax.swing.event.TableModelEvent;  /** * This is an implementation of <code>TableModel</code> that * uses a <code>Vector</code> of <code>Vectors</code> to store the * cell value objects. * <p> * <strong>Warning:</strong> <code>DefaultTableModel</code> returns a * column class of <code>Object</code>.  When * <code>DefaultTableModel</code> is used with a * <code>TableRowSorter</code> this will result in extensive use of * <code>toString</code>, which for non-<code>String</code> data types * is expensive.  If you use <code>DefaultTableModel</code> with a * <code>TableRowSorter</code> you are strongly encouraged to override * <code>getColumnClass</code> to return the appropriate type. * <p> * <strong>Warning:</strong> * Serialized objects of this class will not be compatible with * future Swing releases. The current serialization support is * appropriate for short term storage or RMI between applications running * the same version of Swing.  As of 1.4, support for long term storage * of all JavaBeans<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * * @author Philip Milne * * @see TableModel * @see #getDataVector */public class DefaultTableModel extends AbstractTableModel implements Serializable { //// Instance Variables//     /**     * The <code>Vector</code> of <code>Vectors</code> of     * <code>Object</code> values.     */    protected Vector    dataVector;     /** The <code>Vector</code> of column identifiers. */    protected Vector    columnIdentifiers; //// Constructors//     /**     *  Constructs a default <code>DefaultTableModel</code>     *  which is a table of zero columns and zero rows.     */    public DefaultTableModel() {        this(0, 0);    }     private static Vector newVector(int size) {        Vector v = new Vector(size);        v.setSize(size);        return v;    }     /**     *  Constructs a <code>DefaultTableModel</code> with     *  <code>rowCount</code> and <code>columnCount</code> of     *  <code>null</code> object values.     *     * @param rowCount           the number of rows the table holds     * @param columnCount        the number of columns the table holds     *     * @see #setValueAt     */    public DefaultTableModel(int rowCount, int columnCount) {        this(newVector(columnCount), rowCount);    }     /**     *  Constructs a <code>DefaultTableModel</code> with as many columns     *  as there are elements in <code>columnNames</code>     *  and <code>rowCount</code> of <code>null</code>     *  object values.  Each column's name will be taken from     *  the <code>columnNames</code> vector.     *     * @param columnNames       <code>vector</code> containing the names     *                          of the new columns; if this is     *                          <code>null</code> then the model has no columns     * @param rowCount           the number of rows the table holds     * @see #setDataVector     * @see #setValueAt     */    public DefaultTableModel(Vector columnNames, int rowCount) {        setDataVector(newVector(rowCount), columnNames);    }     /**     *  Constructs a <code>DefaultTableModel</code> with as many     *  columns as there are elements in <code>columnNames</code>     *  and <code>rowCount</code> of <code>null</code>     *  object values.  Each column's name will be taken from     *  the <code>columnNames</code> array.     *     * @param columnNames       <code>array</code> containing the names     *                          of the new columns; if this is     *                          <code>null</code> then the model has no columns     * @param rowCount           the number of rows the table holds     * @see #setDataVector     * @see #setValueAt     */    public DefaultTableModel(Object[] columnNames, int rowCount) {        this(convertToVector(columnNames), rowCount);    }     /**     *  Constructs a <code>DefaultTableModel</code> and initializes the table     *  by passing <code>data</code> and <code>columnNames</code>     *  to the <code>setDataVector</code> method.     *     * @param data              the data of the table, a <code>Vector</code>     *                          of <code>Vector</code>s of <code>Object</code>     *                          values     * @param columnNames       <code>vector</code> containing the names     *                          of the new columns     * @see #getDataVector     * @see #setDataVector     */    public DefaultTableModel(Vector data, Vector columnNames) {        setDataVector(data, columnNames);    }     /**     *  Constructs a <code>DefaultTableModel</code> and initializes the table     *  by passing <code>data</code> and <code>columnNames</code>     *  to the <code>setDataVector</code>     *  method. The first index in the <code>Object[][]</code> array is     *  the row index and the second is the column index.     *     * @param data              the data of the table     * @param columnNames       the names of the columns     * @see #getDataVector     * @see #setDataVector     */    public DefaultTableModel(Object[][] data, Object[] columnNames) {        setDataVector(data, columnNames);    }     /**     *  Returns the <code>Vector</code> of <code>Vectors</code>     *  that contains the table's     *  data values.  The vectors contained in the outer vector are     *  each a single row of values.  In other words, to get to the cell     *  at row 1, column 5: <p>     *     *  <code>((Vector)getDataVector().elementAt(1)).elementAt(5);</code><p>     *     * @return  the vector of vectors containing the tables data values     *     * @see #newDataAvailable     * @see #newRowsAdded     * @see #setDataVector     */    public Vector getDataVector() {        return dataVector;    }     private static Vector nonNullVector(Vector v) {        return (v != null) ? v : new Vector();    }     /**     *  Replaces the current <code>dataVector</code> instance variable     *  with the new <code>Vector</code> of rows, <code>dataVector</code>.     *  Each row is represented in <code>dataVector</code> as a     *  <code>Vector</code> of <code>Object</code> values.     *  <code>columnIdentifiers</code> are the names of the new     *  columns.  The first name in <code>columnIdentifiers</code> is     *  mapped to column 0 in <code>dataVector</code>. Each row in     *  <code>dataVector</code> is adjusted to match the number of     *  columns in <code>columnIdentifiers</code>     *  either by truncating the <code>Vector</code> if it is too long,     *  or adding <code>null</code> values if it is too short.     *  <p>Note that passing in a <code>null</code> value for     *  <code>dataVector</code> results in unspecified behavior,     *  an possibly an exception.     *     * @param   dataVector         the new data vector     * @param   columnIdentifiers     the names of the columns     * @see #getDataVector     */    public void setDataVector(Vector dataVector, Vector columnIdentifiers) {        this.dataVector = nonNullVector(dataVector);        this.columnIdentifiers = nonNullVector(columnIdentifiers);        justifyRows(0, getRowCount());        fireTableStructureChanged();    }     /**     *  Replaces the value in the <code>dataVector</code> instance     *  variable with the values in the array <code>dataVector</code>.     *  The first index in the <code>Object[][]</code>     *  array is the row index and the second is the column index.     *  <code>columnIdentifiers</code> are the names of the new columns.     *     * @param dataVector                the new data vector     * @param columnIdentifiers the names of the columns     * @see #setDataVector(Vector, Vector)     */    public void setDataVector(Object[][] dataVector, Object[] columnIdentifiers) {        setDataVector(convertToVector(dataVector), convertToVector(columnIdentifiers));    }     /**     *  Equivalent to <code>fireTableChanged</code>.     *     * @param event  the change event     *     */    public void newDataAvailable(TableModelEvent event) {        fireTableChanged(event);    } //// Manipulating rows//     private void justifyRows(int from, int to) {        // Sometimes the DefaultTableModel is subclassed        // instead of the AbstractTableModel by mistake.        // Set the number of rows for the case when getRowCount        // is overridden.        dataVector.setSize(getRowCount());         for (int i = from; i < to; i++) {            if (dataVector.elementAt(i) == null) {                dataVector.setElementAt(new Vector(), i);            }            ((Vector)dataVector.elementAt(i)).setSize(getColumnCount());        }    }     /**     *  Ensures that the new rows have the correct number of columns.     *  This is accomplished by  using the <code>setSize</code> method in     *  <code>Vector</code> which truncates vectors     *  which are too long, and appends <code>null</code>s if they     *  are too short.     *  This method also sends out a <code>tableChanged</code>     *  notification message to all the listeners.     *     * @param e         this <code>TableModelEvent</code> describes     *                           where the rows were added.     *                           If <code>null</code> it assumes     *                           all the rows were newly added     * @see #getDataVector     */    public void newRowsAdded(TableModelEvent e) {        justifyRows(e.getFirstRow(), e.getLastRow() + 1);        fireTableChanged(e);    }     /**     *  Equivalent to <code>fireTableChanged</code>.     *     *  @param event the change event     *     */    public void rowsRemoved(TableModelEvent event) {        fireTableChanged(event);    }     /**     * Obsolete as of Java 2 platform v1.3.  Please use <code>setRowCount</code> instead.     */    /*     *  Sets the number of rows in the model.  If the new size is greater     *  than the current size, new rows are added to the end of the model     *  If the new size is less than the current size, all     *  rows at index <code>rowCount</code> and greater are discarded. <p>     *     * @param   rowCount   the new number of rows     * @see #setRowCount     */    public void setNumRows(int rowCount) {        int old = getRowCount();        if (old == rowCount) {            return;        }        dataVector.setSize(rowCount);        if (rowCount <= old) {            fireTableRowsDeleted(rowCount, old-1);        }        else {            justifyRows(old, rowCount);            fireTableRowsInserted(old, rowCount-1);        }    }     /**     *  Sets the number of rows in the model.  If the new size is greater     *  than the current size, new rows are added to the end of the model     *  If the new size is less than the current size, all     *  rows at index <code>rowCount</code> and greater are discarded. <p>     *     *  @see #setColumnCount     * @since 1.3     */    public void setRowCount(int rowCount) {        setNumRows(rowCount);    }     /**     *  Adds a row to the end of the model.  The new row will contain     *  <code>null</code> values unless <code>rowData</code> is specified.     *  Notification of the row being added will be generated.     *     * @param   rowData          optional data of the row being added     */    public void addRow(Vector rowData) {        insertRow(getRowCount(), rowData);    }     /**     *  Adds a row to the end of the model.  The new row will contain     *  <code>null</code> values unless <code>rowData</code> is specified.     *  Notification of the row being added will be generated.     *     * @param   rowData          optional data of the row being added     */    public void addRow(Object[] rowData) {        addRow(convertToVector(rowData));    }     /**     *  Inserts a row at <code>row</code> in the model.  The new row     *  will contain <code>null</code> values unless <code>rowData</code>     *  is specified.  Notification of the row being added will be generated.     *     * @param   row             the row index of the row to be inserted     * @param   rowData         optional data of the row being added     * @exception  ArrayIndexOutOfBoundsException  if the row was invalid     */    public void insertRow(int row, Vector rowData) {        dataVector.insertElementAt(rowData, row);        justifyRows(row, row+1);        fireTableRowsInserted(row, row);    }     /**     *  Inserts a row at <code>row</code> in the model.  The new row     *  will contain <code>null</code> values unless <code>rowData</code>     *  is specified.  Notification of the row being added will be generated.     *     * @param   row      the row index of the row to be inserted     * @param   rowData          optional data of the row being added     * @exception  ArrayIndexOutOfBoundsException  if the row was invalid     */    public void insertRow(int row, Object[] rowData) {        insertRow(row, convertToVector(rowData));    }     private static int gcd(int i, int j) {        return (j == 0) ? i : gcd(j, i%j);    }     private static void rotate(Vector v, int a, int b, int shift) {        int size = b - a;        int r = size - shift;        int g = gcd(size, r);        for(int i = 0; i < g; i++) {            int to = i;            Object tmp = v.elementAt(a + to);            for(int from = (to + r) % size; from != i; from = (to + r) % size) {                v.setElementAt(v.elementAt(a + from), a + to);                to = from;            }            v.setElementAt(tmp, a + to);        }    }     /**     *  Moves one or more rows from the inclusive range <code>start</code> to     *  <code>end</code> to the <code>to</code> position in the model.     *  After the move, the row that was at index <code>start</code>     *  will be at index <code>to</code>.     *  This method will send a <code>tableChanged</code> notification     *  message to all the listeners. <p>     *     *  <pre>     *  Examples of moves:     *  <p>     *  1. moveRow(1,3,5);     *          a|B|C|D|e|f|g|h|i|j|k   - before     *          a|e|f|g|h|B|C|D|i|j|k   - after     *  <p>     *  2. moveRow(6,7,1);     *          a|b|c|d|e|f|G|H|i|j|k   - before     *          a|G|H|b|c|d|e|f|i|j|k   - after     *  <p>     *  </pre>     *     * @param   start       the starting row index to be moved     * @param   end         the ending row index to be moved     * @param   to          the destination of the rows to be moved     * @exception  ArrayIndexOutOfBoundsException  if any of the elements     * would be moved out of the table's range     *     */    public void moveRow(int start, int end, int to) {        int shift = to - start;        int first, last;        if (shift < 0) {            first = to;            last = end;        }        else {            first = start;            last = to + end - start;        }        rotate(dataVector, first, last + 1, shift);         fireTableRowsUpdated(first, last);    }     /**     *  Removes the row at <code>row</code> from the model.  Notification     *  of the row being removed will be sent to all the listeners.     *     * @param   row      the row index of the row to be removed     * @exception  ArrayIndexOutOfBoundsException  if the row was invalid     */    public void removeRow(int row) {        dataVector.removeElementAt(row);        fireTableRowsDeleted(row, row);    } //// Manipulating columns//     /**     * Replaces the column identifiers in the model.  If the number of     * <code>newIdentifier</code>s is greater than the current number     * of columns, new columns are added to the end of each row in the model.     * If the number of <code>newIdentifier</code>s is less than the current     * number of columns, all the extra columns at the end of a row are     * discarded. <p>     *     * @param   columnIdentifiers  vector of column identifiers.  If     *                          <code>null</code>, set the model     *                          to zero columns     * @see #setNumRows     */    public void setColumnIdentifiers(Vector columnIdentifiers) {        setDataVector(dataVector, columnIdentifiers);    }     /**     * Replaces the column identifiers in the model.  If the number of     * <code>newIdentifier</code>s is greater than the current number     * of columns, new columns are added to the end of each row in the model.     * If the number of <code>newIdentifier</code>s is less than the current     * number of columns, all the extra columns at the end of a row are     * discarded. <p>     *     * @param   newIdentifiers  array of column identifiers.     *                          If <code>null</code>, set     *                          the model to zero columns     * @see #setNumRows     */

Lines 1–500 of 708.