739 lines · 25.9 KB · Java
RawDownload
/* * Copyright (c) 1997, 2005, 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 javax.swing.*;import javax.swing.event.*;import java.awt.*;import java.util.Vector;import java.util.Enumeration;import java.util.EventListener;import java.beans.PropertyChangeListener;import java.beans.PropertyChangeEvent;import java.io.Serializable;import sun.swing.SwingUtilities2; /** * The standard column-handler for a <code>JTable</code>. * <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 Alan Chung * @author Philip Milne * @see JTable */public class DefaultTableColumnModel implements TableColumnModel,                        PropertyChangeListener, ListSelectionListener, Serializable{//// Instance Variables//     /** Array of TableColumn objects in this model */    protected Vector<TableColumn> tableColumns;     /** Model for keeping track of column selections */    protected ListSelectionModel selectionModel;     /** Width margin between each column */    protected int columnMargin;     /** List of TableColumnModelListener */    protected EventListenerList listenerList = new EventListenerList();     /** Change event (only one needed) */    transient protected ChangeEvent changeEvent = null;     /** Column selection allowed in this column model */    protected boolean columnSelectionAllowed;     /** A local cache of the combined width of all columns */    protected int totalColumnWidth; //// Constructors//    /**     * Creates a default table column model.     */    public DefaultTableColumnModel() {        super();         // Initialize local ivars to default        tableColumns = new Vector<TableColumn>();        setSelectionModel(createSelectionModel());        setColumnMargin(1);        invalidateWidthCache();        setColumnSelectionAllowed(false);    } //// Modifying the model//     /**     *  Appends <code>aColumn</code> to the end of the     *  <code>tableColumns</code> array.     *  This method also posts the <code>columnAdded</code>     *  event to its listeners.     *     * @param   aColumn         the <code>TableColumn</code> to be added     * @exception IllegalArgumentException      if <code>aColumn</code> is     *                          <code>null</code>     * @see     #removeColumn     */    public void addColumn(TableColumn aColumn) {        if (aColumn == null) {            throw new IllegalArgumentException("Object is null");        }         tableColumns.addElement(aColumn);        aColumn.addPropertyChangeListener(this);        invalidateWidthCache();         // Post columnAdded event notification        fireColumnAdded(new TableColumnModelEvent(this, 0,                                                  getColumnCount() - 1));    }     /**     *  Deletes the <code>column</code> from the     *  <code>tableColumns</code> array.  This method will do nothing if     *  <code>column</code> is not in the table's columns list.     *  <code>tile</code> is called     *  to resize both the header and table views.     *  This method also posts a <code>columnRemoved</code>     *  event to its listeners.     *     * @param   column          the <code>TableColumn</code> to be removed     * @see     #addColumn     */    public void removeColumn(TableColumn column) {        int columnIndex = tableColumns.indexOf(column);         if (columnIndex != -1) {            // Adjust for the selection            if (selectionModel != null) {                selectionModel.removeIndexInterval(columnIndex,columnIndex);            }             column.removePropertyChangeListener(this);            tableColumns.removeElementAt(columnIndex);            invalidateWidthCache();             // Post columnAdded event notification.  (JTable and JTableHeader            // listens so they can adjust size and redraw)            fireColumnRemoved(new TableColumnModelEvent(this,                                           columnIndex, 0));        }    }     /**     * Moves the column and heading at <code>columnIndex</code> to     * <code>newIndex</code>.  The old column at <code>columnIndex</code>     * will now be found at <code>newIndex</code>.  The column     * that used to be at <code>newIndex</code> is shifted     * left or right to make room.  This will not move any columns if     * <code>columnIndex</code> equals <code>newIndex</code>.  This method     * also posts a <code>columnMoved</code> event to its listeners.     *     * @param   columnIndex                     the index of column to be moved     * @param   newIndex                        new index to move the column     * @exception IllegalArgumentException      if <code>column</code> or     *                                          <code>newIndex</code>     *                                          are not in the valid range     */    public void moveColumn(int columnIndex, int newIndex) {        if ((columnIndex < 0) || (columnIndex >= getColumnCount()) ||            (newIndex < 0) || (newIndex >= getColumnCount()))            throw new IllegalArgumentException("moveColumn() - Index out of range");         TableColumn aColumn;         // If the column has not yet moved far enough to change positions        // post the event anyway, the "draggedDistance" property of the        // tableHeader will say how far the column has been dragged.        // Here we are really trying to get the best out of an        // API that could do with some rethinking. We preserve backward        // compatibility by slightly bending the meaning of these methods.        if (columnIndex == newIndex) {            fireColumnMoved(new TableColumnModelEvent(this, columnIndex, newIndex));            return;        }        aColumn = tableColumns.elementAt(columnIndex);         tableColumns.removeElementAt(columnIndex);        boolean selected = selectionModel.isSelectedIndex(columnIndex);        selectionModel.removeIndexInterval(columnIndex,columnIndex);         tableColumns.insertElementAt(aColumn, newIndex);        selectionModel.insertIndexInterval(newIndex, 1, true);        if (selected) {            selectionModel.addSelectionInterval(newIndex, newIndex);        }        else {            selectionModel.removeSelectionInterval(newIndex, newIndex);        }         fireColumnMoved(new TableColumnModelEvent(this, columnIndex,                                                               newIndex));    }     /**     * Sets the column margin to <code>newMargin</code>.  This method     * also posts a <code>columnMarginChanged</code> event to its     * listeners.     *     * @param   newMargin               the new margin width, in pixels     * @see     #getColumnMargin     * @see     #getTotalColumnWidth     */    public void setColumnMargin(int newMargin) {        if (newMargin != columnMargin) {            columnMargin = newMargin;            // Post columnMarginChanged event notification.            fireColumnMarginChanged();        }    } //// Querying the model//     /**     * Returns the number of columns in the <code>tableColumns</code> array.     *     * @return  the number of columns in the <code>tableColumns</code> array     * @see     #getColumns     */    public int getColumnCount() {        return tableColumns.size();    }     /**     * Returns an <code>Enumeration</code> of all the columns in the model.     * @return an <code>Enumeration</code> of the columns in the model     */    public Enumeration<TableColumn> getColumns() {        return tableColumns.elements();    }     /**     * Returns the index of the first column in the <code>tableColumns</code>     * array whose identifier is equal to <code>identifier</code>,     * when compared using <code>equals</code>.     *     * @param           identifier              the identifier object     * @return          the index of the first column in the     *                  <code>tableColumns</code> array whose identifier     *                  is equal to <code>identifier</code>     * @exception       IllegalArgumentException  if <code>identifier</code>     *                          is <code>null</code>, or if no     *                          <code>TableColumn</code> has this     *                          <code>identifier</code>     * @see             #getColumn     */    public int getColumnIndex(Object identifier) {        if (identifier == null) {            throw new IllegalArgumentException("Identifier is null");        }         Enumeration enumeration = getColumns();        TableColumn aColumn;        int index = 0;         while (enumeration.hasMoreElements()) {            aColumn = (TableColumn)enumeration.nextElement();            // Compare them this way in case the column's identifier is null.            if (identifier.equals(aColumn.getIdentifier()))                return index;            index++;        }        throw new IllegalArgumentException("Identifier not found");    }     /**     * Returns the <code>TableColumn</code> object for the column     * at <code>columnIndex</code>.     *     * @param   columnIndex     the index of the column desired     * @return  the <code>TableColumn</code> object for the column     *                          at <code>columnIndex</code>     */    public TableColumn getColumn(int columnIndex) {        return tableColumns.elementAt(columnIndex);    }     /**     * Returns the width margin for <code>TableColumn</code>.     * The default <code>columnMargin</code> is 1.     *     * @return  the maximum width for the <code>TableColumn</code>     * @see     #setColumnMargin     */    public int getColumnMargin() {        return columnMargin;    }     /**     * Returns the index of the column that lies at position <code>x</code>,     * or -1 if no column covers this point.     *     * In keeping with Swing's separable model architecture, a     * TableColumnModel does not know how the table columns actually appear on     * screen.  The visual presentation of the columns is the responsibility     * of the view/controller object using this model (typically JTable).  The     * view/controller need not display the columns sequentially from left to     * right.  For example, columns could be displayed from right to left to     * accomodate a locale preference or some columns might be hidden at the     * request of the user.  Because the model does not know how the columns     * are laid out on screen, the given <code>xPosition</code> should not be     * considered to be a coordinate in 2D graphics space.  Instead, it should     * be considered to be a width from the start of the first column in the     * model.  If the column index for a given X coordinate in 2D space is     * required, <code>JTable.columnAtPoint</code> can be used instead.     *     * @param  x  the horizontal location of interest     * @return  the index of the column or -1 if no column is found     * @see javax.swing.JTable#columnAtPoint     */    public int getColumnIndexAtX(int x) {        if (x < 0) {            return -1;        }        int cc = getColumnCount();        for(int column = 0; column < cc; column++) {            x = x - getColumn(column).getWidth();            if (x < 0) {                return column;            }        }        return -1;    }     /**     * Returns the total combined width of all columns.     * @return the <code>totalColumnWidth</code> property     */    public int getTotalColumnWidth() {        if (totalColumnWidth == -1) {            recalcWidthCache();        }        return totalColumnWidth;    } //// Selection model//     /**     *  Sets the selection model for this <code>TableColumnModel</code>     *  to <code>newModel</code>     *  and registers for listener notifications from the new selection     *  model.  If <code>newModel</code> is <code>null</code>,     *  an exception is thrown.     *     * @param   newModel        the new selection model     * @exception IllegalArgumentException      if <code>newModel</code>     *                                          is <code>null</code>     * @see     #getSelectionModel     */    public void setSelectionModel(ListSelectionModel newModel) {        if (newModel == null) {            throw new IllegalArgumentException("Cannot set a null SelectionModel");        }         ListSelectionModel oldModel = selectionModel;         if (newModel != oldModel) {            if (oldModel != null) {                oldModel.removeListSelectionListener(this);            }             selectionModel= newModel;            newModel.addListSelectionListener(this);        }    }     /**     * Returns the <code>ListSelectionModel</code> that is used to     * maintain column selection state.     *     * @return  the object that provides column selection state.  Or     *          <code>null</code> if row selection is not allowed.     * @see     #setSelectionModel     */    public ListSelectionModel getSelectionModel() {        return selectionModel;    }     // implements javax.swing.table.TableColumnModel    /**     * Sets whether column selection is allowed.  The default is false.     * @param  flag true if column selection will be allowed, false otherwise     */    public void setColumnSelectionAllowed(boolean flag) {        columnSelectionAllowed = flag;    }     // implements javax.swing.table.TableColumnModel    /**     * Returns true if column selection is allowed, otherwise false.     * The default is false.     * @return the <code>columnSelectionAllowed</code> property     */    public boolean getColumnSelectionAllowed() {        return columnSelectionAllowed;    }     // implements javax.swing.table.TableColumnModel    /**     * Returns an array of selected columns.  If <code>selectionModel</code>     * is <code>null</code>, returns an empty array.     * @return an array of selected columns or an empty array if nothing     *                  is selected or the <code>selectionModel</code> is     *                  <code>null</code>     */    public int[] getSelectedColumns() {        if (selectionModel != null) {            int iMin = selectionModel.getMinSelectionIndex();            int iMax = selectionModel.getMaxSelectionIndex();             if ((iMin == -1) || (iMax == -1)) {                return new int[0];            }             int[] rvTmp = new int[1+ (iMax - iMin)];            int n = 0;            for(int i = iMin; i <= iMax; i++) {                if (selectionModel.isSelectedIndex(i)) {                    rvTmp[n++] = i;                }            }            int[] rv = new int[n];            System.arraycopy(rvTmp, 0, rv, 0, n);            return rv;        }        return  new int[0];    }     // implements javax.swing.table.TableColumnModel    /**     * Returns the number of columns selected.     * @return the number of columns selected     */    public int getSelectedColumnCount() {        if (selectionModel != null) {            int iMin = selectionModel.getMinSelectionIndex();            int iMax = selectionModel.getMaxSelectionIndex();            int count = 0;             for(int i = iMin; i <= iMax; i++) {                if (selectionModel.isSelectedIndex(i)) {                    count++;                }            }            return count;        }        return 0;    } //// Listener Support Methods//     // implements javax.swing.table.TableColumnModel    /**     * Adds a listener for table column model events.     * @param x  a <code>TableColumnModelListener</code> object     */    public void addColumnModelListener(TableColumnModelListener x) {        listenerList.add(TableColumnModelListener.class, x);    }     // implements javax.swing.table.TableColumnModel    /**     * Removes a listener for table column model events.     * @param x  a <code>TableColumnModelListener</code> object     */    public void removeColumnModelListener(TableColumnModelListener x) {        listenerList.remove(TableColumnModelListener.class, x);    }     /**     * Returns an array of all the column model listeners     * registered on this model.     *     * @return all of this default table column model's <code>ColumnModelListener</code>s     *         or an empty     *         array if no column model listeners are currently registered     *

Lines 1–500 of 739.