jdk/src/share/classes/javax/swing/JTable.java

Print this page




   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing;
  27 
  28 import java.util.*;
  29 
  30 import java.applet.Applet;
  31 import java.awt.*;
  32 import java.awt.event.*;
  33 import java.awt.print.*;
  34 
  35 import java.beans.*;



  36 
  37 import java.io.ObjectOutputStream;
  38 import java.io.ObjectInputStream;
  39 import java.io.IOException;
  40 import java.io.InvalidObjectException;
  41 
  42 import javax.accessibility.*;
  43 
  44 import javax.swing.event.*;
  45 import javax.swing.plaf.*;
  46 import javax.swing.table.*;
  47 import javax.swing.border.*;
  48 
  49 import java.text.NumberFormat;
  50 import java.text.DateFormat;
  51 import java.text.MessageFormat;
  52 
  53 import javax.print.attribute.*;
  54 import javax.print.PrintService;

  55 import sun.reflect.misc.ReflectUtil;
  56 
  57 import sun.swing.SwingUtilities2;
  58 import sun.swing.SwingUtilities2.Section;
  59 import static sun.swing.SwingUtilities2.Section.*;
  60 import sun.swing.PrintingStatus;
  61 
  62 /**
  63  * The <code>JTable</code> is used to display and edit regular two-dimensional tables
  64  * of cells.
  65  * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/table.html">How to Use Tables</a>
  66  * in <em>The Java Tutorial</em>
  67  * for task-oriented documentation and examples of using <code>JTable</code>.
  68  *
  69  * <p>
  70  * The <code>JTable</code> has many
  71  * facilities that make it possible to customize its rendering and editing
  72  * but provides defaults for these features so that simple tables can be
  73  * set up easily.  For example, to set up a table with 10 rows and 10
  74  * columns of numbers:


 187  * <p>
 188  * As for all <code>JComponent</code> classes, you can use
 189  * {@link InputMap} and {@link ActionMap} to associate an
 190  * {@link Action} object with a {@link KeyStroke} and execute the
 191  * action under specified conditions.
 192  * <p>
 193  * <strong>Warning:</strong> Swing is not thread safe. For more
 194  * information see <a
 195  * href="package-summary.html#threading">Swing's Threading
 196  * Policy</a>.
 197  * <p>
 198  * <strong>Warning:</strong>
 199  * Serialized objects of this class will not be compatible with
 200  * future Swing releases. The current serialization support is
 201  * appropriate for short term storage or RMI between applications running
 202  * the same version of Swing.  As of 1.4, support for long term storage
 203  * of all JavaBeans&trade;
 204  * has been added to the <code>java.beans</code> package.
 205  * Please see {@link java.beans.XMLEncoder}.
 206  *
 207  *
 208  * @beaninfo
 209  *   attribute: isContainer false
 210  * description: A component which displays data in a two dimensional grid.
 211  *
 212  * @author Philip Milne
 213  * @author Shannon Hickey (printing support)
 214  * @see javax.swing.table.DefaultTableModel
 215  * @see javax.swing.table.TableRowSorter
 216  * @since 1.2
 217  */
 218 /* The first versions of the JTable, contained in Swing-0.1 through
 219  * Swing-0.4, were written by Alan Chung.
 220  */


 221 @SuppressWarnings("serial") // Same-version serialization only
 222 public class JTable extends JComponent implements TableModelListener, Scrollable,
 223     TableColumnModelListener, ListSelectionListener, CellEditorListener,
 224     Accessible, RowSorterListener
 225 {
 226 //
 227 // Static Constants
 228 //
 229 
 230     /**
 231      * @see #getUIClassID
 232      * @see #readObject
 233      */
 234     private static final String uiClassID = "TableUI";
 235 
 236     /** Do not adjust column widths automatically; use a horizontal scrollbar instead. */
 237     public static final int     AUTO_RESIZE_OFF = 0;
 238 
 239     /** When a column is adjusted in the UI, adjust the next column the opposite way. */
 240     public static final int     AUTO_RESIZE_NEXT_COLUMN = 1;


 873      * @param aTable a {@code JTable} to be used for the scroll pane
 874      * @return a {@code JScrollPane} created using {@code aTable}
 875      * @deprecated As of Swing version 1.0.2,
 876      * replaced by <code>new JScrollPane(aTable)</code>.
 877      */
 878     @Deprecated
 879     static public JScrollPane createScrollPaneForTable(JTable aTable) {
 880         return new JScrollPane(aTable);
 881     }
 882 
 883 //
 884 // Table Attributes
 885 //
 886 
 887     /**
 888      * Sets the <code>tableHeader</code> working with this <code>JTable</code> to <code>newHeader</code>.
 889      * It is legal to have a <code>null</code> <code>tableHeader</code>.
 890      *
 891      * @param   tableHeader                       new tableHeader
 892      * @see     #getTableHeader
 893      * @beaninfo
 894      *  bound: true
 895      *  description: The JTableHeader instance which renders the column headers.
 896      */


 897     public void setTableHeader(JTableHeader tableHeader) {
 898         if (this.tableHeader != tableHeader) {
 899             JTableHeader old = this.tableHeader;
 900             // Release the old header
 901             if (old != null) {
 902                 old.setTable(null);
 903             }
 904             this.tableHeader = tableHeader;
 905             if (tableHeader != null) {
 906                 tableHeader.setTable(this);
 907             }
 908             firePropertyChange("tableHeader", old, tableHeader);
 909         }
 910     }
 911 
 912     /**
 913      * Returns the <code>tableHeader</code> used by this <code>JTable</code>.
 914      *
 915      * @return  the <code>tableHeader</code> used by this table
 916      * @see     #setTableHeader
 917      */
 918     public JTableHeader getTableHeader() {
 919         return tableHeader;
 920     }
 921 
 922     /**
 923      * Sets the height, in pixels, of all cells to <code>rowHeight</code>,
 924      * revalidates, and repaints.
 925      * The height of the cells will be equal to the row height minus
 926      * the row margin.
 927      *
 928      * @param   rowHeight                       new row height
 929      * @exception IllegalArgumentException      if <code>rowHeight</code> is
 930      *                                          less than 1
 931      * @see     #getRowHeight
 932      * @beaninfo
 933      *  bound: true
 934      *  description: The height of the specified row.
 935      */


 936     public void setRowHeight(int rowHeight) {
 937         if (rowHeight <= 0) {
 938             throw new IllegalArgumentException("New row height less than 1");
 939         }
 940         int old = this.rowHeight;
 941         this.rowHeight = rowHeight;
 942         rowModel = null;
 943         if (sortManager != null) {
 944             sortManager.modelRowSizes = null;
 945         }
 946         isRowHeightSet = true;
 947         resizeAndRepaint();
 948         firePropertyChange("rowHeight", old, rowHeight);
 949     }
 950 
 951     /**
 952      * Returns the height of a table row, in pixels.
 953      *
 954      * @return  the height in pixels of a table row
 955      * @see     #setRowHeight


 958         return rowHeight;
 959     }
 960 
 961     private SizeSequence getRowModel() {
 962         if (rowModel == null) {
 963             rowModel = new SizeSequence(getRowCount(), getRowHeight());
 964         }
 965         return rowModel;
 966     }
 967 
 968     /**
 969      * Sets the height for <code>row</code> to <code>rowHeight</code>,
 970      * revalidates, and repaints. The height of the cells in this row
 971      * will be equal to the row height minus the row margin.
 972      *
 973      * @param   row                             the row whose height is being
 974                                                 changed
 975      * @param   rowHeight                       new row height, in pixels
 976      * @exception IllegalArgumentException      if <code>rowHeight</code> is
 977      *                                          less than 1
 978      * @beaninfo
 979      *  bound: true
 980      *  description: The height in pixels of the cells in <code>row</code>
 981      * @since 1.3
 982      */


 983     public void setRowHeight(int row, int rowHeight) {
 984         if (rowHeight <= 0) {
 985             throw new IllegalArgumentException("New row height less than 1");
 986         }
 987         getRowModel().setSize(row, rowHeight);
 988         if (sortManager != null) {
 989             sortManager.setViewRowHeight(row, rowHeight);
 990         }
 991         resizeAndRepaint();
 992     }
 993 
 994     /**
 995      * Returns the height, in pixels, of the cells in <code>row</code>.
 996      * @param   row              the row whose height is to be returned
 997      * @return the height, in pixels, of the cells in the row
 998      * @since 1.3
 999      */
1000     public int getRowHeight(int row) {
1001         return (rowModel == null) ? getRowHeight() : rowModel.getSize(row);
1002     }
1003 
1004     /**
1005      * Sets the amount of empty space between cells in adjacent rows.
1006      *
1007      * @param  rowMargin  the number of pixels between cells in a row
1008      * @see     #getRowMargin
1009      * @beaninfo
1010      *  bound: true
1011      *  description: The amount of space between cells.
1012      */


1013     public void setRowMargin(int rowMargin) {
1014         int old = this.rowMargin;
1015         this.rowMargin = rowMargin;
1016         resizeAndRepaint();
1017         firePropertyChange("rowMargin", old, rowMargin);
1018     }
1019 
1020     /**
1021      * Gets the amount of empty space, in pixels, between cells. Equivalent to:
1022      * <code>getIntercellSpacing().height</code>.
1023      * @return the number of pixels between cells in a row
1024      *
1025      * @see     #setRowMargin
1026      */
1027     public int getRowMargin() {
1028         return rowMargin;
1029     }
1030 
1031     /**
1032      * Sets the <code>rowMargin</code> and the <code>columnMargin</code> --
1033      * the height and width of the space between cells -- to
1034      * <code>intercellSpacing</code>.
1035      *
1036      * @param   intercellSpacing        a <code>Dimension</code>
1037      *                                  specifying the new width
1038      *                                  and height between cells
1039      * @see     #getIntercellSpacing
1040      * @beaninfo
1041      *  description: The spacing between the cells,
1042      *               drawn in the background color of the JTable.
1043      */


1044     public void setIntercellSpacing(Dimension intercellSpacing) {
1045         // Set the rowMargin here and columnMargin in the TableColumnModel
1046         setRowMargin(intercellSpacing.height);
1047         getColumnModel().setColumnMargin(intercellSpacing.width);
1048 
1049         resizeAndRepaint();
1050     }
1051 
1052     /**
1053      * Returns the horizontal and vertical space between cells.
1054      * The default spacing is look and feel dependent.
1055      *
1056      * @return  the horizontal and vertical spacing between cells
1057      * @see     #setIntercellSpacing
1058      */
1059     public Dimension getIntercellSpacing() {
1060         return new Dimension(getColumnModel().getColumnMargin(), rowMargin);
1061     }
1062 
1063     /**
1064      * Sets the color used to draw grid lines to <code>gridColor</code> and redisplays.
1065      * The default color is look and feel dependent.
1066      *
1067      * @param   gridColor                       the new color of the grid lines
1068      * @exception IllegalArgumentException      if <code>gridColor</code> is <code>null</code>
1069      * @see     #getGridColor
1070      * @beaninfo
1071      *  bound: true
1072      *  description: The grid color.
1073      */


1074     public void setGridColor(Color gridColor) {
1075         if (gridColor == null) {
1076             throw new IllegalArgumentException("New color is null");
1077         }
1078         Color old = this.gridColor;
1079         this.gridColor = gridColor;
1080         firePropertyChange("gridColor", old, gridColor);
1081         // Redraw
1082         repaint();
1083     }
1084 
1085     /**
1086      * Returns the color used to draw grid lines.
1087      * The default color is look and feel dependent.
1088      *
1089      * @return  the color used to draw grid lines
1090      * @see     #setGridColor
1091      */
1092     public Color getGridColor() {
1093         return gridColor;
1094     }
1095 
1096     /**
1097      *  Sets whether the table draws grid lines around cells.
1098      *  If <code>showGrid</code> is true it does; if it is false it doesn't.
1099      *  There is no <code>getShowGrid</code> method as this state is held
1100      *  in two variables -- <code>showHorizontalLines</code> and <code>showVerticalLines</code> --
1101      *  each of which can be queried independently.
1102      *
1103      * @param   showGrid                 true if table view should draw grid lines
1104      *
1105      * @see     #setShowVerticalLines
1106      * @see     #setShowHorizontalLines
1107      * @beaninfo
1108      *  description: The color used to draw the grid lines.
1109      */


1110     public void setShowGrid(boolean showGrid) {
1111         setShowHorizontalLines(showGrid);
1112         setShowVerticalLines(showGrid);
1113 
1114         // Redraw
1115         repaint();
1116     }
1117 
1118     /**
1119      *  Sets whether the table draws horizontal lines between cells.
1120      *  If <code>showHorizontalLines</code> is true it does; if it is false it doesn't.
1121      *
1122      * @param   showHorizontalLines      true if table view should draw horizontal lines
1123      * @see     #getShowHorizontalLines
1124      * @see     #setShowGrid
1125      * @see     #setShowVerticalLines
1126      * @beaninfo
1127      *  bound: true
1128      *  description: Whether horizontal lines should be drawn in between the cells.
1129      */


1130     public void setShowHorizontalLines(boolean showHorizontalLines) {
1131         boolean old = this.showHorizontalLines;
1132         this.showHorizontalLines = showHorizontalLines;
1133         firePropertyChange("showHorizontalLines", old, showHorizontalLines);
1134 
1135         // Redraw
1136         repaint();
1137     }
1138 
1139     /**
1140      *  Sets whether the table draws vertical lines between cells.
1141      *  If <code>showVerticalLines</code> is true it does; if it is false it doesn't.
1142      *
1143      * @param   showVerticalLines              true if table view should draw vertical lines
1144      * @see     #getShowVerticalLines
1145      * @see     #setShowGrid
1146      * @see     #setShowHorizontalLines
1147      * @beaninfo
1148      *  bound: true
1149      *  description: Whether vertical lines should be drawn in between the cells.
1150      */


1151     public void setShowVerticalLines(boolean showVerticalLines) {
1152         boolean old = this.showVerticalLines;
1153         this.showVerticalLines = showVerticalLines;
1154         firePropertyChange("showVerticalLines", old, showVerticalLines);
1155         // Redraw
1156         repaint();
1157     }
1158 
1159     /**
1160      * Returns true if the table draws horizontal lines between cells, false if it
1161      * doesn't. The default value is look and feel dependent.
1162      *
1163      * @return  true if the table draws horizontal lines between cells, false if it
1164      *          doesn't
1165      * @see     #setShowHorizontalLines
1166      */
1167     public boolean getShowHorizontalLines() {
1168         return showHorizontalLines;
1169     }
1170 


1177      * @see     #setShowVerticalLines
1178      */
1179     public boolean getShowVerticalLines() {
1180         return showVerticalLines;
1181     }
1182 
1183     /**
1184      * Sets the table's auto resize mode when the table is resized.  For further
1185      * information on how the different resize modes work, see
1186      * {@link #doLayout}.
1187      *
1188      * @param   mode One of 5 legal values:
1189      *                   AUTO_RESIZE_OFF,
1190      *                   AUTO_RESIZE_NEXT_COLUMN,
1191      *                   AUTO_RESIZE_SUBSEQUENT_COLUMNS,
1192      *                   AUTO_RESIZE_LAST_COLUMN,
1193      *                   AUTO_RESIZE_ALL_COLUMNS
1194      *
1195      * @see     #getAutoResizeMode
1196      * @see     #doLayout
1197      * @beaninfo
1198      *  bound: true
1199      *  description: Whether the columns should adjust themselves automatically.
1200      *        enum: AUTO_RESIZE_OFF                JTable.AUTO_RESIZE_OFF
1201      *              AUTO_RESIZE_NEXT_COLUMN        JTable.AUTO_RESIZE_NEXT_COLUMN
1202      *              AUTO_RESIZE_SUBSEQUENT_COLUMNS JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS
1203      *              AUTO_RESIZE_LAST_COLUMN        JTable.AUTO_RESIZE_LAST_COLUMN
1204      *              AUTO_RESIZE_ALL_COLUMNS        JTable.AUTO_RESIZE_ALL_COLUMNS
1205      */







1206     public void setAutoResizeMode(int mode) {
1207         if (isValidAutoResizeMode(mode)) {
1208             int old = autoResizeMode;
1209             autoResizeMode = mode;
1210             resizeAndRepaint();
1211             if (tableHeader != null) {
1212                 tableHeader.resizeAndRepaint();
1213             }
1214             firePropertyChange("autoResizeMode", old, autoResizeMode);
1215         }
1216     }
1217 
1218     private static boolean isValidAutoResizeMode(int mode) {
1219         return (mode == AUTO_RESIZE_OFF)
1220                 || (mode == AUTO_RESIZE_NEXT_COLUMN)
1221                 || (mode == AUTO_RESIZE_SUBSEQUENT_COLUMNS)
1222                 || (mode == AUTO_RESIZE_LAST_COLUMN)
1223                 || (mode == AUTO_RESIZE_ALL_COLUMNS);
1224     }
1225 


1227      * Returns the auto resize mode of the table.  The default mode
1228      * is AUTO_RESIZE_SUBSEQUENT_COLUMNS.
1229      *
1230      * @return  the autoResizeMode of the table
1231      *
1232      * @see     #setAutoResizeMode
1233      * @see     #doLayout
1234      */
1235     public int getAutoResizeMode() {
1236         return autoResizeMode;
1237     }
1238 
1239     /**
1240      * Sets this table's <code>autoCreateColumnsFromModel</code> flag.
1241      * This method calls <code>createDefaultColumnsFromModel</code> if
1242      * <code>autoCreateColumnsFromModel</code> changes from false to true.
1243      *
1244      * @param   autoCreateColumnsFromModel   true if <code>JTable</code> should automatically create columns
1245      * @see     #getAutoCreateColumnsFromModel
1246      * @see     #createDefaultColumnsFromModel
1247      * @beaninfo
1248      *  bound: true
1249      *  description: Automatically populates the columnModel when a new TableModel is submitted.
1250      */


1251     public void setAutoCreateColumnsFromModel(boolean autoCreateColumnsFromModel) {
1252         if (this.autoCreateColumnsFromModel != autoCreateColumnsFromModel) {
1253             boolean old = this.autoCreateColumnsFromModel;
1254             this.autoCreateColumnsFromModel = autoCreateColumnsFromModel;
1255             if (autoCreateColumnsFromModel) {
1256                 createDefaultColumnsFromModel();
1257             }
1258             firePropertyChange("autoCreateColumnsFromModel", old, autoCreateColumnsFromModel);
1259         }
1260     }
1261 
1262     /**
1263      * Determines whether the table will create default columns from the model.
1264      * If true, <code>setModel</code> will clear any existing columns and
1265      * create new columns from the new model.  Also, if the event in
1266      * the <code>tableChanged</code> notification specifies that the
1267      * entire table changed, then the columns will be rebuilt.
1268      * The default is true.
1269      *
1270      * @return  the autoCreateColumnsFromModel of the table


1421      * feels (including those that subclass {@code BasicLookAndFeel}) begin a
1422      * drag and drop operation whenever the user presses the mouse button over
1423      * an item (in single selection mode) or a selection (in other selection
1424      * modes) and then moves the mouse a few pixels. Setting this property to
1425      * {@code true} can therefore have a subtle effect on how selections behave.
1426      * <p>
1427      * If a look and feel is used that ignores this property, you can still
1428      * begin a drag and drop operation by calling {@code exportAsDrag} on the
1429      * table's {@code TransferHandler}.
1430      *
1431      * @param b whether or not to enable automatic drag handling
1432      * @exception HeadlessException if
1433      *            <code>b</code> is <code>true</code> and
1434      *            <code>GraphicsEnvironment.isHeadless()</code>
1435      *            returns <code>true</code>
1436      * @see java.awt.GraphicsEnvironment#isHeadless
1437      * @see #getDragEnabled
1438      * @see #setTransferHandler
1439      * @see TransferHandler
1440      * @since 1.4
1441      *
1442      * @beaninfo
1443      *  description: determines whether automatic drag handling is enabled
1444      *        bound: false
1445      */


1446     public void setDragEnabled(boolean b) {
1447         checkDragEnabled(b);
1448         dragEnabled = b;
1449     }
1450 
1451     private void checkDragEnabled(boolean b) {
1452         if (b && GraphicsEnvironment.isHeadless()) {
1453             throw new HeadlessException();
1454         }
1455     }
1456 
1457     /**
1458      * Returns whether or not automatic drag handling is enabled.
1459      *
1460      * @return the value of the {@code dragEnabled} property
1461      * @see #setDragEnabled
1462      * @since 1.4
1463      */
1464     public boolean getDragEnabled() {
1465         return dragEnabled;


1813     }
1814 
1815     /**
1816      * Returns the location that this component should visually indicate
1817      * as the drop location during a DnD operation over the component,
1818      * or {@code null} if no location is to currently be shown.
1819      * <p>
1820      * This method is not meant for querying the drop location
1821      * from a {@code TransferHandler}, as the drop location is only
1822      * set after the {@code TransferHandler}'s <code>canImport</code>
1823      * has returned and has allowed for the location to be shown.
1824      * <p>
1825      * When this property changes, a property change event with
1826      * name "dropLocation" is fired by the component.
1827      *
1828      * @return the drop location
1829      * @see #setDropMode
1830      * @see TransferHandler#canImport(TransferHandler.TransferSupport)
1831      * @since 1.6
1832      */

1833     public final DropLocation getDropLocation() {
1834         return dropLocation;
1835     }
1836 
1837     /**
1838      * Specifies whether a {@code RowSorter} should be created for the
1839      * table whenever its model changes.
1840      * <p>
1841      * When {@code setAutoCreateRowSorter(true)} is invoked, a {@code
1842      * TableRowSorter} is immediately created and installed on the
1843      * table.  While the {@code autoCreateRowSorter} property remains
1844      * {@code true}, every time the model is changed, a new {@code
1845      * TableRowSorter} is created and set as the table's row sorter.
1846      * The default value for the {@code autoCreateRowSorter}
1847      * property is {@code false}.
1848      *
1849      * @param autoCreateRowSorter whether or not a {@code RowSorter}
1850      *        should be automatically created
1851      * @see javax.swing.table.TableRowSorter
1852      * @beaninfo
1853      *        bound: true
1854      *    preferred: true
1855      *  description: Whether or not to turn on sorting by default.
1856      * @since 1.6
1857      */


1858     public void setAutoCreateRowSorter(boolean autoCreateRowSorter) {
1859         boolean oldValue = this.autoCreateRowSorter;
1860         this.autoCreateRowSorter = autoCreateRowSorter;
1861         if (autoCreateRowSorter) {
1862             setRowSorter(new TableRowSorter<TableModel>(getModel()));
1863         }
1864         firePropertyChange("autoCreateRowSorter", oldValue,
1865                            autoCreateRowSorter);
1866     }
1867 
1868     /**
1869      * Returns {@code true} if whenever the model changes, a new
1870      * {@code RowSorter} should be created and installed
1871      * as the table's sorter; otherwise, returns {@code false}.
1872      *
1873      * @return true if a {@code RowSorter} should be created when
1874      *         the model changes
1875      * @since 1.6
1876      */
1877     public boolean getAutoCreateRowSorter() {
1878         return autoCreateRowSorter;
1879     }
1880 
1881     /**
1882      * Specifies whether the selection should be updated after sorting.
1883      * If true, on sorting the selection is reset such that
1884      * the same rows, in terms of the model, remain selected.  The default
1885      * is true.
1886      *
1887      * @param update whether or not to update the selection on sorting
1888      * @beaninfo
1889      *        bound: true
1890      *       expert: true
1891      *  description: Whether or not to update the selection on sorting
1892      * @since 1.6
1893      */


1894     public void setUpdateSelectionOnSort(boolean update) {
1895         if (updateSelectionOnSort != update) {
1896             updateSelectionOnSort = update;
1897             firePropertyChange("updateSelectionOnSort", !update, update);
1898         }
1899     }
1900 
1901     /**
1902      * Returns true if the selection should be updated after sorting.
1903      *
1904      * @return whether to update the selection on a sort
1905      * @since 1.6
1906      */
1907     public boolean getUpdateSelectionOnSort() {
1908         return updateSelectionOnSort;
1909     }
1910 
1911     /**
1912      * Sets the <code>RowSorter</code>.  <code>RowSorter</code> is used
1913      * to provide sorting and filtering to a <code>JTable</code>.
1914      * <p>
1915      * This method clears the selection and resets any variable row heights.
1916      * <p>
1917      * This method fires a <code>PropertyChangeEvent</code> when appropriate,
1918      * with the property name <code>"rowSorter"</code>.  For
1919      * backward-compatibility, this method fires an additional event with the
1920      * property name <code>"sorter"</code>.
1921      * <p>
1922      * If the underlying model of the <code>RowSorter</code> differs from
1923      * that of this <code>JTable</code> undefined behavior will result.
1924      *
1925      * @param sorter the <code>RowSorter</code>; <code>null</code> turns
1926      *        sorting off
1927      * @see javax.swing.table.TableRowSorter
1928      * @beaninfo
1929      *        bound: true
1930      *  description: The table's RowSorter
1931      * @since 1.6
1932      */


1933     public void setRowSorter(RowSorter<? extends TableModel> sorter) {
1934         RowSorter<? extends TableModel> oldRowSorter = null;
1935         if (sortManager != null) {
1936             oldRowSorter = sortManager.sorter;
1937             sortManager.dispose();
1938             sortManager = null;
1939         }
1940         rowModel = null;
1941         clearSelectionAndLeadAnchor();
1942         if (sorter != null) {
1943             sortManager = new SortManager(sorter);
1944         }
1945         resizeAndRepaint();
1946         firePropertyChange("rowSorter", oldRowSorter, sorter);
1947         firePropertyChange("sorter", oldRowSorter, sorter);
1948     }
1949 
1950     /**
1951      * Returns the object responsible for sorting.
1952      *


1964      * Sets the table's selection mode to allow only single selections, a single
1965      * contiguous interval, or multiple intervals.
1966      * <P>
1967      * <b>Note:</b>
1968      * <code>JTable</code> provides all the methods for handling
1969      * column and row selection.  When setting states,
1970      * such as <code>setSelectionMode</code>, it not only
1971      * updates the mode for the row selection model but also sets similar
1972      * values in the selection model of the <code>columnModel</code>.
1973      * If you want to have the row and column selection models operating
1974      * in different modes, set them both directly.
1975      * <p>
1976      * Both the row and column selection models for <code>JTable</code>
1977      * default to using a <code>DefaultListSelectionModel</code>
1978      * so that <code>JTable</code> works the same way as the
1979      * <code>JList</code>. See the <code>setSelectionMode</code> method
1980      * in <code>JList</code> for details about the modes.
1981      *
1982      * @param selectionMode the mode used by the row and column selection models
1983      * @see JList#setSelectionMode
1984      * @beaninfo
1985      * description: The selection mode used by the row and column selection models.
1986      *        enum: SINGLE_SELECTION            ListSelectionModel.SINGLE_SELECTION
1987      *              SINGLE_INTERVAL_SELECTION   ListSelectionModel.SINGLE_INTERVAL_SELECTION
1988      *              MULTIPLE_INTERVAL_SELECTION ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
1989      */





1990     public void setSelectionMode(int selectionMode) {
1991         clearSelection();
1992         getSelectionModel().setSelectionMode(selectionMode);
1993         getColumnModel().getSelectionModel().setSelectionMode(selectionMode);
1994     }
1995 
1996     /**
1997      * Sets whether the rows in this model can be selected.
1998      *
1999      * @param rowSelectionAllowed   true if this model will allow row selection
2000      * @see #getRowSelectionAllowed
2001      * @beaninfo
2002      *  bound: true
2003      *    attribute: visualUpdate true
2004      *  description: If true, an entire row is selected for each selected cell.
2005      */


2006     public void setRowSelectionAllowed(boolean rowSelectionAllowed) {
2007         boolean old = this.rowSelectionAllowed;
2008         this.rowSelectionAllowed = rowSelectionAllowed;
2009         if (old != rowSelectionAllowed) {
2010             repaint();
2011         }
2012         firePropertyChange("rowSelectionAllowed", old, rowSelectionAllowed);
2013     }
2014 
2015     /**
2016      * Returns true if rows can be selected.
2017      *
2018      * @return true if rows can be selected, otherwise false
2019      * @see #setRowSelectionAllowed
2020      */
2021     public boolean getRowSelectionAllowed() {
2022         return rowSelectionAllowed;
2023     }
2024 
2025     /**
2026      * Sets whether the columns in this model can be selected.
2027      *
2028      * @param columnSelectionAllowed   true if this model will allow column selection
2029      * @see #getColumnSelectionAllowed
2030      * @beaninfo
2031      *  bound: true
2032      *    attribute: visualUpdate true
2033      *  description: If true, an entire column is selected for each selected cell.
2034      */


2035     public void setColumnSelectionAllowed(boolean columnSelectionAllowed) {
2036         boolean old = columnModel.getColumnSelectionAllowed();
2037         columnModel.setColumnSelectionAllowed(columnSelectionAllowed);
2038         if (old != columnSelectionAllowed) {
2039             repaint();
2040         }
2041         firePropertyChange("columnSelectionAllowed", old, columnSelectionAllowed);
2042     }
2043 
2044     /**
2045      * Returns true if columns can be selected.
2046      *
2047      * @return true if columns can be selected, otherwise false
2048      * @see #setColumnSelectionAllowed
2049      */
2050     public boolean getColumnSelectionAllowed() {
2051         return columnModel.getColumnSelectionAllowed();
2052     }
2053 
2054     /**
2055      * Sets whether this table allows both a column selection and a
2056      * row selection to exist simultaneously. When set,
2057      * the table treats the intersection of the row and column selection
2058      * models as the selected cells. Override <code>isCellSelected</code> to
2059      * change this default behavior. This method is equivalent to setting
2060      * both the <code>rowSelectionAllowed</code> property and
2061      * <code>columnSelectionAllowed</code> property of the
2062      * <code>columnModel</code> to the supplied value.
2063      *
2064      * @param  cellSelectionEnabled     true if simultaneous row and column
2065      *                                  selection is allowed
2066      * @see #getCellSelectionEnabled
2067      * @see #isCellSelected
2068      * @beaninfo
2069      *  bound: true
2070      *    attribute: visualUpdate true
2071      *  description: Select a rectangular region of cells rather than
2072      *               rows or columns.
2073      */


2074     public void setCellSelectionEnabled(boolean cellSelectionEnabled) {
2075         setRowSelectionAllowed(cellSelectionEnabled);
2076         setColumnSelectionAllowed(cellSelectionEnabled);
2077         boolean old = this.cellSelectionEnabled;
2078         this.cellSelectionEnabled = cellSelectionEnabled;
2079         firePropertyChange("cellSelectionEnabled", old, cellSelectionEnabled);
2080     }
2081 
2082     /**
2083      * Returns true if both row and column selection models are enabled.
2084      * Equivalent to <code>getRowSelectionAllowed() &amp;&amp;
2085      * getColumnSelectionAllowed()</code>.
2086      *
2087      * @return true if both row and column selection models are enabled
2088      *
2089      * @see #setCellSelectionEnabled
2090      */
2091     public boolean getCellSelectionEnabled() {
2092         return getRowSelectionAllowed() && getColumnSelectionAllowed();
2093     }


2241         selectionModel.removeSelectionInterval(boundRow(index0), boundRow(index1));
2242     }
2243 
2244     /**
2245      * Deselects the columns from <code>index0</code> to <code>index1</code>, inclusive.
2246      *
2247      * @exception IllegalArgumentException      if <code>index0</code> or
2248      *                                          <code>index1</code> lie outside
2249      *                                          [0, <code>getColumnCount()</code>-1]
2250      * @param   index0 one end of the interval
2251      * @param   index1 the other end of the interval
2252      */
2253     public void removeColumnSelectionInterval(int index0, int index1) {
2254         columnModel.getSelectionModel().removeSelectionInterval(boundColumn(index0), boundColumn(index1));
2255     }
2256 
2257     /**
2258      * Returns the index of the first selected row, -1 if no row is selected.
2259      * @return the index of the first selected row
2260      */

