9607 lines · 367.0 KB · Java
RawDownload
/* * Copyright (c) 1997, 2010, 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; import java.util.*; import java.applet.Applet;import java.awt.*;import java.awt.event.*;import java.awt.print.*; import java.beans.*; import java.io.Serializable;import java.io.ObjectOutputStream;import java.io.ObjectInputStream;import java.io.IOException; import javax.accessibility.*; import javax.swing.event.*;import javax.swing.plaf.*;import javax.swing.table.*;import javax.swing.border.*; import java.text.NumberFormat;import java.text.DateFormat;import java.text.MessageFormat; import javax.print.attribute.*;import javax.print.PrintService; import sun.swing.SwingUtilities2;import sun.swing.SwingUtilities2.Section;import static sun.swing.SwingUtilities2.Section.*;import sun.swing.PrintingStatus;import sun.swing.SwingLazyValue; /** * The <code>JTable</code> is used to display and edit regular two-dimensional tables * of cells. * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/table.html">How to Use Tables</a> * in <em>The Java Tutorial</em> * for task-oriented documentation and examples of using <code>JTable</code>. * * <p> * The <code>JTable</code> has many * facilities that make it possible to customize its rendering and editing * but provides defaults for these features so that simple tables can be * set up easily.  For example, to set up a table with 10 rows and 10 * columns of numbers: * <p> * <pre> *      TableModel dataModel = new AbstractTableModel() { *          public int getColumnCount() { return 10; } *          public int getRowCount() { return 10;} *          public Object getValueAt(int row, int col) { return new Integer(row*col); } *      }; *      JTable table = new JTable(dataModel); *      JScrollPane scrollpane = new JScrollPane(table); * </pre> * <p> * {@code JTable}s are typically placed inside of a {@code JScrollPane}.  By * default, a {@code JTable} will adjust its width such that * a horizontal scrollbar is unnecessary.  To allow for a horizontal scrollbar, * invoke {@link #setAutoResizeMode} with {@code AUTO_RESIZE_OFF}. * Note that if you wish to use a <code>JTable</code> in a standalone * view (outside of a <code>JScrollPane</code>) and want the header * displayed, you can get it using {@link #getTableHeader} and * display it separately. * <p> * To enable sorting and filtering of rows, use a * {@code RowSorter}. * You can set up a row sorter in either of two ways: * <ul> *   <li>Directly set the {@code RowSorter}. For example: *        {@code table.setRowSorter(new TableRowSorter(model))}. *   <li>Set the {@code autoCreateRowSorter} *       property to {@code true}, so that the {@code JTable} *       creates a {@code RowSorter} for *       you. For example: {@code setAutoCreateRowSorter(true)}. * </ul> * <p> * When designing applications that use the <code>JTable</code> it is worth paying * close attention to the data structures that will represent the table's data. * The <code>DefaultTableModel</code> is a model implementation that * uses a <code>Vector</code> of <code>Vector</code>s of <code>Object</code>s to * store the cell values. As well as copying the data from an * application into the <code>DefaultTableModel</code>, * it is also possible to wrap the data in the methods of the * <code>TableModel</code> interface so that the data can be passed to the * <code>JTable</code> directly, as in the example above. This often results * in more efficient applications because the model is free to choose the * internal representation that best suits the data. * A good rule of thumb for deciding whether to use the <code>AbstractTableModel</code> * or the <code>DefaultTableModel</code> is to use the <code>AbstractTableModel</code> * as the base class for creating subclasses and the <code>DefaultTableModel</code> * when subclassing is not required. * <p> * The "TableExample" directory in the demo area of the source distribution * gives a number of complete examples of <code>JTable</code> usage, * covering how the <code>JTable</code> can be used to provide an * editable view of data taken from a database and how to modify * the columns in the display to use specialized renderers and editors. * <p> * The <code>JTable</code> uses integers exclusively to refer to both the rows and the columns * of the model that it displays. The <code>JTable</code> simply takes a tabular range of cells * and uses <code>getValueAt(int, int)</code> to retrieve the * values from the model during painting.  It is important to remember that * the column and row indexes returned by various <code>JTable</code> methods * are in terms of the <code>JTable</code> (the view) and are not * necessarily the same indexes used by the model. * <p> * By default, columns may be rearranged in the <code>JTable</code> so that the * view's columns appear in a different order to the columns in the model. * This does not affect the implementation of the model at all: when the * columns are reordered, the <code>JTable</code> maintains the new order of the columns * internally and converts its column indices before querying the model. * <p> * So, when writing a <code>TableModel</code>, it is not necessary to listen for column * reordering events as the model will be queried in its own coordinate * system regardless of what is happening in the view. * In the examples area there is a demonstration of a sorting algorithm making * use of exactly this technique to interpose yet another coordinate system * where the order of the rows is changed, rather than the order of the columns. * <p> * Similarly when using the sorting and filtering functionality * provided by <code>RowSorter</code> the underlying * <code>TableModel</code> does not need to know how to do sorting, * rather <code>RowSorter</code> will handle it.  Coordinate * conversions will be necessary when using the row based methods of * <code>JTable</code> with the underlying <code>TableModel</code>. * All of <code>JTable</code>s row based methods are in terms of the * <code>RowSorter</code>, which is not necessarily the same as that * of the underlying <code>TableModel</code>.  For example, the * selection is always in terms of <code>JTable</code> so that when * using <code>RowSorter</code> you will need to convert using * <code>convertRowIndexToView</code> or * <code>convertRowIndexToModel</code>.  The following shows how to * convert coordinates from <code>JTable</code> to that of the * underlying model: * <pre> *   int[] selection = table.getSelectedRows(); *   for (int i = 0; i &lt; selection.length; i++) { *     selection[i] = table.convertRowIndexToModel(selection[i]); *   } *   // selection is now in terms of the underlying TableModel * </pre> * <p> * By default if sorting is enabled <code>JTable</code> will persist the * selection and variable row heights in terms of the model on * sorting.  For example if row 0, in terms of the underlying model, * is currently selected, after the sort row 0, in terms of the * underlying model will be selected.  Visually the selection may * change, but in terms of the underlying model it will remain the * same.  The one exception to that is if the model index is no longer * visible or was removed.  For example, if row 0 in terms of model * was filtered out the selection will be empty after the sort. * <p> * J2SE 5 adds methods to <code>JTable</code> to provide convenient access to some * common printing needs. Simple new {@link #print()} methods allow for quick * and easy addition of printing support to your application. In addition, a new * {@link #getPrintable} method is available for more advanced printing needs. * <p> * As for all <code>JComponent</code> classes, you can use * {@link InputMap} and {@link ActionMap} to associate an * {@link Action} object with a {@link KeyStroke} and execute the * action under specified conditions. * <p> * <strong>Warning:</strong> Swing is not thread safe. For more * information see <a * href="package-summary.html#threading">Swing's Threading * Policy</a>. * <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}. * * * @beaninfo *   attribute: isContainer false * description: A component which displays data in a two dimensional grid. * * @author Philip Milne * @author Shannon Hickey (printing support) * @see javax.swing.table.DefaultTableModel * @see javax.swing.table.TableRowSorter *//* The first versions of the JTable, contained in Swing-0.1 through * Swing-0.4, were written by Alan Chung. */public class JTable extends JComponent implements TableModelListener, Scrollable,    TableColumnModelListener, ListSelectionListener, CellEditorListener,    Accessible, RowSorterListener{//// Static Constants//     /**     * @see #getUIClassID     * @see #readObject     */    private static final String uiClassID = "TableUI";     /** Do not adjust column widths automatically; use a horizontal scrollbar instead. */    public static final int     AUTO_RESIZE_OFF = 0;     /** When a column is adjusted in the UI, adjust the next column the opposite way. */    public static final int     AUTO_RESIZE_NEXT_COLUMN = 1;     /** During UI adjustment, change subsequent columns to preserve the total width;      * this is the default behavior. */    public static final int     AUTO_RESIZE_SUBSEQUENT_COLUMNS = 2;     /** During all resize operations, apply adjustments to the last column only. */    public static final int     AUTO_RESIZE_LAST_COLUMN = 3;     /** During all resize operations, proportionately resize all columns. */    public static final int     AUTO_RESIZE_ALL_COLUMNS = 4;      /**     * Printing modes, used in printing <code>JTable</code>s.     *     * @see #print(JTable.PrintMode, MessageFormat, MessageFormat,     *             boolean, PrintRequestAttributeSet, boolean)     * @see #getPrintable     * @since 1.5     */    public enum PrintMode {         /**         * Printing mode that prints the table at its current size,         * spreading both columns and rows across multiple pages if necessary.         */        NORMAL,         /**         * Printing mode that scales the output smaller, if necessary,         * to fit the table's entire width (and thereby all columns) on each page;         * Rows are spread across multiple pages as necessary.         */        FIT_WIDTH    }  //// Instance Variables//     /** The <code>TableModel</code> of the table. */    protected TableModel        dataModel;     /** The <code>TableColumnModel</code> of the table. */    protected TableColumnModel  columnModel;     /** The <code>ListSelectionModel</code> of the table, used to keep track of row selections. */    protected ListSelectionModel selectionModel;     /** The <code>TableHeader</code> working with the table. */    protected JTableHeader      tableHeader;     /** The height in pixels of each row in the table. */    protected int               rowHeight;     /** The height in pixels of the margin between the cells in each row. */    protected int               rowMargin;     /** The color of the grid. */    protected Color             gridColor;     /** The table draws horizontal lines between cells if <code>showHorizontalLines</code> is true. */    protected boolean           showHorizontalLines;     /** The table draws vertical lines between cells if <code>showVerticalLines</code> is true. */    protected boolean           showVerticalLines;     /**     *  Determines if the table automatically resizes the     *  width of the table's columns to take up the entire width of the     *  table, and how it does the resizing.     */    protected int               autoResizeMode;     /**     *  The table will query the <code>TableModel</code> to build the default     *  set of columns if this is true.     */    protected boolean           autoCreateColumnsFromModel;     /** Used by the <code>Scrollable</code> interface to determine the initial visible area. */    protected Dimension         preferredViewportSize;     /** True if row selection is allowed in this table. */    protected boolean           rowSelectionAllowed;     /**     * Obsolete as of Java 2 platform v1.3.  Please use the     * <code>rowSelectionAllowed</code> property and the     * <code>columnSelectionAllowed</code> property of the     * <code>columnModel</code> instead. Or use the     * method <code>getCellSelectionEnabled</code>.     */    /*     * If true, both a row selection and a column selection     * can be non-empty at the same time, the selected cells are the     * the cells whose row and column are both selected.     */    protected boolean           cellSelectionEnabled;     /** If editing, the <code>Component</code> that is handling the editing. */    transient protected Component       editorComp;     /**     * The active cell editor object, that overwrites the screen real estate     * occupied by the current cell and allows the user to change its contents.     * {@code null} if the table isn't currently editing.     */    transient protected TableCellEditor cellEditor;     /** Identifies the column of the cell being edited. */    transient protected int             editingColumn;     /** Identifies the row of the cell being edited. */    transient protected int             editingRow;     /**     * A table of objects that display the contents of a cell,     * indexed by class as declared in <code>getColumnClass</code>     * in the <code>TableModel</code> interface.     */    transient protected Hashtable defaultRenderersByColumnClass;     /**     * A table of objects that display and edit the contents of a cell,     * indexed by class as declared in <code>getColumnClass</code>     * in the <code>TableModel</code> interface.     */    transient protected Hashtable defaultEditorsByColumnClass;     /** The foreground color of selected cells. */    protected Color selectionForeground;     /** The background color of selected cells. */    protected Color selectionBackground; //// Private state//     // WARNING: If you directly access this field you should also change the    // SortManager.modelRowSizes field as well.    private SizeSequence rowModel;    private boolean dragEnabled;    private boolean surrendersFocusOnKeystroke;    private PropertyChangeListener editorRemover = null;    /**     * The last value of getValueIsAdjusting from the column selection models     * columnSelectionChanged notification. Used to test if a repaint is     * needed.     */    private boolean columnSelectionAdjusting;    /**     * The last value of getValueIsAdjusting from the row selection models     * valueChanged notification. Used to test if a repaint is needed.     */    private boolean rowSelectionAdjusting;     /**     * To communicate errors between threads during printing.     */    private Throwable printError;     /**     * True when setRowHeight(int) has been invoked.     */    private boolean isRowHeightSet;     /**     * If true, on a sort the selection is reset.     */    private boolean updateSelectionOnSort;     /**     * Information used in sorting.     */    private transient SortManager sortManager;     /**     * If true, when sorterChanged is invoked it's value is ignored.     */    private boolean ignoreSortChange;     /**     * Whether or not sorterChanged has been invoked.     */    private boolean sorterChanged;     /**     * If true, any time the model changes a new RowSorter is set.     */    private boolean autoCreateRowSorter;     /**     * Whether or not the table always fills the viewport height.     * @see #setFillsViewportHeight     * @see #getScrollableTracksViewportHeight     */    private boolean fillsViewportHeight;     /**     * The drop mode for this component.     */    private DropMode dropMode = DropMode.USE_SELECTION;     /**     * The drop location.     */    private transient DropLocation dropLocation;     /**     * A subclass of <code>TransferHandler.DropLocation</code> representing     * a drop location for a <code>JTable</code>.     *     * @see #getDropLocation     * @since 1.6     */    public static final class DropLocation extends TransferHandler.DropLocation {        private final int row;        private final int col;        private final boolean isInsertRow;        private final boolean isInsertCol;         private DropLocation(Point p, int row, int col,                             boolean isInsertRow, boolean isInsertCol) {             super(p);            this.row = row;            this.col = col;            this.isInsertRow = isInsertRow;            this.isInsertCol = isInsertCol;        }         /**         * Returns the row index where a dropped item should be placed in the         * table. Interpretation of the value depends on the return of         * <code>isInsertRow()</code>. If that method returns         * <code>true</code> this value indicates the index where a new         * row should be inserted. Otherwise, it represents the value         * of an existing row on which the data was dropped. This index is         * in terms of the view.         * <p>         * <code>-1</code> indicates that the drop occurred over empty space,         * and no row could be calculated.         *         * @return the drop row         */        public int getRow() {            return row;        }         /**         * Returns the column index where a dropped item should be placed in the         * table. Interpretation of the value depends on the return of         * <code>isInsertColumn()</code>. If that method returns         * <code>true</code> this value indicates the index where a new         * column should be inserted. Otherwise, it represents the value         * of an existing column on which the data was dropped. This index is         * in terms of the view.         * <p>         * <code>-1</code> indicates that the drop occurred over empty space,

Lines 1–500 of 9607.