2261     public int getSelectedRow() {
2262         return selectionModel.getMinSelectionIndex();
2263     }
2264 
2265     /**
2266      * Returns the index of the first selected column,
2267      * -1 if no column is selected.
2268      * @return the index of the first selected column
2269      */

2270     public int getSelectedColumn() {
2271         return columnModel.getSelectionModel().getMinSelectionIndex();
2272     }
2273 
2274     /**
2275      * Returns the indices of all selected rows.
2276      *
2277      * @return an array of integers containing the indices of all selected rows,
2278      *         or an empty array if no row is selected
2279      * @see #getSelectedRow
2280      */

2281     public int[] getSelectedRows() {
2282         int iMin = selectionModel.getMinSelectionIndex();
2283         int iMax = selectionModel.getMaxSelectionIndex();
2284 
2285         if ((iMin == -1) || (iMax == -1)) {
2286             return new int[0];
2287         }
2288 
2289         int[] rvTmp = new int[1+ (iMax - iMin)];
2290         int n = 0;
2291         for(int i = iMin; i <= iMax; i++) {
2292             if (selectionModel.isSelectedIndex(i)) {
2293                 rvTmp[n++] = i;
2294             }
2295         }
2296         int[] rv = new int[n];
2297         System.arraycopy(rvTmp, 0, rv, 0, n);
2298         return rv;
2299     }
2300 
2301     /**
2302      * Returns the indices of all selected columns.
2303      *
2304      * @return an array of integers containing the indices of all selected columns,
2305      *         or an empty array if no column is selected
2306      * @see #getSelectedColumn
2307      */

2308     public int[] getSelectedColumns() {
2309         return columnModel.getSelectedColumns();
2310     }
2311 
2312     /**
2313      * Returns the number of selected rows.
2314      *
2315      * @return the number of selected rows, 0 if no rows are selected
2316      */

2317     public int getSelectedRowCount() {
2318         int iMin = selectionModel.getMinSelectionIndex();
2319         int iMax = selectionModel.getMaxSelectionIndex();
2320         int count = 0;
2321 
2322         for(int i = iMin; i <= iMax; i++) {
2323             if (selectionModel.isSelectedIndex(i)) {
2324                 count++;
2325             }
2326         }
2327         return count;
2328     }
2329 
2330     /**
2331      * Returns the number of selected columns.
2332      *
2333      * @return the number of selected columns, 0 if no columns are selected
2334      */

2335     public int getSelectedColumnCount() {
2336         return columnModel.getSelectedColumnCount();
2337     }
2338 
2339     /**
2340      * Returns true if the specified index is in the valid range of rows,
2341      * and the row at that index is selected.
2342      *
2343      * @param row a row in the row model
2344      * @return true if <code>row</code> is a valid index and the row at
2345      *              that index is selected (where 0 is the first row)
2346      */
2347     public boolean isRowSelected(int row) {
2348         return selectionModel.isSelectedIndex(row);
2349     }
2350 
2351     /**
2352      * Returns true if the specified index is in the valid range of columns,
2353      * and the column at that index is selected.
2354      *


2502         return selectionForeground;
2503     }
2504 
2505     /**
2506      * Sets the foreground color for selected cells.  Cell renderers
2507      * can use this color to render text and graphics for selected
2508      * cells.
2509      * <p>
2510      * The default value of this property is defined by the look
2511      * and feel implementation.
2512      * <p>
2513      * This is a <a href="http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html">JavaBeans</a> bound property.
2514      *
2515      * @param selectionForeground  the <code>Color</code> to use in the foreground
2516      *                             for selected list items
2517      * @see #getSelectionForeground
2518      * @see #setSelectionBackground
2519      * @see #setForeground
2520      * @see #setBackground
2521      * @see #setFont
2522      * @beaninfo
2523      *       bound: true
2524      * description: A default foreground color for selected cells.
2525      */


2526     public void setSelectionForeground(Color selectionForeground) {
2527         Color old = this.selectionForeground;
2528         this.selectionForeground = selectionForeground;
2529         firePropertyChange("selectionForeground", old, selectionForeground);
2530         repaint();
2531     }
2532 
2533     /**
2534      * Returns the background color for selected cells.
2535      *
2536      * @return the <code>Color</code> used for the background of selected list items
2537      * @see #setSelectionBackground
2538      * @see #setSelectionForeground
2539      */
2540     public Color getSelectionBackground() {
2541         return selectionBackground;
2542     }
2543 
2544     /**
2545      * Sets the background color for selected cells.  Cell renderers
2546      * can use this color to the fill selected cells.
2547      * <p>
2548      * The default value of this property is defined by the look
2549      * and feel implementation.
2550      * <p>
2551      * This is a <a href="http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html">JavaBeans</a> bound property.
2552      *
2553      * @param selectionBackground  the <code>Color</code> to use for the background
2554      *                             of selected cells
2555      * @see #getSelectionBackground
2556      * @see #setSelectionForeground
2557      * @see #setForeground
2558      * @see #setBackground
2559      * @see #setFont
2560      * @beaninfo
2561      *       bound: true
2562      * description: A default background color for selected cells.
2563      */


2564     public void setSelectionBackground(Color selectionBackground) {
2565         Color old = this.selectionBackground;
2566         this.selectionBackground = selectionBackground;
2567         firePropertyChange("selectionBackground", old, selectionBackground);
2568         repaint();
2569     }
2570 
2571     /**
2572      * Returns the <code>TableColumn</code> object for the column in the table
2573      * whose identifier is equal to <code>identifier</code>, when compared using
2574      * <code>equals</code>.
2575      *
2576      * @return  the <code>TableColumn</code> object that matches the identifier
2577      * @exception IllegalArgumentException      if <code>identifier</code> is <code>null</code> or no <code>TableColumn</code> has this identifier
2578      *
2579      * @param   identifier                      the identifier object
2580      */
2581     public TableColumn getColumn(Object identifier) {
2582         TableColumnModel cm = getColumnModel();
2583         int columnIndex = cm.getColumnIndex(identifier);


2659      * @since 1.6
2660      */
2661     public int convertRowIndexToModel(int viewRowIndex) {
2662         RowSorter<?> sorter = getRowSorter();
2663         if (sorter != null) {
2664             return sorter.convertRowIndexToModel(viewRowIndex);
2665         }
2666         return viewRowIndex;
2667     }
2668 
2669     /**
2670      * Returns the number of rows that can be shown in the
2671      * <code>JTable</code>, given unlimited space.  If a
2672      * <code>RowSorter</code> with a filter has been specified, the
2673      * number of rows returned may differ from that of the underlying
2674      * <code>TableModel</code>.
2675      *
2676      * @return the number of rows shown in the <code>JTable</code>
2677      * @see #getColumnCount
2678      */

2679     public int getRowCount() {
2680         RowSorter<?> sorter = getRowSorter();
2681         if (sorter != null) {
2682             return sorter.getViewRowCount();
2683         }
2684         return getModel().getRowCount();
2685     }
2686 
2687     /**
2688      * Returns the number of columns in the column model. Note that this may
2689      * be different from the number of columns in the table model.
2690      *
2691      * @return  the number of columns in the table
2692      * @see #getRowCount
2693      * @see #removeColumn
2694      */

2695     public int getColumnCount() {
2696         return getColumnModel().getColumnCount();
2697     }
2698 
2699     /**
2700      * Returns the name of the column appearing in the view at
2701      * column position <code>column</code>.
2702      *
2703      * @param  column    the column in the view being queried
2704      * @return the name of the column at position <code>column</code>
2705                         in the view where the first column is column 0
2706      */
2707     public String getColumnName(int column) {
2708         return getModel().getColumnName(convertColumnIndexToModel(column));
2709     }
2710 
2711     /**
2712      * Returns the type of the column appearing in the view at
2713      * column position <code>column</code>.
2714      *


3543             editorComp.validate();
3544             editorComp.repaint();
3545 
3546             setCellEditor(editor);
3547             setEditingRow(row);
3548             setEditingColumn(column);
3549             editor.addCellEditorListener(this);
3550 
3551             return true;
3552         }
3553         return false;
3554     }
3555 
3556     /**
3557      * Returns true if a cell is being edited.
3558      *
3559      * @return  true if the table is editing a cell
3560      * @see     #editingColumn
3561      * @see     #editingRow
3562      */

3563     public boolean isEditing() {
3564         return cellEditor != null;
3565     }
3566 
3567     /**
3568      * Returns the component that is handling the editing session.
3569      * If nothing is being edited, returns null.
3570      *
3571      * @return  Component handling editing session
3572      */

3573     public Component getEditorComponent() {
3574         return editorComp;
3575     }
3576 
3577     /**
3578      * Returns the index of the column that contains the cell currently
3579      * being edited.  If nothing is being edited, returns -1.
3580      *
3581      * @return  the index of the column that contains the cell currently
3582      *          being edited; returns -1 if nothing being edited
3583      * @see #editingRow
3584      */
3585     public int getEditingColumn() {
3586         return editingColumn;
3587     }
3588 
3589     /**
3590      * Returns the index of the row that contains the cell currently
3591      * being edited.  If nothing is being edited, returns -1.
3592      *


3599     }
3600 
3601 //
3602 // Managing TableUI
3603 //
3604 
3605     /**
3606      * Returns the L&amp;F object that renders this component.
3607      *
3608      * @return the <code>TableUI</code> object that renders this component
3609      */
3610     public TableUI getUI() {
3611         return (TableUI)ui;
3612     }
3613 
3614     /**
3615      * Sets the L&amp;F object that renders this component and repaints.
3616      *
3617      * @param ui  the TableUI L&amp;F object
3618      * @see UIDefaults#getUI
3619      * @beaninfo
3620      *        bound: true
3621      *       hidden: true
3622      *    attribute: visualUpdate true
3623      *  description: The UI object that implements the Component's LookAndFeel.
3624      */


3625     public void setUI(TableUI ui) {
3626         if (this.ui != ui) {
3627             super.setUI(ui);
3628             repaint();
3629         }
3630     }
3631 
3632     /**
3633      * Notification from the <code>UIManager</code> that the L&amp;F has changed.
3634      * Replaces the current UI object with the latest version from the
3635      * <code>UIManager</code>.
3636      *
3637      * @see JComponent#updateUI
3638      */
3639     public void updateUI() {
3640         // Update the UIs of the cell renderers, cell editors and header renderers.
3641         TableColumnModel cm = getColumnModel();
3642         for(int column = 0; column < cm.getColumnCount(); column++) {
3643             TableColumn aColumn = cm.getColumn(column);
3644             SwingUtilities.updateRendererOrEditorUI(aColumn.getCellRenderer());


3660 
3661         // Update the UI of the table header
3662         if (tableHeader != null && tableHeader.getParent() == null) {
3663             tableHeader.updateUI();
3664         }
3665 
3666         // Update UI applied to parent ScrollPane
3667         configureEnclosingScrollPaneUI();
3668 
3669         setUI((TableUI)UIManager.getUI(this));
3670     }
3671 
3672     /**
3673      * Returns the suffix used to construct the name of the L&amp;F class used to
3674      * render this component.
3675      *
3676      * @return the string "TableUI"
3677      * @see JComponent#getUIClassID
3678      * @see UIDefaults#getUI
3679      */

3680     public String getUIClassID() {
3681         return uiClassID;
3682     }
3683 
3684 
3685 //
3686 // Managing models
3687 //
3688 
3689     /**
3690      * Sets the data model for this table to <code>newModel</code> and registers
3691      * with it for listener notifications from the new data model.
3692      *
3693      * @param   dataModel        the new data source for this table
3694      * @exception IllegalArgumentException      if <code>newModel</code> is <code>null</code>
3695      * @see     #getModel
3696      * @beaninfo
3697      *  bound: true
3698      *  description: The model that is the source of the data for this view.
3699      */


3700     public void setModel(TableModel dataModel) {
3701         if (dataModel == null) {
3702             throw new IllegalArgumentException("Cannot set a null TableModel");
3703         }
3704         if (this.dataModel != dataModel) {
3705             TableModel old = this.dataModel;
3706             if (old != null) {
3707                 old.removeTableModelListener(this);
3708             }
3709             this.dataModel = dataModel;
3710             dataModel.addTableModelListener(this);
3711 
3712             tableChanged(new TableModelEvent(dataModel, TableModelEvent.HEADER_ROW));
3713 
3714             firePropertyChange("model", old, dataModel);
3715 
3716             if (getAutoCreateRowSorter()) {
3717                 setRowSorter(new TableRowSorter<TableModel>(dataModel));
3718             }
3719         }


3721 
3722     /**
3723      * Returns the <code>TableModel</code> that provides the data displayed by this
3724      * <code>JTable</code>.
3725      *
3726      * @return  the <code>TableModel</code> that provides the data displayed by this <code>JTable</code>
3727      * @see     #setModel
3728      */
3729     public TableModel getModel() {
3730         return dataModel;
3731     }
3732 
3733     /**
3734      * Sets the column model for this table to <code>newModel</code> and registers
3735      * for listener notifications from the new column model. Also sets
3736      * the column model of the <code>JTableHeader</code> to <code>columnModel</code>.
3737      *
3738      * @param   columnModel        the new data source for this table
3739      * @exception IllegalArgumentException      if <code>columnModel</code> is <code>null</code>
3740      * @see     #getColumnModel
3741      * @beaninfo
3742      *  bound: true
3743      *  description: The object governing the way columns appear in the view.
3744      */


3745     public void setColumnModel(TableColumnModel columnModel) {
3746         if (columnModel == null) {
3747             throw new IllegalArgumentException("Cannot set a null ColumnModel");
3748         }
3749         TableColumnModel old = this.columnModel;
3750         if (columnModel != old) {
3751             if (old != null) {
3752                 old.removeColumnModelListener(this);
3753             }
3754             this.columnModel = columnModel;
3755             columnModel.addColumnModelListener(this);
3756 
3757             // Set the column model of the header as well.
3758             if (tableHeader != null) {
3759                 tableHeader.setColumnModel(columnModel);
3760             }
3761 
3762             firePropertyChange("columnModel", old, columnModel);
3763             resizeAndRepaint();
3764         }
3765     }
3766 
3767     /**
3768      * Returns the <code>TableColumnModel</code> that contains all column information
3769      * of this table.
3770      *
3771      * @return  the object that provides the column state of the table
3772      * @see     #setColumnModel
3773      */
3774     public TableColumnModel getColumnModel() {
3775         return columnModel;
3776     }
3777 
3778     /**
3779      * Sets the row selection model for this table to <code>newModel</code>
3780      * and registers for listener notifications from the new selection model.
3781      *
3782      * @param   newModel        the new selection model
3783      * @exception IllegalArgumentException      if <code>newModel</code> is <code>null</code>
3784      * @see     #getSelectionModel
3785      * @beaninfo
3786      *      bound: true
3787      *      description: The selection model for rows.
3788      */


3789     public void setSelectionModel(ListSelectionModel newModel) {
3790         if (newModel == null) {
3791             throw new IllegalArgumentException("Cannot set a null SelectionModel");
3792         }
3793 
3794         ListSelectionModel oldModel = selectionModel;
3795 
3796         if (newModel != oldModel) {
3797             if (oldModel != null) {
3798                 oldModel.removeListSelectionListener(this);
3799             }
3800 
3801             selectionModel = newModel;
3802             newModel.addListSelectionListener(this);
3803 
3804             firePropertyChange("selectionModel", oldModel, newModel);
3805             repaint();
3806         }
3807     }
3808 


4756      * Application code will not use these methods explicitly, they
4757      * are used internally by JTable.
4758      *
4759      * @param  e  the event received
4760      * @see CellEditorListener
4761      */
4762     public void editingCanceled(ChangeEvent e) {
4763         removeEditor();
4764     }
4765 
4766 //
4767 // Implementing the Scrollable interface
4768 //
4769 
4770     /**
4771      * Sets the preferred size of the viewport for this table.
4772      *
4773      * @param size  a <code>Dimension</code> object specifying the <code>preferredSize</code> of a
4774      *              <code>JViewport</code> whose view is this table
4775      * @see Scrollable#getPreferredScrollableViewportSize
4776      * @beaninfo
4777      * description: The preferred size of the viewport.
4778      */


4779     public void setPreferredScrollableViewportSize(Dimension size) {
4780         preferredViewportSize = size;
4781     }
4782 
4783     /**
4784      * Returns the preferred size of the viewport for this table.
4785      *
4786      * @return a <code>Dimension</code> object containing the <code>preferredSize</code> of the <code>JViewport</code>
4787      *         which displays this table
4788      * @see Scrollable#getPreferredScrollableViewportSize
4789      */
4790     public Dimension getPreferredScrollableViewportSize() {
4791         return preferredViewportSize;
4792     }
4793 
4794     /**
4795      * Returns the scroll increment (in pixels) that completely exposes one new
4796      * row or column (depending on the orientation).
4797      * <p>
4798      * This method is called each time the user requests a unit scroll.


5194             return rect.y + rect.height;
5195         }
5196         else if (getComponentOrientation().isLeftToRight()) {
5197             return rect.x + rect.width;
5198         }
5199         else { // Horizontal, right-to-left
5200             return rect.x;
5201         }
5202     }
5203 
5204     /**
5205      * Returns false if <code>autoResizeMode</code> is set to
5206      * <code>AUTO_RESIZE_OFF</code>, which indicates that the
5207      * width of the viewport does not determine the width
5208      * of the table.  Otherwise returns true.
5209      *
5210      * @return false if <code>autoResizeMode</code> is set
5211      *   to <code>AUTO_RESIZE_OFF</code>, otherwise returns true
5212      * @see Scrollable#getScrollableTracksViewportWidth
5213      */

5214     public boolean getScrollableTracksViewportWidth() {
5215         return !(autoResizeMode == AUTO_RESIZE_OFF);
5216     }
5217 
5218     /**
5219      * Returns {@code false} to indicate that the height of the viewport does
5220      * not determine the height of the table, unless
5221      * {@code getFillsViewportHeight} is {@code true} and the preferred height
5222      * of the table is smaller than the viewport's height.
5223      *
5224      * @return {@code false} unless {@code getFillsViewportHeight} is
5225      *         {@code true} and the table needs to be stretched to fill
5226      *         the viewport
5227      * @see Scrollable#getScrollableTracksViewportHeight
5228      * @see #setFillsViewportHeight
5229      * @see #getFillsViewportHeight
5230      */

5231     public boolean getScrollableTracksViewportHeight() {
5232         Container parent = SwingUtilities.getUnwrappedParent(this);
5233         return getFillsViewportHeight()
5234                && parent instanceof JViewport
5235                && parent.getHeight() > getPreferredSize().height;
5236     }
5237 
5238     /**
5239      * Sets whether or not this table is always made large enough
5240      * to fill the height of an enclosing viewport. If the preferred
5241      * height of the table is smaller than the viewport, then the table
5242      * will be stretched to fill the viewport. In other words, this
5243      * ensures the table is never smaller than the viewport.
5244      * The default for this property is {@code false}.
5245      *
5246      * @param fillsViewportHeight whether or not this table is always
5247      *        made large enough to fill the height of an enclosing
5248      *        viewport
5249      * @see #getFillsViewportHeight
5250      * @see #getScrollableTracksViewportHeight
5251      * @since 1.6
5252      * @beaninfo
5253      *      bound: true
5254      *      description: Whether or not this table is always made large enough
5255      *                   to fill the height of an enclosing viewport
5256      */


5257     public void setFillsViewportHeight(boolean fillsViewportHeight) {
5258         boolean old = this.fillsViewportHeight;
5259         this.fillsViewportHeight = fillsViewportHeight;
5260         resizeAndRepaint();
5261         firePropertyChange("fillsViewportHeight", old, fillsViewportHeight);
5262     }
5263 
5264     /**
5265      * Returns whether or not this table is always made large enough
5266      * to fill the height of an enclosing viewport.
5267      *
5268      * @return whether or not this table is always made large enough
5269      *         to fill the height of an enclosing viewport
5270      * @see #setFillsViewportHeight
5271      * @since 1.6
5272      */
5273     public boolean getFillsViewportHeight() {
5274         return fillsViewportHeight;
5275     }
5276 


5633     }
5634 
5635     /**
5636      * Returns the active cell editor, which is {@code null} if the table
5637      * is not currently editing.
5638      *
5639      * @return the {@code TableCellEditor} that does the editing,
5640      *         or {@code null} if the table is not currently editing.
5641      * @see #cellEditor
5642      * @see #getCellEditor(int, int)
5643      */
5644     public TableCellEditor getCellEditor() {
5645         return cellEditor;
5646     }
5647 
5648     /**
5649      * Sets the active cell editor.
5650      *
5651      * @param anEditor the active cell editor
5652      * @see #cellEditor
5653      * @beaninfo
5654      *  bound: true
5655      *  description: The table's active cell editor.
5656      */


5657     public void setCellEditor(TableCellEditor anEditor) {
5658         TableCellEditor oldEditor = cellEditor;
5659         cellEditor = anEditor;
5660         firePropertyChange("tableCellEditor", oldEditor, anEditor);
5661     }
5662 
5663     /**
5664      * Sets the <code>editingColumn</code> variable.
5665      * @param aColumn  the column of the cell to be edited
5666      *
5667      * @see #editingColumn
5668      */
5669     public void setEditingColumn(int aColumn) {
5670         editingColumn = aColumn;
5671     }
5672 
5673     /**
5674      * Sets the <code>editingRow</code> variable.
5675      * @param aRow  the row of the cell to be edited
5676      *


6629                 }
6630 
6631                 return retVal;
6632             }
6633         }
6634     }
6635 
6636 /////////////////
6637 // Accessibility support
6638 ////////////////
6639 
6640     /**
6641      * Gets the AccessibleContext associated with this JTable.
6642      * For tables, the AccessibleContext takes the form of an
6643      * AccessibleJTable.
6644      * A new AccessibleJTable instance is created if necessary.
6645      *
6646      * @return an AccessibleJTable that serves as the
6647      *         AccessibleContext of this JTable
6648      */

6649     public AccessibleContext getAccessibleContext() {
6650         if (accessibleContext == null) {
6651             accessibleContext = new AccessibleJTable();
6652         }
6653         return accessibleContext;
6654     }
6655 
6656     //
6657     // *** should also implement AccessibleSelection?
6658     // *** and what's up with keyboard navigation/manipulation?
6659     //
6660     /**
6661      * This class implements accessibility support for the
6662      * <code>JTable</code> class.  It provides an implementation of the
6663      * Java Accessibility API appropriate to table user-interface elements.
6664      * <p>
6665      * <strong>Warning:</strong>
6666      * Serialized objects of this class will not be compatible with
6667      * future Swing releases. The current serialization support is
6668      * appropriate for short term storage or RMI between applications running




   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */

  25 package javax.swing;
  26 
  27 import java.util.*;
  28 
  29 import java.applet.Applet;
  30 import java.awt.*;
  31 import java.awt.event.*;
  32 import java.awt.print.*;
  33 
  34 import java.beans.JavaBean;
  35 import java.beans.BeanProperty;
  36 import java.beans.PropertyChangeEvent;
  37 import java.beans.PropertyChangeListener;
  38 
  39 import java.io.ObjectOutputStream;
  40 import java.io.ObjectInputStream;
  41 import java.io.IOException;
  42 import java.io.InvalidObjectException;
  43 
  44 import javax.accessibility.*;
  45 
  46 import javax.swing.event.*;
  47 import javax.swing.plaf.*;
  48 import javax.swing.table.*;
  49 import javax.swing.border.*;
  50 
  51 import java.text.NumberFormat;
  52 import java.text.DateFormat;
  53 import java.text.MessageFormat;
  54 
  55 import javax.print.attribute.*;
  56 import javax.print.PrintService;
  57 
  58 import sun.reflect.misc.ReflectUtil;
  59 
  60 import sun.swing.SwingUtilities2;
  61 import sun.swing.SwingUtilities2.Section;
  62 import static sun.swing.SwingUtilities2.Section.*;
  63 import sun.swing.PrintingStatus;
  64 
  65 /**
  66  * The <code>JTable</code> is used to display and edit regular two-dimensional tables
  67  * of cells.
  68  * See <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/table.html">How to Use Tables</a>
  69  * in <em>The Java Tutorial</em>
  70  * for task-oriented documentation and examples of using <code>JTable</code>.
  71  *
  72  * <p>
  73  * The <code>JTable</code> has many
  74  * facilities that make it possible to customize its rendering and editing
  75  * but provides defaults for these features so that simple tables can be
  76  * set up easily.  For example, to set up a table with 10 rows and 10
  77  * columns of numbers:


 190  * <p>
 191  * As for all <code>JComponent</code> classes, you can use
 192  * {@link InputMap} and {@link ActionMap} to associate an
 193  * {@link Action} object with a {@link KeyStroke} and execute the
 194  * action under specified conditions.
 195  * <p>
 196  * <strong>Warning:</strong> Swing is not thread safe. For more
 197  * information see <a
 198  * href="package-summary.html#threading">Swing's Threading
 199  * Policy</a>.
 200  * <p>
 201  * <strong>Warning:</strong>
 202  * Serialized objects of this class will not be compatible with
 203  * future Swing releases. The current serialization support is
 204  * appropriate for short term storage or RMI between applications running
 205  * the same version of Swing.  As of 1.4, support for long term storage
 206  * of all JavaBeans&trade;
 207  * has been added to the <code>java.beans</code> package.
 208  * Please see {@link java.beans.XMLEncoder}.
 209  *





 210  * @author Philip Milne
 211  * @author Shannon Hickey (printing support)
 212  * @see javax.swing.table.DefaultTableModel
 213  * @see javax.swing.table.TableRowSorter
 214  * @since 1.2
 215  */
 216 /* The first versions of the JTable, contained in Swing-0.1 through
 217  * Swing-0.4, were written by Alan Chung.
 218  */
 219 @JavaBean(defaultProperty = "UI", description = "A component which displays data in a two dimensional grid.")
 220 @SwingContainer(false)
 221 @SuppressWarnings("serial") // Same-version serialization only
 222 public class JTable extends JComponent implements TableModelListener, Scrollable,
 223     TableColumnModelListener, ListSelectionListener, CellEditorListener,
 224     Accessible, RowSorterListener
 225 {
 226 //
 227 // Static Constants
 228 //
 229 
 230     /**
 231      * @see #getUIClassID
 232      * @see #readObject
 233      */
 234     private static final String uiClassID = "TableUI";
 235 
 236     /** Do not adjust column widths automatically; use a horizontal scrollbar instead. */
 237     public static final int     AUTO_RESIZE_OFF = 0;
 238 
 239     /** When a column is adjusted in the UI, adjust the next column the opposite way. */
 240     public static final int     AUTO_RESIZE_NEXT_COLUMN = 1;


 873      * @param aTable a {@code JTable} to be used for the scroll pane
 874      * @return a {@code JScrollPane} created using {@code aTable}
 875      * @deprecated As of Swing version 1.0.2,
 876      * replaced by <code>new JScrollPane(aTable)</code>.
 877      */
 878     @Deprecated
 879     static public JScrollPane createScrollPaneForTable(JTable aTable) {
 880         return new JScrollPane(aTable);
 881     }
 882 
 883 //
 884 // Table Attributes
 885 //
 886 
 887     /**
 888      * Sets the <code>tableHeader</code> working with this <code>JTable</code> to <code>newHeader</code>.
 889      * It is legal to have a <code>null</code> <code>tableHeader</code>.
 890      *
 891      * @param   tableHeader                       new tableHeader
 892      * @see     #getTableHeader



 893      */
 894     @BeanProperty(description
 895             = "The JTableHeader instance which renders the column headers.")
 896     public void setTableHeader(JTableHeader tableHeader) {
 897         if (this.tableHeader != tableHeader) {
 898             JTableHeader old = this.tableHeader;
 899             // Release the old header
 900             if (old != null) {
 901                 old.setTable(null);
 902             }
 903             this.tableHeader = tableHeader;
 904             if (tableHeader != null) {
 905                 tableHeader.setTable(this);
 906             }
 907             firePropertyChange("tableHeader", old, tableHeader);
 908         }
 909     }
 910 
 911     /**
 912      * Returns the <code>tableHeader</code> used by this <code>JTable</code>.
 913      *
 914      * @return  the <code>tableHeader</code> used by this table
 915      * @see     #setTableHeader
 916      */
 917     public JTableHeader getTableHeader() {
 918         return tableHeader;
 919     }
 920 
 921     /**
 922      * Sets the height, in pixels, of all cells to <code>rowHeight</code>,
 923      * revalidates, and repaints.
 924      * The height of the cells will be equal to the row height minus
 925      * the row margin.
 926      *
 927      * @param   rowHeight                       new row height
 928      * @exception IllegalArgumentException      if <code>rowHeight</code> is
 929      *                                          less than 1
 930      * @see     #getRowHeight



 931      */
 932     @BeanProperty(description
 933             = "The height of the specified row.")
 934     public void setRowHeight(int rowHeight) {
 935         if (rowHeight <= 0) {
 936             throw new IllegalArgumentException("New row height less than 1");
 937         }
 938         int old = this.rowHeight;
 939         this.rowHeight = rowHeight;
 940         rowModel = null;
 941         if (sortManager != null) {
 942             sortManager.modelRowSizes = null;
 943         }
 944         isRowHeightSet = true;
 945         resizeAndRepaint();
 946         firePropertyChange("rowHeight", old, rowHeight);
 947     }
 948 
 949     /**
 950      * Returns the height of a table row, in pixels.
 951      *
 952      * @return  the height in pixels of a table row
 953      * @see     #setRowHeight


 956         return rowHeight;
 957     }
 958 
 959     private SizeSequence getRowModel() {
 960         if (rowModel == null) {
 961             rowModel = new SizeSequence(getRowCount(), getRowHeight());
 962         }
 963         return rowModel;
 964     }
 965 
 966     /**
 967      * Sets the height for <code>row</code> to <code>rowHeight</code>,
 968      * revalidates, and repaints. The height of the cells in this row
 969      * will be equal to the row height minus the row margin.
 970      *
 971      * @param   row                             the row whose height is being
 972                                                 changed
 973      * @param   rowHeight                       new row height, in pixels
 974      * @exception IllegalArgumentException      if <code>rowHeight</code> is
 975      *                                          less than 1



 976      * @since 1.3
 977      */
 978     @BeanProperty(description
 979             = "The height in pixels of the cells in <code>row</code>")
 980     public void setRowHeight(int row, int rowHeight) {
 981         if (rowHeight <= 0) {
 982             throw new IllegalArgumentException("New row height less than 1");
 983         }
 984         getRowModel().setSize(row, rowHeight);
 985         if (sortManager != null) {
 986             sortManager.setViewRowHeight(row, rowHeight);
 987         }
 988         resizeAndRepaint();
 989     }
 990 
 991     /**
 992      * Returns the height, in pixels, of the cells in <code>row</code>.
 993      * @param   row              the row whose height is to be returned
 994      * @return the height, in pixels, of the cells in the row
 995      * @since 1.3
 996      */
 997     public int getRowHeight(int row) {
 998         return (rowModel == null) ? getRowHeight() : rowModel.getSize(row);
 999     }
1000 
1001     /**
1002      * Sets the amount of empty space between cells in adjacent rows.
1003      *
1004      * @param  rowMargin  the number of pixels between cells in a row
1005      * @see     #getRowMargin



1006      */
1007     @BeanProperty(description
1008             = "The amount of space between cells.")
1009     public void setRowMargin(int rowMargin) {
1010         int old = this.rowMargin;
1011         this.rowMargin = rowMargin;
1012         resizeAndRepaint();
1013         firePropertyChange("rowMargin", old, rowMargin);
1014     }
1015 
1016     /**
1017      * Gets the amount of empty space, in pixels, between cells. Equivalent to:
1018      * <code>getIntercellSpacing().height</code>.
1019      * @return the number of pixels between cells in a row
1020      *
1021      * @see     #setRowMargin
1022      */
1023     public int getRowMargin() {
1024         return rowMargin;
1025     }
1026 
1027     /**
1028      * Sets the <code>rowMargin</code> and the <code>columnMargin</code> --
1029      * the height and width of the space between cells -- to
1030      * <code>intercellSpacing</code>.
1031      *
1032      * @param   intercellSpacing        a <code>Dimension</code>
1033      *                                  specifying the new width
1034      *                                  and height between cells
1035      * @see     #getIntercellSpacing



1036      */
1037     @BeanProperty(bound = false, description
1038             = "The spacing between the cells, drawn in the background color of the JTable.")
1039     public void setIntercellSpacing(Dimension intercellSpacing) {
1040         // Set the rowMargin here and columnMargin in the TableColumnModel
1041         setRowMargin(intercellSpacing.height);
1042         getColumnModel().setColumnMargin(intercellSpacing.width);
1043 
1044         resizeAndRepaint();
1045     }
1046 
1047     /**
1048      * Returns the horizontal and vertical space between cells.
1049      * The default spacing is look and feel dependent.
1050      *
1051      * @return  the horizontal and vertical spacing between cells
1052      * @see     #setIntercellSpacing
1053      */
1054     public Dimension getIntercellSpacing() {
1055         return new Dimension(getColumnModel().getColumnMargin(), rowMargin);
1056     }
1057 
1058     /**
1059      * Sets the color used to draw grid lines to <code>gridColor</code> and redisplays.
1060      * The default color is look and feel dependent.
1061      *
1062      * @param   gridColor                       the new color of the grid lines
1063      * @exception IllegalArgumentException      if <code>gridColor</code> is <code>null</code>
1064      * @see     #getGridColor



1065      */
1066     @BeanProperty(description
1067             = "The grid color.")
1068     public void setGridColor(Color gridColor) {
1069         if (gridColor == null) {
1070             throw new IllegalArgumentException("New color is null");
1071         }
1072         Color old = this.gridColor;
1073         this.gridColor = gridColor;
1074         firePropertyChange("gridColor", old, gridColor);
1075         // Redraw
1076         repaint();
1077     }
1078 
1079     /**
1080      * Returns the color used to draw grid lines.
1081      * The default color is look and feel dependent.
1082      *
1083      * @return  the color used to draw grid lines
1084      * @see     #setGridColor
1085      */
1086     public Color getGridColor() {
1087         return gridColor;
1088     }
1089 
1090     /**
1091      *  Sets whether the table draws grid lines around cells.
1092      *  If <code>showGrid</code> is true it does; if it is false it doesn't.
1093      *  There is no <code>getShowGrid</code> method as this state is held
1094      *  in two variables -- <code>showHorizontalLines</code> and <code>showVerticalLines</code> --
1095      *  each of which can be queried independently.
1096      *
1097      * @param   showGrid                 true if table view should draw grid lines
1098      *
1099      * @see     #setShowVerticalLines
1100      * @see     #setShowHorizontalLines


1101      */
1102     @BeanProperty(description
1103             = "The color used to draw the grid lines.")
1104     public void setShowGrid(boolean showGrid) {
1105         setShowHorizontalLines(showGrid);
1106         setShowVerticalLines(showGrid);
1107 
1108         // Redraw
1109         repaint();
1110     }
1111 
1112     /**
1113      *  Sets whether the table draws horizontal lines between cells.
1114      *  If <code>showHorizontalLines</code> is true it does; if it is false it doesn't.
1115      *
1116      * @param   showHorizontalLines      true if table view should draw horizontal lines
1117      * @see     #getShowHorizontalLines
1118      * @see     #setShowGrid
1119      * @see     #setShowVerticalLines



1120      */
1121     @BeanProperty(description
1122             = "Whether horizontal lines should be drawn in between the cells.")
1123     public void setShowHorizontalLines(boolean showHorizontalLines) {
1124         boolean old = this.showHorizontalLines;
1125         this.showHorizontalLines = showHorizontalLines;
1126         firePropertyChange("showHorizontalLines", old, showHorizontalLines);
1127 
1128         // Redraw
1129         repaint();
1130     }
1131 
1132     /**
1133      *  Sets whether the table draws vertical lines between cells.
1134      *  If <code>showVerticalLines</code> is true it does; if it is false it doesn't.
1135      *
1136      * @param   showVerticalLines              true if table view should draw vertical lines
1137      * @see     #getShowVerticalLines
1138      * @see     #setShowGrid
1139      * @see     #setShowHorizontalLines



1140      */
1141     @BeanProperty(description
1142             = "Whether vertical lines should be drawn in between the cells.")
1143     public void setShowVerticalLines(boolean showVerticalLines) {
1144         boolean old = this.showVerticalLines;
1145         this.showVerticalLines = showVerticalLines;
1146         firePropertyChange("showVerticalLines", old, showVerticalLines);
1147         // Redraw
1148         repaint();
1149     }
1150 
1151     /**
1152      * Returns true if the table draws horizontal lines between cells, false if it
1153      * doesn't. The default value is look and feel dependent.
1154      *
1155      * @return  true if the table draws horizontal lines between cells, false if it
1156      *          doesn't
1157      * @see     #setShowHorizontalLines
1158      */
1159     public boolean getShowHorizontalLines() {
1160         return showHorizontalLines;
1161     }
1162 


1169      * @see     #setShowVerticalLines
1170      */
1171     public boolean getShowVerticalLines() {
1172         return showVerticalLines;
1173     }
1174 
1175     /**
1176      * Sets the table's auto resize mode when the table is resized.  For further
1177      * information on how the different resize modes work, see
1178      * {@link #doLayout}.
1179      *
1180      * @param   mode One of 5 legal values:
1181      *                   AUTO_RESIZE_OFF,
1182      *                   AUTO_RESIZE_NEXT_COLUMN,
1183      *                   AUTO_RESIZE_SUBSEQUENT_COLUMNS,
1184      *                   AUTO_RESIZE_LAST_COLUMN,
1185      *                   AUTO_RESIZE_ALL_COLUMNS
1186      *
1187      * @see     #getAutoResizeMode
1188      * @see     #doLayout








1189      */
1190     @BeanProperty(enumerationValues = {
1191             "JTable.AUTO_RESIZE_OFF",
1192             "JTable.AUTO_RESIZE_NEXT_COLUMN",
1193             "JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS",
1194             "JTable.AUTO_RESIZE_LAST_COLUMN",
1195             "JTable.AUTO_RESIZE_ALL_COLUMNS"}, description
1196             = "Whether the columns should adjust themselves automatically.")
1197     public void setAutoResizeMode(int mode) {
1198         if (isValidAutoResizeMode(mode)) {
1199             int old = autoResizeMode;
1200             autoResizeMode = mode;
1201             resizeAndRepaint();
1202             if (tableHeader != null) {
1203                 tableHeader.resizeAndRepaint();
1204             }
1205             firePropertyChange("autoResizeMode", old, autoResizeMode);
1206         }
1207     }
1208 
1209     private static boolean isValidAutoResizeMode(int mode) {
1210         return (mode == AUTO_RESIZE_OFF)
1211                 || (mode == AUTO_RESIZE_NEXT_COLUMN)
1212                 || (mode == AUTO_RESIZE_SUBSEQUENT_COLUMNS)
1213                 || (mode == AUTO_RESIZE_LAST_COLUMN)
1214                 || (mode == AUTO_RESIZE_ALL_COLUMNS);
1215     }
1216 


1218      * Returns the auto resize mode of the table.  The default mode
1219      * is AUTO_RESIZE_SUBSEQUENT_COLUMNS.
1220      *
1221      * @return  the autoResizeMode of the table
1222      *
1223      * @see     #setAutoResizeMode
1224      * @see     #doLayout
1225      */
1226     public int getAutoResizeMode() {
1227         return autoResizeMode;
1228     }
1229 
1230     /**
1231      * Sets this table's <code>autoCreateColumnsFromModel</code> flag.
1232      * This method calls <code>createDefaultColumnsFromModel</code> if
1233      * <code>autoCreateColumnsFromModel</code> changes from false to true.
1234      *
1235      * @param   autoCreateColumnsFromModel   true if <code>JTable</code> should automatically create columns
1236      * @see     #getAutoCreateColumnsFromModel
1237      * @see     #createDefaultColumnsFromModel



1238      */
1239     @BeanProperty(description
1240             = "Automatically populates the columnModel when a new TableModel is submitted.")
1241     public void setAutoCreateColumnsFromModel(boolean autoCreateColumnsFromModel) {
1242         if (this.autoCreateColumnsFromModel != autoCreateColumnsFromModel) {
1243             boolean old = this.autoCreateColumnsFromModel;
1244             this.autoCreateColumnsFromModel = autoCreateColumnsFromModel;
1245             if (autoCreateColumnsFromModel) {
1246                 createDefaultColumnsFromModel();
1247             }
1248             firePropertyChange("autoCreateColumnsFromModel", old, autoCreateColumnsFromModel);
1249         }
1250     }
1251 
1252     /**
1253      * Determines whether the table will create default columns from the model.
1254      * If true, <code>setModel</code> will clear any existing columns and
1255      * create new columns from the new model.  Also, if the event in
1256      * the <code>tableChanged</code> notification specifies that the
1257      * entire table changed, then the columns will be rebuilt.
1258      * The default is true.
1259      *
1260      * @return  the autoCreateColumnsFromModel of the table


1411      * feels (including those that subclass {@code BasicLookAndFeel}) begin a
1412      * drag and drop operation whenever the user presses the mouse button over
1413      * an item (in single selection mode) or a selection (in other selection
1414      * modes) and then moves the mouse a few pixels. Setting this property to
1415      * {@code true} can therefore have a subtle effect on how selections behave.
1416      * <p>
1417      * If a look and feel is used that ignores this property, you can still
1418      * begin a drag and drop operation by calling {@code exportAsDrag} on the
1419      * table's {@code TransferHandler}.
1420      *
1421      * @param b whether or not to enable automatic drag handling
1422      * @exception HeadlessException if
1423      *            <code>b</code> is <code>true</code> and
1424      *            <code>GraphicsEnvironment.isHeadless()</code>
1425      *            returns <code>true</code>
1426      * @see java.awt.GraphicsEnvironment#isHeadless
1427      * @see #getDragEnabled
1428      * @see #setTransferHandler
1429      * @see TransferHandler
1430      * @since 1.4




1431      */
1432     @BeanProperty(bound = false, description
1433             = "determines whether automatic drag handling is enabled")
1434     public void setDragEnabled(boolean b) {
1435         checkDragEnabled(b);
1436         dragEnabled = b;
1437     }
1438 
1439     private void checkDragEnabled(boolean b) {
1440         if (b && GraphicsEnvironment.isHeadless()) {
1441             throw new HeadlessException();
1442         }
1443     }
1444 
1445     /**
1446      * Returns whether or not automatic drag handling is enabled.
1447      *
1448      * @return the value of the {@code dragEnabled} property
1449      * @see #setDragEnabled
1450      * @since 1.4
1451      */
1452     public boolean getDragEnabled() {
1453         return dragEnabled;


1801     }
1802 
1803     /**
1804      * Returns the location that this component should visually indicate
1805      * as the drop location during a DnD operation over the component,
1806      * or {@code null} if no location is to currently be shown.
1807      * <p>
1808      * This method is not meant for querying the drop location
1809      * from a {@code TransferHandler}, as the drop location is only
1810      * set after the {@code TransferHandler}'s <code>canImport</code>
1811      * has returned and has allowed for the location to be shown.
1812      * <p>
1813      * When this property changes, a property change event with
1814      * name "dropLocation" is fired by the component.
1815      *
1816      * @return the drop location
1817      * @see #setDropMode
1818      * @see TransferHandler#canImport(TransferHandler.TransferSupport)
1819      * @since 1.6
1820      */
1821     @BeanProperty(bound = false)
1822     public final DropLocation getDropLocation() {
1823         return dropLocation;
1824     }
1825 
1826     /**
1827      * Specifies whether a {@code RowSorter} should be created for the
1828      * table whenever its model changes.
1829      * <p>
1830      * When {@code setAutoCreateRowSorter(true)} is invoked, a {@code
1831      * TableRowSorter} is immediately created and installed on the
1832      * table.  While the {@code autoCreateRowSorter} property remains
1833      * {@code true}, every time the model is changed, a new {@code
1834      * TableRowSorter} is created and set as the table's row sorter.
1835      * The default value for the {@code autoCreateRowSorter}
1836      * property is {@code false}.
1837      *
1838      * @param autoCreateRowSorter whether or not a {@code RowSorter}
1839      *        should be automatically created
1840      * @see javax.swing.table.TableRowSorter




1841      * @since 1.6
1842      */
1843     @BeanProperty(preferred = true, description
1844             = "Whether or not to turn on sorting by default.")
1845     public void setAutoCreateRowSorter(boolean autoCreateRowSorter) {
1846         boolean oldValue = this.autoCreateRowSorter;
1847         this.autoCreateRowSorter = autoCreateRowSorter;
1848         if (autoCreateRowSorter) {
1849             setRowSorter(new TableRowSorter<TableModel>(getModel()));
1850         }
1851         firePropertyChange("autoCreateRowSorter", oldValue,
1852                            autoCreateRowSorter);
1853     }
1854 
1855     /**
1856      * Returns {@code true} if whenever the model changes, a new
1857      * {@code RowSorter} should be created and installed
1858      * as the table's sorter; otherwise, returns {@code false}.
1859      *
1860      * @return true if a {@code RowSorter} should be created when
1861      *         the model changes
1862      * @since 1.6
1863      */
1864     public boolean getAutoCreateRowSorter() {
1865         return autoCreateRowSorter;
1866     }
1867 
1868     /**
1869      * Specifies whether the selection should be updated after sorting.
1870      * If true, on sorting the selection is reset such that
1871      * the same rows, in terms of the model, remain selected.  The default
1872      * is true.
1873      *
1874      * @param update whether or not to update the selection on sorting




1875      * @since 1.6
1876      */
1877     @BeanProperty(expert = true, description
1878             = "Whether or not to update the selection on sorting")
1879     public void setUpdateSelectionOnSort(boolean update) {
1880         if (updateSelectionOnSort != update) {
1881             updateSelectionOnSort = update;
1882             firePropertyChange("updateSelectionOnSort", !update, update);
1883         }
1884     }
1885 
1886     /**
1887      * Returns true if the selection should be updated after sorting.
1888      *
1889      * @return whether to update the selection on a sort
1890      * @since 1.6
1891      */
1892     public boolean getUpdateSelectionOnSort() {
1893         return updateSelectionOnSort;
1894     }
1895 
1896     /**
1897      * Sets the <code>RowSorter</code>.  <code>RowSorter</code> is used
1898      * to provide sorting and filtering to a <code>JTable</code>.
1899      * <p>
1900      * This method clears the selection and resets any variable row heights.
1901      * <p>
1902      * This method fires a <code>PropertyChangeEvent</code> when appropriate,
1903      * with the property name <code>"rowSorter"</code>.  For
1904      * backward-compatibility, this method fires an additional event with the
1905      * property name <code>"sorter"</code>.
1906      * <p>
1907      * If the underlying model of the <code>RowSorter</code> differs from
1908      * that of this <code>JTable</code> undefined behavior will result.
1909      *
1910      * @param sorter the <code>RowSorter</code>; <code>null</code> turns
1911      *        sorting off
1912      * @see javax.swing.table.TableRowSorter



1913      * @since 1.6
1914      */
1915     @BeanProperty(description
1916             = "The table's RowSorter")
1917     public void setRowSorter(RowSorter<? extends TableModel> sorter) {
1918         RowSorter<? extends TableModel> oldRowSorter = null;
1919         if (sortManager != null) {
1920             oldRowSorter = sortManager.sorter;
1921             sortManager.dispose();
1922             sortManager = null;
1923         }
1924         rowModel = null;
1925         clearSelectionAndLeadAnchor();
1926         if (sorter != null) {
1927             sortManager = new SortManager(sorter);
1928         }
1929         resizeAndRepaint();
1930         firePropertyChange("rowSorter", oldRowSorter, sorter);
1931         firePropertyChange("sorter", oldRowSorter, sorter);
1932     }
1933 
1934     /**
1935      * Returns the object responsible for sorting.
1936      *


1948      * Sets the table's selection mode to allow only single selections, a single
1949      * contiguous interval, or multiple intervals.
1950      * <P>
1951      * <b>Note:</b>
1952      * <code>JTable</code> provides all the methods for handling
1953      * column and row selection.  When setting states,
1954      * such as <code>setSelectionMode</code>, it not only
1955      * updates the mode for the row selection model but also sets similar
1956      * values in the selection model of the <code>columnModel</code>.
1957      * If you want to have the row and column selection models operating
1958      * in different modes, set them both directly.
1959      * <p>
1960      * Both the row and column selection models for <code>JTable</code>
1961      * default to using a <code>DefaultListSelectionModel</code>
1962      * so that <code>JTable</code> works the same way as the
1963      * <code>JList</code>. See the <code>setSelectionMode</code> method
1964      * in <code>JList</code> for details about the modes.
1965      *
1966      * @param selectionMode the mode used by the row and column selection models
1967      * @see JList#setSelectionMode





1968      */
1969     @BeanProperty(enumerationValues = {
1970             "ListSelectionModel.SINGLE_SELECTION",
1971             "ListSelectionModel.SINGLE_INTERVAL_SELECTION",
1972             "ListSelectionModel.MULTIPLE_INTERVAL_SELECTION"}, description
1973             = "The selection mode used by the row and column selection models.")
1974     public void setSelectionMode(int selectionMode) {
1975         clearSelection();
1976         getSelectionModel().setSelectionMode(selectionMode);
1977         getColumnModel().getSelectionModel().setSelectionMode(selectionMode);
1978     }
1979 
1980     /**
1981      * Sets whether the rows in this model can be selected.
1982      *
1983      * @param rowSelectionAllowed   true if this model will allow row selection
1984      * @see #getRowSelectionAllowed




1985      */
1986     @BeanProperty(visualUpdate = true, description
1987             = "If true, an entire row is selected for each selected cell.")
1988     public void setRowSelectionAllowed(boolean rowSelectionAllowed) {
1989         boolean old = this.rowSelectionAllowed;
1990         this.rowSelectionAllowed = rowSelectionAllowed;
1991         if (old != rowSelectionAllowed) {
1992             repaint();
1993         }
1994         firePropertyChange("rowSelectionAllowed", old, rowSelectionAllowed);
1995     }
1996 
1997     /**
1998      * Returns true if rows can be selected.
1999      *
2000      * @return true if rows can be selected, otherwise false
2001      * @see #setRowSelectionAllowed
2002      */
2003     public boolean getRowSelectionAllowed() {
2004         return rowSelectionAllowed;
2005     }
2006 
2007     /**
2008      * Sets whether the columns in this model can be selected.
2009      *
2010      * @param columnSelectionAllowed   true if this model will allow column selection
2011      * @see #getColumnSelectionAllowed




2012      */
2013     @BeanProperty(visualUpdate = true, description
2014             = "If true, an entire column is selected for each selected cell.")
2015     public void setColumnSelectionAllowed(boolean columnSelectionAllowed) {
2016         boolean old = columnModel.getColumnSelectionAllowed();
2017         columnModel.setColumnSelectionAllowed(columnSelectionAllowed);
2018         if (old != columnSelectionAllowed) {
2019             repaint();
2020         }
2021         firePropertyChange("columnSelectionAllowed", old, columnSelectionAllowed);
2022     }
2023 
2024     /**
2025      * Returns true if columns can be selected.
2026      *
2027      * @return true if columns can be selected, otherwise false
2028      * @see #setColumnSelectionAllowed
2029      */
2030     public boolean getColumnSelectionAllowed() {
2031         return columnModel.getColumnSelectionAllowed();
2032     }
2033 
2034     /**
2035      * Sets whether this table allows both a column selection and a
2036      * row selection to exist simultaneously. When set,
2037      * the table treats the intersection of the row and column selection
2038      * models as the selected cells. Override <code>isCellSelected</code> to
2039      * change this default behavior. This method is equivalent to setting
2040      * both the <code>rowSelectionAllowed</code> property and
2041      * <code>columnSelectionAllowed</code> property of the
2042      * <code>columnModel</code> to the supplied value.
2043      *
2044      * @param  cellSelectionEnabled     true if simultaneous row and column
2045      *                                  selection is allowed
2046      * @see #getCellSelectionEnabled
2047      * @see #isCellSelected





2048      */
2049     @BeanProperty(visualUpdate = true, description
2050             = "Select a rectangular region of cells rather than rows or columns.")
2051     public void setCellSelectionEnabled(boolean cellSelectionEnabled) {
2052         setRowSelectionAllowed(cellSelectionEnabled);
2053         setColumnSelectionAllowed(cellSelectionEnabled);
2054         boolean old = this.cellSelectionEnabled;
2055         this.cellSelectionEnabled = cellSelectionEnabled;
2056         firePropertyChange("cellSelectionEnabled", old, cellSelectionEnabled);
2057     }
2058 
2059     /**
2060      * Returns true if both row and column selection models are enabled.
2061      * Equivalent to <code>getRowSelectionAllowed() &amp;&amp;
2062      * getColumnSelectionAllowed()</code>.
2063      *
2064      * @return true if both row and column selection models are enabled
2065      *
2066      * @see #setCellSelectionEnabled
2067      */
2068     public boolean getCellSelectionEnabled() {
2069         return getRowSelectionAllowed() && getColumnSelectionAllowed();
2070     }


2218         selectionModel.removeSelectionInterval(boundRow(index0), boundRow(index1));
2219     }
2220 
2221     /**
2222      * Deselects the columns from <code>index0</code> to <code>index1</code>, inclusive.
2223      *
2224      * @exception IllegalArgumentException      if <code>index0</code> or
2225      *                                          <code>index1</code> lie outside
2226      *                                          [0, <code>getColumnCount()</code>-1]
2227      * @param   index0 one end of the interval
2228      * @param   index1 the other end of the interval
2229      */
2230     public void removeColumnSelectionInterval(int index0, int index1) {
2231         columnModel.getSelectionModel().removeSelectionInterval(boundColumn(index0), boundColumn(index1));
2232     }
2233 
2234     /**
2235      * Returns the index of the first selected row, -1 if no row is selected.
2236      * @return the index of the first selected row
2237      */
2238     @BeanProperty(bound = false)
2239     public int getSelectedRow() {
2240         return selectionModel.getMinSelectionIndex();
2241     }
2242 
2243     /**
2244      * Returns the index of the first selected column,
2245      * -1 if no column is selected.
2246      * @return the index of the first selected column
2247      */
2248     @BeanProperty(bound = false)
2249     public int getSelectedColumn() {
2250         return columnModel.getSelectionModel().getMinSelectionIndex();
2251     }
2252 
2253     /**
2254      * Returns the indices of all selected rows.
2255      *
2256      * @return an array of integers containing the indices of all selected rows,
2257      *         or an empty array if no row is selected
2258      * @see #getSelectedRow
2259      */
2260     @BeanProperty(bound = false)
2261     public int[] getSelectedRows() {
2262         int iMin = selectionModel.getMinSelectionIndex();
2263         int iMax = selectionModel.getMaxSelectionIndex();
2264 
2265         if ((iMin == -1) || (iMax == -1)) {
2266             return new int[0];
2267         }
2268 
2269         int[] rvTmp = new int[1+ (iMax - iMin)];
2270         int n = 0;
2271         for(int i = iMin; i <= iMax; i++) {
2272             if (selectionModel.isSelectedIndex(i)) {
2273                 rvTmp[n++] = i;
2274             }
2275         }
2276         int[] rv = new int[n];
2277         System.arraycopy(rvTmp, 0, rv, 0, n);
2278         return rv;
2279     }
2280 
2281     /**
2282      * Returns the indices of all selected columns.
2283      *
2284      * @return an array of integers containing the indices of all selected columns,
2285      *         or an empty array if no column is selected
2286      * @see #getSelectedColumn
2287      */
2288     @BeanProperty(bound = false)
2289     public int[] getSelectedColumns() {
2290         return columnModel.getSelectedColumns();
2291     }
2292 
2293     /**
2294      * Returns the number of selected rows.
2295      *
2296      * @return the number of selected rows, 0 if no rows are selected
2297      */
2298     @BeanProperty(bound = false)
2299     public int getSelectedRowCount() {
2300         int iMin = selectionModel.getMinSelectionIndex();
2301         int iMax = selectionModel.getMaxSelectionIndex();
2302         int count = 0;
2303 
2304         for(int i = iMin; i <= iMax; i++) {
2305             if (selectionModel.isSelectedIndex(i)) {
2306                 count++;
2307             }
2308         }
2309         return count;
2310     }
2311 
2312     /**
2313      * Returns the number of selected columns.
2314      *
2315      * @return the number of selected columns, 0 if no columns are selected
2316      */
2317     @BeanProperty(bound = false)
2318     public int getSelectedColumnCount() {
2319         return columnModel.getSelectedColumnCount();
2320     }
2321 
2322     /**
2323      * Returns true if the specified index is in the valid range of rows,
2324      * and the row at that index is selected.
2325      *
2326      * @param row a row in the row model
2327      * @return true if <code>row</code> is a valid index and the row at
2328      *              that index is selected (where 0 is the first row)
2329      */
2330     public boolean isRowSelected(int row) {
2331         return selectionModel.isSelectedIndex(row);
2332     }
2333 
2334     /**
2335      * Returns true if the specified index is in the valid range of columns,
2336      * and the column at that index is selected.
2337      *


2485         return selectionForeground;
2486     }
2487 
2488     /**
2489      * Sets the foreground color for selected cells.  Cell renderers
2490      * can use this color to render text and graphics for selected
2491      * cells.
2492      * <p>
2493      * The default value of this property is defined by the look
2494      * and feel implementation.
2495      * <p>
2496      * This is a <a href="http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html">JavaBeans</a> bound property.
2497      *
2498      * @param selectionForeground  the <code>Color</code> to use in the foreground
2499      *                             for selected list items
2500      * @see #getSelectionForeground
2501      * @see #setSelectionBackground
2502      * @see #setForeground
2503      * @see #setBackground
2504      * @see #setFont



2505      */
2506     @BeanProperty(description
2507             = "A default foreground color for selected cells.")
2508     public void setSelectionForeground(Color selectionForeground) {
2509         Color old = this.selectionForeground;
2510         this.selectionForeground = selectionForeground;
2511         firePropertyChange("selectionForeground", old, selectionForeground);
2512         repaint();
2513     }
2514 
2515     /**
2516      * Returns the background color for selected cells.
2517      *
2518      * @return the <code>Color</code> used for the background of selected list items
2519      * @see #setSelectionBackground
2520      * @see #setSelectionForeground
2521      */
2522     public Color getSelectionBackground() {
2523         return selectionBackground;
2524     }
2525 
2526     /**
2527      * Sets the background color for selected cells.  Cell renderers
2528      * can use this color to the fill selected cells.
2529      * <p>
2530      * The default value of this property is defined by the look
2531      * and feel implementation.
2532      * <p>
2533      * This is a <a href="http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html">JavaBeans</a> bound property.
2534      *
2535      * @param selectionBackground  the <code>Color</code> to use for the background
2536      *                             of selected cells
2537      * @see #getSelectionBackground
2538      * @see #setSelectionForeground
2539      * @see #setForeground
2540      * @see #setBackground
2541      * @see #setFont



2542      */
2543     @BeanProperty(description
2544             = "A default background color for selected cells.")
2545     public void setSelectionBackground(Color selectionBackground) {
2546         Color old = this.selectionBackground;
2547         this.selectionBackground = selectionBackground;
2548         firePropertyChange("selectionBackground", old, selectionBackground);
2549         repaint();
2550     }
2551 
2552     /**
2553      * Returns the <code>TableColumn</code> object for the column in the table
2554      * whose identifier is equal to <code>identifier</code>, when compared using
2555      * <code>equals</code>.
2556      *
2557      * @return  the <code>TableColumn</code> object that matches the identifier
2558      * @exception IllegalArgumentException      if <code>identifier</code> is <code>null</code> or no <code>TableColumn</code> has this identifier
2559      *
2560      * @param   identifier                      the identifier object
2561      */
2562     public TableColumn getColumn(Object identifier) {
2563         TableColumnModel cm = getColumnModel();
2564         int columnIndex = cm.getColumnIndex(identifier);


2640      * @since 1.6
2641      */
2642     public int convertRowIndexToModel(int viewRowIndex) {
2643         RowSorter<?> sorter = getRowSorter();
2644         if (sorter != null) {
2645             return sorter.convertRowIndexToModel(viewRowIndex);
2646         }
2647         return viewRowIndex;
2648     }
2649 
2650     /**
2651      * Returns the number of rows that can be shown in the
2652      * <code>JTable</code>, given unlimited space.  If a
2653      * <code>RowSorter</code> with a filter has been specified, the
2654      * number of rows returned may differ from that of the underlying
2655      * <code>TableModel</code>.
2656      *
2657      * @return the number of rows shown in the <code>JTable</code>
2658      * @see #getColumnCount
2659      */
2660     @BeanProperty(bound = false)
2661     public int getRowCount() {
2662         RowSorter<?> sorter = getRowSorter();
2663         if (sorter != null) {
2664             return sorter.getViewRowCount();
2665         }
2666         return getModel().getRowCount();
2667     }
2668 
2669     /**
2670      * Returns the number of columns in the column model. Note that this may
2671      * be different from the number of columns in the table model.
2672      *
2673      * @return  the number of columns in the table
2674      * @see #getRowCount
2675      * @see #removeColumn
2676      */
2677     @BeanProperty(bound = false)
2678     public int getColumnCount() {
2679         return getColumnModel().getColumnCount();
2680     }
2681 
2682     /**
2683      * Returns the name of the column appearing in the view at
2684      * column position <code>column</code>.
2685      *
2686      * @param  column    the column in the view being queried
2687      * @return the name of the column at position <code>column</code>
2688                         in the view where the first column is column 0
2689      */
2690     public String getColumnName(int column) {
2691         return getModel().getColumnName(convertColumnIndexToModel(column));
2692     }
2693 
2694     /**
2695      * Returns the type of the column appearing in the view at
2696      * column position <code>column</code>.
2697      *


3526             editorComp.validate();
3527             editorComp.repaint();
3528 
3529             setCellEditor(editor);
3530             setEditingRow(row);
3531             setEditingColumn(column);
3532             editor.addCellEditorListener(this);
3533 
3534             return true;
3535         }
3536         return false;
3537     }
3538 
3539     /**
3540      * Returns true if a cell is being edited.
3541      *
3542      * @return  true if the table is editing a cell
3543      * @see     #editingColumn
3544      * @see     #editingRow
3545      */
3546     @BeanProperty(bound = false)
3547     public boolean isEditing() {
3548         return cellEditor != null;
3549     }
3550 
3551     /**
3552      * Returns the component that is handling the editing session.
3553      * If nothing is being edited, returns null.
3554      *
3555      * @return  Component handling editing session
3556      */
3557     @BeanProperty(bound = false)
3558     public Component getEditorComponent() {
3559         return editorComp;
3560     }
3561 
3562     /**
3563      * Returns the index of the column that contains the cell currently
3564      * being edited.  If nothing is being edited, returns -1.
3565      *
3566      * @return  the index of the column that contains the cell currently
3567      *          being edited; returns -1 if nothing being edited
3568      * @see #editingRow
3569      */
3570     public int getEditingColumn() {
3571         return editingColumn;
3572     }
3573 
3574     /**
3575      * Returns the index of the row that contains the cell currently
3576      * being edited.  If nothing is being edited, returns -1.
3577      *


3584     }
3585 
3586 //
3587 // Managing TableUI
3588 //
3589 
3590     /**
3591      * Returns the L&amp;F object that renders this component.
3592      *
3593      * @return the <code>TableUI</code> object that renders this component
3594      */
3595     public TableUI getUI() {
3596         return (TableUI)ui;
3597     }
3598 
3599     /**
3600      * Sets the L&amp;F object that renders this component and repaints.
3601      *
3602      * @param ui  the TableUI L&amp;F object
3603      * @see UIDefaults#getUI





3604      */
3605     @BeanProperty(hidden = true, visualUpdate = true, description
3606             = "The UI object that implements the Component's LookAndFeel.")
3607     public void setUI(TableUI ui) {
3608         if (this.ui != ui) {
3609             super.setUI(ui);
3610             repaint();
3611         }
3612     }
3613 
3614     /**
3615      * Notification from the <code>UIManager</code> that the L&amp;F has changed.
3616      * Replaces the current UI object with the latest version from the
3617      * <code>UIManager</code>.
3618      *
3619      * @see JComponent#updateUI
3620      */
3621     public void updateUI() {
3622         // Update the UIs of the cell renderers, cell editors and header renderers.
3623         TableColumnModel cm = getColumnModel();
3624         for(int column = 0; column < cm.getColumnCount(); column++) {
3625             TableColumn aColumn = cm.getColumn(column);
3626             SwingUtilities.updateRendererOrEditorUI(aColumn.getCellRenderer());


3642 
3643         // Update the UI of the table header
3644         if (tableHeader != null && tableHeader.getParent() == null) {
3645             tableHeader.updateUI();
3646         }
3647 
3648         // Update UI applied to parent ScrollPane
3649         configureEnclosingScrollPaneUI();
3650 
3651         setUI((TableUI)UIManager.getUI(this));
3652     }
3653 
3654     /**
3655      * Returns the suffix used to construct the name of the L&amp;F class used to
3656      * render this component.
3657      *
3658      * @return the string "TableUI"
3659      * @see JComponent#getUIClassID
3660      * @see UIDefaults#getUI
3661      */
3662     @BeanProperty(bound = false)
3663     public String getUIClassID() {
3664         return uiClassID;
3665     }
3666 
3667 
3668 //
3669 // Managing models
3670 //
3671 
3672     /**
3673      * Sets the data model for this table to <code>newModel</code> and registers
3674      * with it for listener notifications from the new data model.
3675      *
3676      * @param   dataModel        the new data source for this table
3677      * @exception IllegalArgumentException      if <code>newModel</code> is <code>null</code>
3678      * @see     #getModel



3679      */
3680     @BeanProperty(description
3681             = "The model that is the source of the data for this view.")
3682     public void setModel(TableModel dataModel) {
3683         if (dataModel == null) {
3684             throw new IllegalArgumentException("Cannot set a null TableModel");
3685         }
3686         if (this.dataModel != dataModel) {
3687             TableModel old = this.dataModel;
3688             if (old != null) {
3689                 old.removeTableModelListener(this);
3690             }
3691             this.dataModel = dataModel;
3692             dataModel.addTableModelListener(this);
3693 
3694             tableChanged(new TableModelEvent(dataModel, TableModelEvent.HEADER_ROW));
3695 
3696             firePropertyChange("model", old, dataModel);
3697 
3698             if (getAutoCreateRowSorter()) {
3699                 setRowSorter(new TableRowSorter<TableModel>(dataModel));
3700             }
3701         }


3703 
3704     /**
3705      * Returns the <code>TableModel</code> that provides the data displayed by this
3706      * <code>JTable</code>.
3707      *
3708      * @return  the <code>TableModel</code> that provides the data displayed by this <code>JTable</code>
3709      * @see     #setModel
3710      */
3711     public TableModel getModel() {
3712         return dataModel;
3713     }
3714 
3715     /**
3716      * Sets the column model for this table to <code>newModel</code> and registers
3717      * for listener notifications from the new column model. Also sets
3718      * the column model of the <code>JTableHeader</code> to <code>columnModel</code>.
3719      *
3720      * @param   columnModel        the new data source for this table
3721      * @exception IllegalArgumentException      if <code>columnModel</code> is <code>null</code>
3722      * @see     #getColumnModel



3723      */
3724     @BeanProperty(description
3725             = "The object governing the way columns appear in the view.")
3726     public void setColumnModel(TableColumnModel columnModel) {
3727         if (columnModel == null) {
3728             throw new IllegalArgumentException("Cannot set a null ColumnModel");
3729         }
3730         TableColumnModel old = this.columnModel;
3731         if (columnModel != old) {
3732             if (old != null) {
3733                 old.removeColumnModelListener(this);
3734             }
3735             this.columnModel = columnModel;
3736             columnModel.addColumnModelListener(this);
3737 
3738             // Set the column model of the header as well.
3739             if (tableHeader != null) {
3740                 tableHeader.setColumnModel(columnModel);
3741             }
3742 
3743             firePropertyChange("columnModel", old, columnModel);
3744             resizeAndRepaint();
3745         }
3746     }
3747 
3748     /**
3749      * Returns the <code>TableColumnModel</code> that contains all column information
3750      * of this table.
3751      *
3752      * @return  the object that provides the column state of the table
3753      * @see     #setColumnModel
3754      */
3755     public TableColumnModel getColumnModel() {
3756         return columnModel;
3757     }
3758 
3759     /**
3760      * Sets the row selection model for this table to <code>newModel</code>
3761      * and registers for listener notifications from the new selection model.
3762      *
3763      * @param   newModel        the new selection model
3764      * @exception IllegalArgumentException      if <code>newModel</code> is <code>null</code>
3765      * @see     #getSelectionModel



3766      */
3767     @BeanProperty(description
3768             = "The selection model for rows.")
3769     public void setSelectionModel(ListSelectionModel newModel) {
3770         if (newModel == null) {
3771             throw new IllegalArgumentException("Cannot set a null SelectionModel");
3772         }
3773 
3774         ListSelectionModel oldModel = selectionModel;
3775 
3776         if (newModel != oldModel) {
3777             if (oldModel != null) {
3778                 oldModel.removeListSelectionListener(this);
3779             }
3780 
3781             selectionModel = newModel;
3782             newModel.addListSelectionListener(this);
3783 
3784             firePropertyChange("selectionModel", oldModel, newModel);
3785             repaint();
3786         }
3787     }
3788 


4736      * Application code will not use these methods explicitly, they
4737      * are used internally by JTable.
4738      *
4739      * @param  e  the event received
4740      * @see CellEditorListener
4741      */
4742     public void editingCanceled(ChangeEvent e) {
4743         removeEditor();
4744     }
4745 
4746 //
4747 // Implementing the Scrollable interface
4748 //
4749 
4750     /**
4751      * Sets the preferred size of the viewport for this table.
4752      *
4753      * @param size  a <code>Dimension</code> object specifying the <code>preferredSize</code> of a
4754      *              <code>JViewport</code> whose view is this table
4755      * @see Scrollable#getPreferredScrollableViewportSize


4756      */
4757     @BeanProperty(bound = false, description
4758             = "The preferred size of the viewport.")
4759     public void setPreferredScrollableViewportSize(Dimension size) {
4760         preferredViewportSize = size;
4761     }
4762 
4763     /**
4764      * Returns the preferred size of the viewport for this table.
4765      *
4766      * @return a <code>Dimension</code> object containing the <code>preferredSize</code> of the <code>JViewport</code>
4767      *         which displays this table
4768      * @see Scrollable#getPreferredScrollableViewportSize
4769      */
4770     public Dimension getPreferredScrollableViewportSize() {
4771         return preferredViewportSize;
4772     }
4773 
4774     /**
4775      * Returns the scroll increment (in pixels) that completely exposes one new
4776      * row or column (depending on the orientation).
4777      * <p>
4778      * This method is called each time the user requests a unit scroll.


5174             return rect.y + rect.height;
5175         }
5176         else if (getComponentOrientation().isLeftToRight()) {
5177             return rect.x + rect.width;
5178         }
5179         else { // Horizontal, right-to-left
5180             return rect.x;
5181         }
5182     }
5183 
5184     /**
5185      * Returns false if <code>autoResizeMode</code> is set to
5186      * <code>AUTO_RESIZE_OFF</code>, which indicates that the
5187      * width of the viewport does not determine the width
5188      * of the table.  Otherwise returns true.
5189      *
5190      * @return false if <code>autoResizeMode</code> is set
5191      *   to <code>AUTO_RESIZE_OFF</code>, otherwise returns true
5192      * @see Scrollable#getScrollableTracksViewportWidth
5193      */
5194     @BeanProperty(bound = false)
5195     public boolean getScrollableTracksViewportWidth() {
5196         return !(autoResizeMode == AUTO_RESIZE_OFF);
5197     }
5198 
5199     /**
5200      * Returns {@code false} to indicate that the height of the viewport does
5201      * not determine the height of the table, unless
5202      * {@code getFillsViewportHeight} is {@code true} and the preferred height
5203      * of the table is smaller than the viewport's height.
5204      *
5205      * @return {@code false} unless {@code getFillsViewportHeight} is
5206      *         {@code true} and the table needs to be stretched to fill
5207      *         the viewport
5208      * @see Scrollable#getScrollableTracksViewportHeight
5209      * @see #setFillsViewportHeight
5210      * @see #getFillsViewportHeight
5211      */
5212     @BeanProperty(bound = false)
5213     public boolean getScrollableTracksViewportHeight() {
5214         Container parent = SwingUtilities.getUnwrappedParent(this);
5215         return getFillsViewportHeight()
5216                && parent instanceof JViewport
5217                && parent.getHeight() > getPreferredSize().height;
5218     }
5219 
5220     /**
5221      * Sets whether or not this table is always made large enough
5222      * to fill the height of an enclosing viewport. If the preferred
5223      * height of the table is smaller than the viewport, then the table
5224      * will be stretched to fill the viewport. In other words, this
5225      * ensures the table is never smaller than the viewport.
5226      * The default for this property is {@code false}.
5227      *
5228      * @param fillsViewportHeight whether or not this table is always
5229      *        made large enough to fill the height of an enclosing
5230      *        viewport
5231      * @see #getFillsViewportHeight
5232      * @see #getScrollableTracksViewportHeight
5233      * @since 1.6




5234      */
5235     @BeanProperty(description
5236             = "Whether or not this table is always made large enough to fill the height of an enclosing viewport")
5237     public void setFillsViewportHeight(boolean fillsViewportHeight) {
5238         boolean old = this.fillsViewportHeight;
5239         this.fillsViewportHeight = fillsViewportHeight;
5240         resizeAndRepaint();
5241         firePropertyChange("fillsViewportHeight", old, fillsViewportHeight);
5242     }
5243 
5244     /**
5245      * Returns whether or not this table is always made large enough
5246      * to fill the height of an enclosing viewport.
5247      *
5248      * @return whether or not this table is always made large enough
5249      *         to fill the height of an enclosing viewport
5250      * @see #setFillsViewportHeight
5251      * @since 1.6
5252      */
5253     public boolean getFillsViewportHeight() {
5254         return fillsViewportHeight;
5255     }
5256 


5613     }
5614 
5615     /**
5616      * Returns the active cell editor, which is {@code null} if the table
5617      * is not currently editing.
5618      *
5619      * @return the {@code TableCellEditor} that does the editing,
5620      *         or {@code null} if the table is not currently editing.
5621      * @see #cellEditor
5622      * @see #getCellEditor(int, int)
5623      */
5624     public TableCellEditor getCellEditor() {
5625         return cellEditor;
5626     }
5627 
5628     /**
5629      * Sets the active cell editor.
5630      *
5631      * @param anEditor the active cell editor
5632      * @see #cellEditor



5633      */
5634     @BeanProperty(description
5635             = "The table's active cell editor.")
5636     public void setCellEditor(TableCellEditor anEditor) {
5637         TableCellEditor oldEditor = cellEditor;
5638         cellEditor = anEditor;
5639         firePropertyChange("tableCellEditor", oldEditor, anEditor);
5640     }
5641 
5642     /**
5643      * Sets the <code>editingColumn</code> variable.
5644      * @param aColumn  the column of the cell to be edited
5645      *
5646      * @see #editingColumn
5647      */
5648     public void setEditingColumn(int aColumn) {
5649         editingColumn = aColumn;
5650     }
5651 
5652     /**
5653      * Sets the <code>editingRow</code> variable.
5654      * @param aRow  the row of the cell to be edited
5655      *


6608                 }
6609 
6610                 return retVal;
6611             }
6612         }
6613     }
6614 
6615 /////////////////
6616 // Accessibility support
6617 ////////////////
6618 
6619     /**
6620      * Gets the AccessibleContext associated with this JTable.
6621      * For tables, the AccessibleContext takes the form of an
6622      * AccessibleJTable.
6623      * A new AccessibleJTable instance is created if necessary.
6624      *
6625      * @return an AccessibleJTable that serves as the
6626      *         AccessibleContext of this JTable
6627      */
6628     @BeanProperty(bound = false)
6629     public AccessibleContext getAccessibleContext() {
6630         if (accessibleContext == null) {
6631             accessibleContext = new AccessibleJTable();
6632         }
6633         return accessibleContext;
6634     }
6635 
6636     //
6637     // *** should also implement AccessibleSelection?
6638     // *** and what's up with keyboard navigation/manipulation?
6639     //
6640     /**
6641      * This class implements accessibility support for the
6642      * <code>JTable</code> class.  It provides an implementation of the
6643      * Java Accessibility API appropriate to table user-interface elements.
6644      * <p>
6645      * <strong>Warning:</strong>
6646      * Serialized objects of this class will not be compatible with
6647      * future Swing releases. The current serialization support is
6648      * appropriate for short term storage or RMI between applications running