< prev index next >

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

Print this page




  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 import java.util.List;
  53 
  54 import javax.print.attribute.*;
  55 import javax.print.PrintService;
  56 
  57 import sun.misc.ManagedLocalsThread;
  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:
  78  *
  79  * <pre>
  80  *      TableModel dataModel = new AbstractTableModel() {
  81  *          public int getColumnCount() { return 10; }
  82  *          public int getRowCount() { return 10;}
  83  *          public Object getValueAt(int row, int col) { return new Integer(row*col); }
  84  *      };
  85  *      JTable table = new JTable(dataModel);
  86  *      JScrollPane scrollpane = new JScrollPane(table);
  87  * </pre>
  88  * <p>
  89  * {@code JTable}s are typically placed inside of a {@code JScrollPane}.  By
  90  * default, a {@code JTable} will adjust its width such that
  91  * a horizontal scrollbar is unnecessary.  To allow for a horizontal scrollbar,
  92  * invoke {@link #setAutoResizeMode} with {@code AUTO_RESIZE_OFF}.
  93  * Note that if you wish to use a <code>JTable</code> in a standalone
  94  * view (outside of a <code>JScrollPane</code>) and want the header
  95  * displayed, you can get it using {@link #getTableHeader} and
  96  * display it separately.
  97  * <p>
  98  * To enable sorting and filtering of rows, use a
  99  * {@code RowSorter}.
 100  * You can set up a row sorter in either of two ways:
 101  * <ul>
 102  *   <li>Directly set the {@code RowSorter}. For example:
 103  *        {@code table.setRowSorter(new TableRowSorter(model))}.
 104  *   <li>Set the {@code autoCreateRowSorter}
 105  *       property to {@code true}, so that the {@code JTable}
 106  *       creates a {@code RowSorter} for
 107  *       you. For example: {@code setAutoCreateRowSorter(true)}.
 108  * </ul>
 109  * <p>
 110  * When designing applications that use the <code>JTable</code> it is worth paying
 111  * close attention to the data structures that will represent the table's data.
 112  * The <code>DefaultTableModel</code> is a model implementation that
 113  * uses a <code>Vector</code> of <code>Vector</code>s of <code>Object</code>s to
 114  * store the cell values. As well as copying the data from an
 115  * application into the <code>DefaultTableModel</code>,
 116  * it is also possible to wrap the data in the methods of the
 117  * <code>TableModel</code> interface so that the data can be passed to the
 118  * <code>JTable</code> directly, as in the example above. This often results
 119  * in more efficient applications because the model is free to choose the
 120  * internal representation that best suits the data.
 121  * A good rule of thumb for deciding whether to use the <code>AbstractTableModel</code>
 122  * or the <code>DefaultTableModel</code> is to use the <code>AbstractTableModel</code>
 123  * as the base class for creating subclasses and the <code>DefaultTableModel</code>
 124  * when subclassing is not required.
 125  * <p>
 126  * The "TableExample" directory in the demo area of the source distribution
 127  * gives a number of complete examples of <code>JTable</code> usage,
 128  * covering how the <code>JTable</code> can be used to provide an
 129  * editable view of data taken from a database and how to modify
 130  * the columns in the display to use specialized renderers and editors.
 131  * <p>
 132  * The <code>JTable</code> uses integers exclusively to refer to both the rows and the columns
 133  * of the model that it displays. The <code>JTable</code> simply takes a tabular range of cells
 134  * and uses <code>getValueAt(int, int)</code> to retrieve the
 135  * values from the model during painting.  It is important to remember that
 136  * the column and row indexes returned by various <code>JTable</code> methods
 137  * are in terms of the <code>JTable</code> (the view) and are not
 138  * necessarily the same indexes used by the model.
 139  * <p>
 140  * By default, columns may be rearranged in the <code>JTable</code> so that the
 141  * view's columns appear in a different order to the columns in the model.
 142  * This does not affect the implementation of the model at all: when the
 143  * columns are reordered, the <code>JTable</code> maintains the new order of the columns
 144  * internally and converts its column indices before querying the model.
 145  * <p>
 146  * So, when writing a <code>TableModel</code>, it is not necessary to listen for column
 147  * reordering events as the model will be queried in its own coordinate
 148  * system regardless of what is happening in the view.
 149  * In the examples area there is a demonstration of a sorting algorithm making
 150  * use of exactly this technique to interpose yet another coordinate system
 151  * where the order of the rows is changed, rather than the order of the columns.
 152  * <p>
 153  * Similarly when using the sorting and filtering functionality
 154  * provided by <code>RowSorter</code> the underlying
 155  * <code>TableModel</code> does not need to know how to do sorting,
 156  * rather <code>RowSorter</code> will handle it.  Coordinate
 157  * conversions will be necessary when using the row based methods of
 158  * <code>JTable</code> with the underlying <code>TableModel</code>.
 159  * All of <code>JTable</code>s row based methods are in terms of the
 160  * <code>RowSorter</code>, which is not necessarily the same as that
 161  * of the underlying <code>TableModel</code>.  For example, the
 162  * selection is always in terms of <code>JTable</code> so that when
 163  * using <code>RowSorter</code> you will need to convert using
 164  * <code>convertRowIndexToView</code> or
 165  * <code>convertRowIndexToModel</code>.  The following shows how to
 166  * convert coordinates from <code>JTable</code> to that of the
 167  * underlying model:
 168  * <pre>
 169  *   int[] selection = table.getSelectedRows();
 170  *   for (int i = 0; i &lt; selection.length; i++) {
 171  *     selection[i] = table.convertRowIndexToModel(selection[i]);
 172  *   }
 173  *   // selection is now in terms of the underlying TableModel
 174  * </pre>
 175  * <p>
 176  * By default if sorting is enabled <code>JTable</code> will persist the
 177  * selection and variable row heights in terms of the model on
 178  * sorting.  For example if row 0, in terms of the underlying model,
 179  * is currently selected, after the sort row 0, in terms of the
 180  * underlying model will be selected.  Visually the selection may
 181  * change, but in terms of the underlying model it will remain the
 182  * same.  The one exception to that is if the model index is no longer
 183  * visible or was removed.  For example, if row 0 in terms of model
 184  * was filtered out the selection will be empty after the sort.
 185  * <p>
 186  * J2SE 5 adds methods to <code>JTable</code> to provide convenient access to some
 187  * common printing needs. Simple new {@link #print()} methods allow for quick
 188  * and easy addition of printing support to your application. In addition, a new
 189  * {@link #getPrintable} method is available for more advanced printing needs.
 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  *
 211  * @beaninfo
 212  *   attribute: isContainer false
 213  * description: A component which displays data in a two dimensional grid.
 214  *
 215  * @author Philip Milne
 216  * @author Shannon Hickey (printing support)
 217  * @see javax.swing.table.DefaultTableModel
 218  * @see javax.swing.table.TableRowSorter
 219  * @since 1.2
 220  */
 221 /* The first versions of the JTable, contained in Swing-0.1 through
 222  * Swing-0.4, were written by Alan Chung.
 223  */
 224 @SuppressWarnings("serial") // Same-version serialization only
 225 public class JTable extends JComponent implements TableModelListener, Scrollable,
 226     TableColumnModelListener, ListSelectionListener, CellEditorListener,
 227     Accessible, RowSorterListener


 237     private static final String uiClassID = "TableUI";
 238 
 239     /** Do not adjust column widths automatically; use a horizontal scrollbar instead. */
 240     public static final int     AUTO_RESIZE_OFF = 0;
 241 
 242     /** When a column is adjusted in the UI, adjust the next column the opposite way. */
 243     public static final int     AUTO_RESIZE_NEXT_COLUMN = 1;
 244 
 245     /** During UI adjustment, change subsequent columns to preserve the total width;
 246       * this is the default behavior. */
 247     public static final int     AUTO_RESIZE_SUBSEQUENT_COLUMNS = 2;
 248 
 249     /** During all resize operations, apply adjustments to the last column only. */
 250     public static final int     AUTO_RESIZE_LAST_COLUMN = 3;
 251 
 252     /** During all resize operations, proportionately resize all columns. */
 253     public static final int     AUTO_RESIZE_ALL_COLUMNS = 4;
 254 
 255 
 256     /**
 257      * Printing modes, used in printing <code>JTable</code>s.
 258      *
 259      * @see #print(JTable.PrintMode, MessageFormat, MessageFormat,
 260      *             boolean, PrintRequestAttributeSet, boolean)
 261      * @see #getPrintable
 262      * @since 1.5
 263      */
 264     public enum PrintMode {
 265 
 266         /**
 267          * Printing mode that prints the table at its current size,
 268          * spreading both columns and rows across multiple pages if necessary.
 269          */
 270         NORMAL,
 271 
 272         /**
 273          * Printing mode that scales the output smaller, if necessary,
 274          * to fit the table's entire width (and thereby all columns) on each page;
 275          * Rows are spread across multiple pages as necessary.
 276          */
 277         FIT_WIDTH
 278     }
 279 
 280 
 281 //
 282 // Instance Variables
 283 //
 284 
 285     /** The <code>TableModel</code> of the table. */
 286     protected TableModel        dataModel;
 287 
 288     /** The <code>TableColumnModel</code> of the table. */
 289     protected TableColumnModel  columnModel;
 290 
 291     /** The <code>ListSelectionModel</code> of the table, used to keep track of row selections. */
 292     protected ListSelectionModel selectionModel;
 293 
 294     /** The <code>TableHeader</code> working with the table. */
 295     protected JTableHeader      tableHeader;
 296 
 297     /** The height in pixels of each row in the table. */
 298     protected int               rowHeight;
 299 
 300     /** The height in pixels of the margin between the cells in each row. */
 301     protected int               rowMargin;
 302 
 303     /** The color of the grid. */
 304     protected Color             gridColor;
 305 
 306     /** The table draws horizontal lines between cells if <code>showHorizontalLines</code> is true. */
 307     protected boolean           showHorizontalLines;
 308 
 309     /** The table draws vertical lines between cells if <code>showVerticalLines</code> is true. */
 310     protected boolean           showVerticalLines;
 311 
 312     /**
 313      *  Determines if the table automatically resizes the
 314      *  width of the table's columns to take up the entire width of the
 315      *  table, and how it does the resizing.
 316      */
 317     protected int               autoResizeMode;
 318 
 319     /**
 320      *  The table will query the <code>TableModel</code> to build the default
 321      *  set of columns if this is true.
 322      */
 323     protected boolean           autoCreateColumnsFromModel;
 324 
 325     /** Used by the <code>Scrollable</code> interface to determine the initial visible area. */
 326     protected Dimension         preferredViewportSize;
 327 
 328     /** True if row selection is allowed in this table. */
 329     protected boolean           rowSelectionAllowed;
 330 
 331     /**
 332      * Obsolete as of Java 2 platform v1.3.  Please use the
 333      * <code>rowSelectionAllowed</code> property and the
 334      * <code>columnSelectionAllowed</code> property of the
 335      * <code>columnModel</code> instead. Or use the
 336      * method <code>getCellSelectionEnabled</code>.
 337      */
 338     /*
 339      * If true, both a row selection and a column selection
 340      * can be non-empty at the same time, the selected cells are the
 341      * the cells whose row and column are both selected.
 342      */
 343     protected boolean           cellSelectionEnabled;
 344 
 345     /** If editing, the <code>Component</code> that is handling the editing. */
 346     protected transient Component       editorComp;
 347 
 348     /**
 349      * The active cell editor object, that overwrites the screen real estate
 350      * occupied by the current cell and allows the user to change its contents.
 351      * {@code null} if the table isn't currently editing.
 352      */
 353     protected transient TableCellEditor cellEditor;
 354 
 355     /** Identifies the column of the cell being edited. */
 356     protected transient int             editingColumn;
 357 
 358     /** Identifies the row of the cell being edited. */
 359     protected transient int             editingRow;
 360 
 361    /**
 362      * A table of objects that display the contents of a cell,
 363      * indexed by class as declared in <code>getColumnClass</code>
 364      * in the <code>TableModel</code> interface.
 365      */
 366     protected transient Hashtable<Object, Object> defaultRenderersByColumnClass;
 367     // Logicaly, the above is a Hashtable<Class<?>, TableCellRenderer>.
 368     // It is declared otherwise to accomodate using UIDefaults.
 369 
 370     /**
 371      * A table of objects that display and edit the contents of a cell,
 372      * indexed by class as declared in <code>getColumnClass</code>
 373      * in the <code>TableModel</code> interface.
 374      */
 375     protected transient Hashtable<Object, Object> defaultEditorsByColumnClass;
 376     // Logicaly, the above is a Hashtable<Class<?>, TableCellEditor>.
 377     // It is declared otherwise to accomodate using UIDefaults.
 378 
 379     /** The foreground color of selected cells. */
 380     protected Color selectionForeground;
 381 
 382     /** The background color of selected cells. */
 383     protected Color selectionBackground;
 384 
 385 //
 386 // Private state
 387 //
 388 
 389     // WARNING: If you directly access this field you should also change the
 390     // SortManager.modelRowSizes field as well.
 391     private SizeSequence rowModel;
 392     private boolean dragEnabled;
 393     private boolean surrendersFocusOnKeystroke;


 440     private boolean autoCreateRowSorter;
 441 
 442     /**
 443      * Whether or not the table always fills the viewport height.
 444      * @see #setFillsViewportHeight
 445      * @see #getScrollableTracksViewportHeight
 446      */
 447     private boolean fillsViewportHeight;
 448 
 449     /**
 450      * The drop mode for this component.
 451      */
 452     private DropMode dropMode = DropMode.USE_SELECTION;
 453 
 454     /**
 455      * The drop location.
 456      */
 457     private transient DropLocation dropLocation;
 458 
 459     /**
 460      * A subclass of <code>TransferHandler.DropLocation</code> representing
 461      * a drop location for a <code>JTable</code>.
 462      *
 463      * @see #getDropLocation
 464      * @since 1.6
 465      */
 466     public static final class DropLocation extends TransferHandler.DropLocation {
 467         private final int row;
 468         private final int col;
 469         private final boolean isInsertRow;
 470         private final boolean isInsertCol;
 471 
 472         private DropLocation(Point p, int row, int col,
 473                              boolean isInsertRow, boolean isInsertCol) {
 474 
 475             super(p);
 476             this.row = row;
 477             this.col = col;
 478             this.isInsertRow = isInsertRow;
 479             this.isInsertCol = isInsertCol;
 480         }
 481 
 482         /**
 483          * Returns the row index where a dropped item should be placed in the
 484          * table. Interpretation of the value depends on the return of
 485          * <code>isInsertRow()</code>. If that method returns
 486          * <code>true</code> this value indicates the index where a new
 487          * row should be inserted. Otherwise, it represents the value
 488          * of an existing row on which the data was dropped. This index is
 489          * in terms of the view.
 490          * <p>
 491          * <code>-1</code> indicates that the drop occurred over empty space,
 492          * and no row could be calculated.
 493          *
 494          * @return the drop row
 495          */
 496         public int getRow() {
 497             return row;
 498         }
 499 
 500         /**
 501          * Returns the column index where a dropped item should be placed in the
 502          * table. Interpretation of the value depends on the return of
 503          * <code>isInsertColumn()</code>. If that method returns
 504          * <code>true</code> this value indicates the index where a new
 505          * column should be inserted. Otherwise, it represents the value
 506          * of an existing column on which the data was dropped. This index is
 507          * in terms of the view.
 508          * <p>
 509          * <code>-1</code> indicates that the drop occurred over empty space,
 510          * and no column could be calculated.
 511          *
 512          * @return the drop row
 513          */
 514         public int getColumn() {
 515             return col;
 516         }
 517 
 518         /**
 519          * Returns whether or not this location represents an insert
 520          * of a row.
 521          *
 522          * @return whether or not this is an insert row
 523          */
 524         public boolean isInsertRow() {
 525             return isInsertRow;
 526         }
 527 
 528         /**
 529          * Returns whether or not this location represents an insert


 541          * and the content and format of the returned string may vary
 542          * between implementations.
 543          *
 544          * @return a string representation of this drop location
 545          */
 546         public String toString() {
 547             return getClass().getName()
 548                    + "[dropPoint=" + getDropPoint() + ","
 549                    + "row=" + row + ","
 550                    + "column=" + col + ","
 551                    + "insertRow=" + isInsertRow + ","
 552                    + "insertColumn=" + isInsertCol + "]";
 553         }
 554     }
 555 
 556 //
 557 // Constructors
 558 //
 559 
 560     /**
 561      * Constructs a default <code>JTable</code> that is initialized with a default
 562      * data model, a default column model, and a default selection
 563      * model.
 564      *
 565      * @see #createDefaultDataModel
 566      * @see #createDefaultColumnModel
 567      * @see #createDefaultSelectionModel
 568      */
 569     public JTable() {
 570         this(null, null, null);
 571     }
 572 
 573     /**
 574      * Constructs a <code>JTable</code> that is initialized with
 575      * <code>dm</code> as the data model, a default column model,
 576      * and a default selection model.
 577      *
 578      * @param dm        the data model for the table
 579      * @see #createDefaultColumnModel
 580      * @see #createDefaultSelectionModel
 581      */
 582     public JTable(TableModel dm) {
 583         this(dm, null, null);
 584     }
 585 
 586     /**
 587      * Constructs a <code>JTable</code> that is initialized with
 588      * <code>dm</code> as the data model, <code>cm</code>
 589      * as the column model, and a default selection model.
 590      *
 591      * @param dm        the data model for the table
 592      * @param cm        the column model for the table
 593      * @see #createDefaultSelectionModel
 594      */
 595     public JTable(TableModel dm, TableColumnModel cm) {
 596         this(dm, cm, null);
 597     }
 598 
 599     /**
 600      * Constructs a <code>JTable</code> that is initialized with
 601      * <code>dm</code> as the data model, <code>cm</code> as the
 602      * column model, and <code>sm</code> as the selection model.
 603      * If any of the parameters are <code>null</code> this method
 604      * will initialize the table with the corresponding default model.
 605      * The <code>autoCreateColumnsFromModel</code> flag is set to false
 606      * if <code>cm</code> is non-null, otherwise it is set to true
 607      * and the column model is populated with suitable
 608      * <code>TableColumns</code> for the columns in <code>dm</code>.
 609      *
 610      * @param dm        the data model for the table
 611      * @param cm        the column model for the table
 612      * @param sm        the row selection model for the table
 613      * @see #createDefaultDataModel
 614      * @see #createDefaultColumnModel
 615      * @see #createDefaultSelectionModel
 616      */
 617     public JTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) {
 618         super();
 619         setLayout(null);
 620 
 621         setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
 622                            JComponent.getManagingFocusForwardTraversalKeys());
 623         setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
 624                            JComponent.getManagingFocusBackwardTraversalKeys());
 625         if (cm == null) {
 626             cm = createDefaultColumnModel();
 627             autoCreateColumnsFromModel = true;
 628         }
 629         setColumnModel(cm);
 630 
 631         if (sm == null) {
 632             sm = createDefaultSelectionModel();
 633         }
 634         setSelectionModel(sm);
 635 
 636     // Set the model last, that way if the autoCreatColumnsFromModel has
 637     // been set above, we will automatically populate an empty columnModel
 638     // with suitable columns for the new model.
 639         if (dm == null) {
 640             dm = createDefaultDataModel();
 641         }
 642         setModel(dm);
 643 
 644         initializeLocalVars();
 645         updateUI();
 646     }
 647 
 648     /**
 649      * Constructs a <code>JTable</code> with <code>numRows</code>
 650      * and <code>numColumns</code> of empty cells using
 651      * <code>DefaultTableModel</code>.  The columns will have
 652      * names of the form "A", "B", "C", etc.
 653      *
 654      * @param numRows           the number of rows the table holds
 655      * @param numColumns        the number of columns the table holds
 656      * @see javax.swing.table.DefaultTableModel
 657      */
 658     public JTable(int numRows, int numColumns) {
 659         this(new DefaultTableModel(numRows, numColumns));
 660     }
 661 
 662     /**
 663      * Constructs a <code>JTable</code> to display the values in the
 664      * <code>Vector</code> of <code>Vectors</code>, <code>rowData</code>,
 665      * with column names, <code>columnNames</code>.  The
 666      * <code>Vectors</code> contained in <code>rowData</code>
 667      * should contain the values for that row. In other words,
 668      * the value of the cell at row 1, column 5 can be obtained
 669      * with the following code:
 670      *
 671      * <pre>((Vector)rowData.elementAt(1)).elementAt(5);</pre>
 672      *
 673      * @param rowData           the data for the new table
 674      * @param columnNames       names of each column
 675      */
 676     @SuppressWarnings("rawtypes")
 677     public JTable(Vector<? extends Vector> rowData, Vector<?> columnNames) {
 678         this(new DefaultTableModel(rowData, columnNames));
 679     }
 680 
 681     /**
 682      * Constructs a <code>JTable</code> to display the values in the two dimensional array,
 683      * <code>rowData</code>, with column names, <code>columnNames</code>.
 684      * <code>rowData</code> is an array of rows, so the value of the cell at row 1,
 685      * column 5 can be obtained with the following code:
 686      *
 687      * <pre> rowData[1][5]; </pre>
 688      * <p>
 689      * All rows must be of the same length as <code>columnNames</code>.
 690      *
 691      * @param rowData           the data for the new table
 692      * @param columnNames       names of each column
 693      */
 694     public JTable(final Object[][] rowData, final Object[] columnNames) {
 695         this(new AbstractTableModel() {
 696             public String getColumnName(int column) { return columnNames[column].toString(); }
 697             public int getRowCount() { return rowData.length; }
 698             public int getColumnCount() { return columnNames.length; }
 699             public Object getValueAt(int row, int col) { return rowData[row][col]; }
 700             public boolean isCellEditable(int row, int column) { return true; }
 701             public void setValueAt(Object value, int row, int col) {
 702                 rowData[row][col] = value;
 703                 fireTableCellUpdated(row, col);
 704             }
 705         });
 706     }
 707 
 708     /**
 709      * Calls the <code>configureEnclosingScrollPane</code> method.
 710      *
 711      * @see #configureEnclosingScrollPane
 712      */
 713     public void addNotify() {
 714         super.addNotify();
 715         configureEnclosingScrollPane();
 716     }
 717 
 718     /**
 719      * If this <code>JTable</code> is the <code>viewportView</code> of an enclosing <code>JScrollPane</code>
 720      * (the usual situation), configure this <code>ScrollPane</code> by, amongst other things,
 721      * installing the table's <code>tableHeader</code> as the <code>columnHeaderView</code> of the scroll pane.
 722      * When a <code>JTable</code> is added to a <code>JScrollPane</code> in the usual way,
 723      * using <code>new JScrollPane(myTable)</code>, <code>addNotify</code> is
 724      * called in the <code>JTable</code> (when the table is added to the viewport).
 725      * <code>JTable</code>'s <code>addNotify</code> method in turn calls this method,
 726      * which is protected so that this default installation procedure can
 727      * be overridden by a subclass.
 728      *
 729      * @see #addNotify
 730      */
 731     protected void configureEnclosingScrollPane() {
 732         Container parent = SwingUtilities.getUnwrappedParent(this);
 733         if (parent instanceof JViewport) {
 734             JViewport port = (JViewport) parent;
 735             Container gp = port.getParent();
 736             if (gp instanceof JScrollPane) {
 737                 JScrollPane scrollPane = (JScrollPane)gp;
 738                 // Make certain we are the viewPort's view and not, for
 739                 // example, the rowHeaderView of the scrollPane -
 740                 // an implementor of fixed columns might do this.
 741                 JViewport viewport = scrollPane.getViewport();
 742                 if (viewport == null ||
 743                         SwingUtilities.getUnwrappedView(viewport) != this) {
 744                     return;
 745                 }


 788                 }
 789                 // add JScrollBar corner component if available from LAF and not already set by the user
 790                 Component corner =
 791                         scrollPane.getCorner(JScrollPane.UPPER_TRAILING_CORNER);
 792                 if (corner == null || corner instanceof UIResource){
 793                     corner = null;
 794                     try {
 795                         corner = (Component) UIManager.get(
 796                                 "Table.scrollPaneCornerComponent");
 797                     } catch (Exception e) {
 798                         // just ignore and don't set corner
 799                     }
 800                     scrollPane.setCorner(JScrollPane.UPPER_TRAILING_CORNER,
 801                             corner);
 802                 }
 803             }
 804         }
 805     }
 806 
 807     /**
 808      * Calls the <code>unconfigureEnclosingScrollPane</code> method.
 809      *
 810      * @see #unconfigureEnclosingScrollPane
 811      */
 812     public void removeNotify() {
 813         KeyboardFocusManager.getCurrentKeyboardFocusManager().
 814             removePropertyChangeListener("permanentFocusOwner", editorRemover);
 815         editorRemover = null;
 816         unconfigureEnclosingScrollPane();
 817         super.removeNotify();
 818     }
 819 
 820     /**
 821      * Reverses the effect of <code>configureEnclosingScrollPane</code>
 822      * by replacing the <code>columnHeaderView</code> of the enclosing
 823      * scroll pane with <code>null</code>. <code>JTable</code>'s
 824      * <code>removeNotify</code> method calls
 825      * this method, which is protected so that this default uninstallation
 826      * procedure can be overridden by a subclass.
 827      *
 828      * @see #removeNotify
 829      * @see #configureEnclosingScrollPane
 830      * @since 1.3
 831      */
 832     protected void unconfigureEnclosingScrollPane() {
 833         Container parent = SwingUtilities.getUnwrappedParent(this);
 834         if (parent instanceof JViewport) {
 835             JViewport port = (JViewport) parent;
 836             Container gp = port.getParent();
 837             if (gp instanceof JScrollPane) {
 838                 JScrollPane scrollPane = (JScrollPane)gp;
 839                 // Make certain we are the viewPort's view and not, for
 840                 // example, the rowHeaderView of the scrollPane -
 841                 // an implementor of fixed columns might do this.
 842                 JViewport viewport = scrollPane.getViewport();
 843                 if (viewport == null ||
 844                         SwingUtilities.getUnwrappedView(viewport) != this) {


 855             }
 856         }
 857     }
 858 
 859     void setUIProperty(String propertyName, Object value) {
 860         if (propertyName == "rowHeight") {
 861             if (!isRowHeightSet) {
 862                 setRowHeight(((Number)value).intValue());
 863                 isRowHeightSet = false;
 864             }
 865             return;
 866         }
 867         super.setUIProperty(propertyName, value);
 868     }
 869 
 870 //
 871 // Static Methods
 872 //
 873 
 874     /**
 875      * Equivalent to <code>new JScrollPane(aTable)</code>.
 876      *
 877      * @param aTable a {@code JTable} to be used for the scroll pane
 878      * @return a {@code JScrollPane} created using {@code aTable}
 879      * @deprecated As of Swing version 1.0.2,
 880      * replaced by <code>new JScrollPane(aTable)</code>.
 881      */
 882     @Deprecated
 883     public static JScrollPane createScrollPaneForTable(JTable aTable) {
 884         return new JScrollPane(aTable);
 885     }
 886 
 887 //
 888 // Table Attributes
 889 //
 890 
 891     /**
 892      * Sets the <code>tableHeader</code> working with this <code>JTable</code> to <code>newHeader</code>.
 893      * It is legal to have a <code>null</code> <code>tableHeader</code>.
 894      *
 895      * @param   tableHeader                       new tableHeader
 896      * @see     #getTableHeader
 897      * @beaninfo
 898      *  bound: true
 899      *  description: The JTableHeader instance which renders the column headers.
 900      */
 901     public void setTableHeader(JTableHeader tableHeader) {
 902         if (this.tableHeader != tableHeader) {
 903             JTableHeader old = this.tableHeader;
 904             // Release the old header
 905             if (old != null) {
 906                 old.setTable(null);
 907             }
 908             this.tableHeader = tableHeader;
 909             if (tableHeader != null) {
 910                 tableHeader.setTable(this);
 911             }
 912             firePropertyChange("tableHeader", old, tableHeader);
 913         }
 914     }
 915 
 916     /**
 917      * Returns the <code>tableHeader</code> used by this <code>JTable</code>.
 918      *
 919      * @return  the <code>tableHeader</code> used by this table
 920      * @see     #setTableHeader
 921      */
 922     public JTableHeader getTableHeader() {
 923         return tableHeader;
 924     }
 925 
 926     /**
 927      * Sets the height, in pixels, of all cells to <code>rowHeight</code>,
 928      * revalidates, and repaints.
 929      * The height of the cells will be equal to the row height minus
 930      * the row margin.
 931      *
 932      * @param   rowHeight                       new row height
 933      * @exception IllegalArgumentException      if <code>rowHeight</code> is
 934      *                                          less than 1
 935      * @see     #getRowHeight
 936      * @beaninfo
 937      *  bound: true
 938      *  description: The height of the specified row.
 939      */
 940     public void setRowHeight(int rowHeight) {
 941         if (rowHeight <= 0) {
 942             throw new IllegalArgumentException("New row height less than 1");
 943         }
 944         int old = this.rowHeight;
 945         this.rowHeight = rowHeight;
 946         rowModel = null;
 947         if (sortManager != null) {
 948             sortManager.modelRowSizes = null;
 949         }
 950         isRowHeightSet = true;
 951         resizeAndRepaint();
 952         firePropertyChange("rowHeight", old, rowHeight);
 953     }
 954 
 955     /**
 956      * Returns the height of a table row, in pixels.
 957      *
 958      * @return  the height in pixels of a table row
 959      * @see     #setRowHeight
 960      */
 961     public int getRowHeight() {
 962         return rowHeight;
 963     }
 964 
 965     private SizeSequence getRowModel() {
 966         if (rowModel == null) {
 967             rowModel = new SizeSequence(getRowCount(), getRowHeight());
 968         }
 969         return rowModel;
 970     }
 971 
 972     /**
 973      * Sets the height for <code>row</code> to <code>rowHeight</code>,
 974      * revalidates, and repaints. The height of the cells in this row
 975      * will be equal to the row height minus the row margin.
 976      *
 977      * @param   row                             the row whose height is being
 978                                                 changed
 979      * @param   rowHeight                       new row height, in pixels
 980      * @exception IllegalArgumentException      if <code>rowHeight</code> is
 981      *                                          less than 1
 982      * @beaninfo
 983      *  bound: true
 984      *  description: The height in pixels of the cells in <code>row</code>
 985      * @since 1.3
 986      */
 987     public void setRowHeight(int row, int rowHeight) {
 988         if (rowHeight <= 0) {
 989             throw new IllegalArgumentException("New row height less than 1");
 990         }
 991         getRowModel().setSize(row, rowHeight);
 992         if (sortManager != null) {
 993             sortManager.setViewRowHeight(row, rowHeight);
 994         }
 995         resizeAndRepaint();
 996     }
 997 
 998     /**
 999      * Returns the height, in pixels, of the cells in <code>row</code>.
1000      * @param   row              the row whose height is to be returned
1001      * @return the height, in pixels, of the cells in the row
1002      * @since 1.3
1003      */
1004     public int getRowHeight(int row) {
1005         return (rowModel == null) ? getRowHeight() : rowModel.getSize(row);
1006     }
1007 
1008     /**
1009      * Sets the amount of empty space between cells in adjacent rows.
1010      *
1011      * @param  rowMargin  the number of pixels between cells in a row
1012      * @see     #getRowMargin
1013      * @beaninfo
1014      *  bound: true
1015      *  description: The amount of space between cells.
1016      */
1017     public void setRowMargin(int rowMargin) {
1018         int old = this.rowMargin;
1019         this.rowMargin = rowMargin;
1020         resizeAndRepaint();
1021         firePropertyChange("rowMargin", old, rowMargin);
1022     }
1023 
1024     /**
1025      * Gets the amount of empty space, in pixels, between cells. Equivalent to:
1026      * <code>getIntercellSpacing().height</code>.
1027      * @return the number of pixels between cells in a row
1028      *
1029      * @see     #setRowMargin
1030      */
1031     public int getRowMargin() {
1032         return rowMargin;
1033     }
1034 
1035     /**
1036      * Sets the <code>rowMargin</code> and the <code>columnMargin</code> --
1037      * the height and width of the space between cells -- to
1038      * <code>intercellSpacing</code>.
1039      *
1040      * @param   intercellSpacing        a <code>Dimension</code>
1041      *                                  specifying the new width
1042      *                                  and height between cells
1043      * @see     #getIntercellSpacing
1044      * @beaninfo
1045      *  description: The spacing between the cells,
1046      *               drawn in the background color of the JTable.
1047      */
1048     public void setIntercellSpacing(Dimension intercellSpacing) {
1049         // Set the rowMargin here and columnMargin in the TableColumnModel
1050         setRowMargin(intercellSpacing.height);
1051         getColumnModel().setColumnMargin(intercellSpacing.width);
1052 
1053         resizeAndRepaint();
1054     }
1055 
1056     /**
1057      * Returns the horizontal and vertical space between cells.
1058      * The default spacing is look and feel dependent.
1059      *
1060      * @return  the horizontal and vertical spacing between cells
1061      * @see     #setIntercellSpacing
1062      */
1063     public Dimension getIntercellSpacing() {
1064         return new Dimension(getColumnModel().getColumnMargin(), rowMargin);
1065     }
1066 
1067     /**
1068      * Sets the color used to draw grid lines to <code>gridColor</code> and redisplays.
1069      * The default color is look and feel dependent.
1070      *
1071      * @param   gridColor                       the new color of the grid lines
1072      * @exception IllegalArgumentException      if <code>gridColor</code> is <code>null</code>
1073      * @see     #getGridColor
1074      * @beaninfo
1075      *  bound: true
1076      *  description: The grid color.
1077      */
1078     public void setGridColor(Color gridColor) {
1079         if (gridColor == null) {
1080             throw new IllegalArgumentException("New color is null");
1081         }
1082         Color old = this.gridColor;
1083         this.gridColor = gridColor;
1084         firePropertyChange("gridColor", old, gridColor);
1085         // Redraw
1086         repaint();
1087     }
1088 
1089     /**
1090      * Returns the color used to draw grid lines.
1091      * The default color is look and feel dependent.
1092      *
1093      * @return  the color used to draw grid lines
1094      * @see     #setGridColor
1095      */
1096     public Color getGridColor() {
1097         return gridColor;
1098     }
1099 
1100     /**
1101      *  Sets whether the table draws grid lines around cells.
1102      *  If <code>showGrid</code> is true it does; if it is false it doesn't.
1103      *  There is no <code>getShowGrid</code> method as this state is held
1104      *  in two variables -- <code>showHorizontalLines</code> and <code>showVerticalLines</code> --
1105      *  each of which can be queried independently.
1106      *
1107      * @param   showGrid                 true if table view should draw grid lines
1108      *
1109      * @see     #setShowVerticalLines
1110      * @see     #setShowHorizontalLines
1111      * @beaninfo
1112      *  description: The color used to draw the grid lines.
1113      */
1114     public void setShowGrid(boolean showGrid) {
1115         setShowHorizontalLines(showGrid);
1116         setShowVerticalLines(showGrid);
1117 
1118         // Redraw
1119         repaint();
1120     }
1121 
1122     /**
1123      *  Sets whether the table draws horizontal lines between cells.
1124      *  If <code>showHorizontalLines</code> is true it does; if it is false it doesn't.
1125      *
1126      * @param   showHorizontalLines      true if table view should draw horizontal lines
1127      * @see     #getShowHorizontalLines
1128      * @see     #setShowGrid
1129      * @see     #setShowVerticalLines
1130      * @beaninfo
1131      *  bound: true
1132      *  description: Whether horizontal lines should be drawn in between the cells.
1133      */
1134     public void setShowHorizontalLines(boolean showHorizontalLines) {
1135         boolean old = this.showHorizontalLines;
1136         this.showHorizontalLines = showHorizontalLines;
1137         firePropertyChange("showHorizontalLines", old, showHorizontalLines);
1138 
1139         // Redraw
1140         repaint();
1141     }
1142 
1143     /**
1144      *  Sets whether the table draws vertical lines between cells.
1145      *  If <code>showVerticalLines</code> is true it does; if it is false it doesn't.
1146      *
1147      * @param   showVerticalLines              true if table view should draw vertical lines
1148      * @see     #getShowVerticalLines
1149      * @see     #setShowGrid
1150      * @see     #setShowHorizontalLines
1151      * @beaninfo
1152      *  bound: true
1153      *  description: Whether vertical lines should be drawn in between the cells.
1154      */
1155     public void setShowVerticalLines(boolean showVerticalLines) {
1156         boolean old = this.showVerticalLines;
1157         this.showVerticalLines = showVerticalLines;
1158         firePropertyChange("showVerticalLines", old, showVerticalLines);
1159         // Redraw
1160         repaint();
1161     }
1162 
1163     /**
1164      * Returns true if the table draws horizontal lines between cells, false if it
1165      * doesn't. The default value is look and feel dependent.


1224                 || (mode == AUTO_RESIZE_NEXT_COLUMN)
1225                 || (mode == AUTO_RESIZE_SUBSEQUENT_COLUMNS)
1226                 || (mode == AUTO_RESIZE_LAST_COLUMN)
1227                 || (mode == AUTO_RESIZE_ALL_COLUMNS);
1228     }
1229 
1230     /**
1231      * Returns the auto resize mode of the table.  The default mode
1232      * is AUTO_RESIZE_SUBSEQUENT_COLUMNS.
1233      *
1234      * @return  the autoResizeMode of the table
1235      *
1236      * @see     #setAutoResizeMode
1237      * @see     #doLayout
1238      */
1239     public int getAutoResizeMode() {
1240         return autoResizeMode;
1241     }
1242 
1243     /**
1244      * Sets this table's <code>autoCreateColumnsFromModel</code> flag.
1245      * This method calls <code>createDefaultColumnsFromModel</code> if
1246      * <code>autoCreateColumnsFromModel</code> changes from false to true.
1247      *
1248      * @param   autoCreateColumnsFromModel   true if <code>JTable</code> should automatically create columns
1249      * @see     #getAutoCreateColumnsFromModel
1250      * @see     #createDefaultColumnsFromModel
1251      * @beaninfo
1252      *  bound: true
1253      *  description: Automatically populates the columnModel when a new TableModel is submitted.
1254      */
1255     public void setAutoCreateColumnsFromModel(boolean autoCreateColumnsFromModel) {
1256         if (this.autoCreateColumnsFromModel != autoCreateColumnsFromModel) {
1257             boolean old = this.autoCreateColumnsFromModel;
1258             this.autoCreateColumnsFromModel = autoCreateColumnsFromModel;
1259             if (autoCreateColumnsFromModel) {
1260                 createDefaultColumnsFromModel();
1261             }
1262             firePropertyChange("autoCreateColumnsFromModel", old, autoCreateColumnsFromModel);
1263         }
1264     }
1265 
1266     /**
1267      * Determines whether the table will create default columns from the model.
1268      * If true, <code>setModel</code> will clear any existing columns and
1269      * create new columns from the new model.  Also, if the event in
1270      * the <code>tableChanged</code> notification specifies that the
1271      * entire table changed, then the columns will be rebuilt.
1272      * The default is true.
1273      *
1274      * @return  the autoCreateColumnsFromModel of the table
1275      * @see     #setAutoCreateColumnsFromModel
1276      * @see     #createDefaultColumnsFromModel
1277      */
1278     public boolean getAutoCreateColumnsFromModel() {
1279         return autoCreateColumnsFromModel;
1280     }
1281 
1282     /**
1283      * Creates default columns for the table from
1284      * the data model using the <code>getColumnCount</code> method
1285      * defined in the <code>TableModel</code> interface.
1286      * <p>
1287      * Clears any existing columns before creating the
1288      * new columns based on information from the model.
1289      *
1290      * @see     #getAutoCreateColumnsFromModel
1291      */
1292     public void createDefaultColumnsFromModel() {
1293         TableModel m = getModel();
1294         if (m != null) {
1295             // Remove any current columns
1296             TableColumnModel cm = getColumnModel();
1297             while (cm.getColumnCount() > 0) {
1298                 cm.removeColumn(cm.getColumn(0));
1299             }
1300 
1301             // Create new columns from the data model info
1302             for (int i = 0; i < m.getColumnCount(); i++) {
1303                 TableColumn newColumn = new TableColumn(i);
1304                 addColumn(newColumn);
1305             }
1306         }
1307     }
1308 
1309     /**
1310      * Sets a default cell renderer to be used if no renderer has been set in
1311      * a <code>TableColumn</code>. If renderer is <code>null</code>,
1312      * removes the default renderer for this column class.
1313      *
1314      * @param  columnClass     set the default cell renderer for this columnClass
1315      * @param  renderer        default cell renderer to be used for this
1316      *                         columnClass
1317      * @see     #getDefaultRenderer
1318      * @see     #setDefaultEditor
1319      */
1320     public void setDefaultRenderer(Class<?> columnClass, TableCellRenderer renderer) {
1321         if (renderer != null) {
1322             defaultRenderersByColumnClass.put(columnClass, renderer);
1323         }
1324         else {
1325             defaultRenderersByColumnClass.remove(columnClass);
1326         }
1327     }
1328 
1329     /**
1330      * Returns the cell renderer to be used when no renderer has been set in
1331      * a <code>TableColumn</code>. During the rendering of cells the renderer is fetched from
1332      * a <code>Hashtable</code> of entries according to the class of the cells in the column. If
1333      * there is no entry for this <code>columnClass</code> the method returns
1334      * the entry for the most specific superclass. The <code>JTable</code> installs entries
1335      * for <code>Object</code>, <code>Number</code>, and <code>Boolean</code>, all of which can be modified
1336      * or replaced.
1337      *
1338      * @param   columnClass   return the default cell renderer
1339      *                        for this columnClass
1340      * @return  the renderer for this columnClass
1341      * @see     #setDefaultRenderer
1342      * @see     #getColumnClass
1343      */
1344     public TableCellRenderer getDefaultRenderer(Class<?> columnClass) {
1345         if (columnClass == null) {
1346             return null;
1347         }
1348         else {
1349             Object renderer = defaultRenderersByColumnClass.get(columnClass);
1350             if (renderer != null) {
1351                 return (TableCellRenderer)renderer;
1352             }
1353             else {
1354                 Class<?> c = columnClass.getSuperclass();
1355                 if (c == null && columnClass != Object.class) {
1356                     c = Object.class;
1357                 }
1358                 return getDefaultRenderer(c);
1359             }
1360         }
1361     }
1362 
1363     /**
1364      * Sets a default cell editor to be used if no editor has been set in
1365      * a <code>TableColumn</code>. If no editing is required in a table, or a
1366      * particular column in a table, uses the <code>isCellEditable</code>
1367      * method in the <code>TableModel</code> interface to ensure that this
1368      * <code>JTable</code> will not start an editor in these columns.
1369      * If editor is <code>null</code>, removes the default editor for this
1370      * column class.
1371      *
1372      * @param  columnClass  set the default cell editor for this columnClass
1373      * @param  editor   default cell editor to be used for this columnClass
1374      * @see     TableModel#isCellEditable
1375      * @see     #getDefaultEditor
1376      * @see     #setDefaultRenderer
1377      */
1378     public void setDefaultEditor(Class<?> columnClass, TableCellEditor editor) {
1379         if (editor != null) {
1380             defaultEditorsByColumnClass.put(columnClass, editor);
1381         }
1382         else {
1383             defaultEditorsByColumnClass.remove(columnClass);
1384         }
1385     }
1386 
1387     /**
1388      * Returns the editor to be used when no editor has been set in
1389      * a <code>TableColumn</code>. During the editing of cells the editor is fetched from
1390      * a <code>Hashtable</code> of entries according to the class of the cells in the column. If
1391      * there is no entry for this <code>columnClass</code> the method returns
1392      * the entry for the most specific superclass. The <code>JTable</code> installs entries
1393      * for <code>Object</code>, <code>Number</code>, and <code>Boolean</code>, all of which can be modified
1394      * or replaced.
1395      *
1396      * @param   columnClass  return the default cell editor for this columnClass
1397      * @return the default cell editor to be used for this columnClass
1398      * @see     #setDefaultEditor
1399      * @see     #getColumnClass
1400      */
1401     public TableCellEditor getDefaultEditor(Class<?> columnClass) {
1402         if (columnClass == null) {
1403             return null;
1404         }
1405         else {
1406             Object editor = defaultEditorsByColumnClass.get(columnClass);
1407             if (editor != null) {
1408                 return (TableCellEditor)editor;
1409             }
1410             else {
1411                 return getDefaultEditor(columnClass.getSuperclass());
1412             }
1413         }


1417      * Turns on or off automatic drag handling. In order to enable automatic
1418      * drag handling, this property should be set to {@code true}, and the
1419      * table's {@code TransferHandler} needs to be {@code non-null}.
1420      * The default value of the {@code dragEnabled} property is {@code false}.
1421      * <p>
1422      * The job of honoring this property, and recognizing a user drag gesture,
1423      * lies with the look and feel implementation, and in particular, the table's
1424      * {@code TableUI}. When automatic drag handling is enabled, most look and
1425      * feels (including those that subclass {@code BasicLookAndFeel}) begin a
1426      * drag and drop operation whenever the user presses the mouse button over
1427      * an item (in single selection mode) or a selection (in other selection
1428      * modes) and then moves the mouse a few pixels. Setting this property to
1429      * {@code true} can therefore have a subtle effect on how selections behave.
1430      * <p>
1431      * If a look and feel is used that ignores this property, you can still
1432      * begin a drag and drop operation by calling {@code exportAsDrag} on the
1433      * table's {@code TransferHandler}.
1434      *
1435      * @param b whether or not to enable automatic drag handling
1436      * @exception HeadlessException if
1437      *            <code>b</code> is <code>true</code> and
1438      *            <code>GraphicsEnvironment.isHeadless()</code>
1439      *            returns <code>true</code>
1440      * @see java.awt.GraphicsEnvironment#isHeadless
1441      * @see #getDragEnabled
1442      * @see #setTransferHandler
1443      * @see TransferHandler
1444      * @since 1.4
1445      *
1446      * @beaninfo
1447      *  description: determines whether automatic drag handling is enabled
1448      *        bound: false
1449      */
1450     public void setDragEnabled(boolean b) {
1451         checkDragEnabled(b);
1452         dragEnabled = b;
1453     }
1454 
1455     private void checkDragEnabled(boolean b) {
1456         if (b && GraphicsEnvironment.isHeadless()) {
1457             throw new HeadlessException();
1458         }
1459     }
1460 
1461     /**
1462      * Returns whether or not automatic drag handling is enabled.
1463      *
1464      * @return the value of the {@code dragEnabled} property
1465      * @see #setDragEnabled
1466      * @since 1.4
1467      */
1468     public boolean getDragEnabled() {
1469         return dragEnabled;
1470     }
1471 
1472     /**
1473      * Sets the drop mode for this component. For backward compatibility,
1474      * the default for this property is <code>DropMode.USE_SELECTION</code>.
1475      * Usage of one of the other modes is recommended, however, for an
1476      * improved user experience. <code>DropMode.ON</code>, for instance,
1477      * offers similar behavior of showing items as selected, but does so without
1478      * affecting the actual selection in the table.
1479      * <p>
1480      * <code>JTable</code> supports the following drop modes:
1481      * <ul>
1482      *    <li><code>DropMode.USE_SELECTION</code></li>
1483      *    <li><code>DropMode.ON</code></li>
1484      *    <li><code>DropMode.INSERT</code></li>
1485      *    <li><code>DropMode.INSERT_ROWS</code></li>
1486      *    <li><code>DropMode.INSERT_COLS</code></li>
1487      *    <li><code>DropMode.ON_OR_INSERT</code></li>
1488      *    <li><code>DropMode.ON_OR_INSERT_ROWS</code></li>
1489      *    <li><code>DropMode.ON_OR_INSERT_COLS</code></li>
1490      * </ul>
1491      * <p>
1492      * The drop mode is only meaningful if this component has a
1493      * <code>TransferHandler</code> that accepts drops.
1494      *
1495      * @param dropMode the drop mode to use
1496      * @throws IllegalArgumentException if the drop mode is unsupported
1497      *         or <code>null</code>
1498      * @see #getDropMode
1499      * @see #getDropLocation
1500      * @see #setTransferHandler
1501      * @see TransferHandler
1502      * @since 1.6
1503      */
1504     public final void setDropMode(DropMode dropMode) {
1505         checkDropMode(dropMode);
1506         this.dropMode = dropMode;
1507     }
1508 
1509     private static void checkDropMode(DropMode dropMode) {
1510         if (dropMode != null) {
1511             switch (dropMode) {
1512                 case USE_SELECTION:
1513                 case ON:
1514                 case INSERT:
1515                 case INSERT_ROWS:
1516                 case INSERT_COLS:
1517                 case ON_OR_INSERT:


1522         }
1523         throw new IllegalArgumentException(dropMode
1524                 + ": Unsupported drop mode for table");
1525     }
1526     /**
1527      * Returns the drop mode for this component.
1528      *
1529      * @return the drop mode for this component
1530      * @see #setDropMode
1531      * @since 1.6
1532      */
1533     public final DropMode getDropMode() {
1534         return dropMode;
1535     }
1536 
1537     /**
1538      * Calculates a drop location in this component, representing where a
1539      * drop at the given point should insert data.
1540      *
1541      * @param p the point to calculate a drop location for
1542      * @return the drop location, or <code>null</code>
1543      */
1544     DropLocation dropLocationForPoint(Point p) {
1545         DropLocation location = null;
1546 
1547         int row = rowAtPoint(p);
1548         int col = columnAtPoint(p);
1549         boolean outside = Boolean.TRUE == getClientProperty("Table.isFileList")
1550                           && SwingUtilities2.pointOutsidePrefSize(this, row, col, p);
1551 
1552         Rectangle rect = getCellRect(row, col, true);
1553         Section xSection, ySection;
1554         boolean between = false;
1555         boolean ltr = getComponentOrientation().isLeftToRight();
1556 
1557         switch(dropMode) {
1558             case USE_SELECTION:
1559             case ON:
1560                 if (row == -1 || col == -1 || outside) {
1561                     location = new DropLocation(p, -1, -1, false, false);
1562                 } else {


1718     }
1719 
1720     /**
1721      * Called to set or clear the drop location during a DnD operation.
1722      * In some cases, the component may need to use it's internal selection
1723      * temporarily to indicate the drop location. To help facilitate this,
1724      * this method returns and accepts as a parameter a state object.
1725      * This state object can be used to store, and later restore, the selection
1726      * state. Whatever this method returns will be passed back to it in
1727      * future calls, as the state parameter. If it wants the DnD system to
1728      * continue storing the same state, it must pass it back every time.
1729      * Here's how this is used:
1730      * <p>
1731      * Let's say that on the first call to this method the component decides
1732      * to save some state (because it is about to use the selection to show
1733      * a drop index). It can return a state object to the caller encapsulating
1734      * any saved selection state. On a second call, let's say the drop location
1735      * is being changed to something else. The component doesn't need to
1736      * restore anything yet, so it simply passes back the same state object
1737      * to have the DnD system continue storing it. Finally, let's say this
1738      * method is messaged with <code>null</code>. This means DnD
1739      * is finished with this component for now, meaning it should restore
1740      * state. At this point, it can use the state parameter to restore
1741      * said state, and of course return <code>null</code> since there's
1742      * no longer anything to store.
1743      *
1744      * @param location the drop location (as calculated by
1745      *        <code>dropLocationForPoint</code>) or <code>null</code>
1746      *        if there's no longer a valid drop location
1747      * @param state the state object saved earlier for this component,
1748      *        or <code>null</code>
1749      * @param forDrop whether or not the method is being called because an
1750      *        actual drop occurred
1751      * @return any saved state for this component, or <code>null</code> if none
1752      */
1753     Object setDropLocation(TransferHandler.DropLocation location,
1754                            Object state,
1755                            boolean forDrop) {
1756 
1757         Object retVal = null;
1758         DropLocation tableLocation = (DropLocation)location;
1759 
1760         if (dropMode == DropMode.USE_SELECTION) {
1761             if (tableLocation == null) {
1762                 if (!forDrop && state != null) {
1763                     clearSelection();
1764 
1765                     int[] rows = ((int[][])state)[0];
1766                     int[] cols = ((int[][])state)[1];
1767                     int[] anchleads = ((int[][])state)[2];
1768 
1769                     for (int row : rows) {
1770                         addRowSelectionInterval(row, row);
1771                     }


1806                     setColumnSelectionInterval(tableLocation.getColumn(),
1807                                                tableLocation.getColumn());
1808                 }
1809             }
1810         }
1811 
1812         DropLocation old = dropLocation;
1813         dropLocation = tableLocation;
1814         firePropertyChange("dropLocation", old, dropLocation);
1815 
1816         return retVal;
1817     }
1818 
1819     /**
1820      * Returns the location that this component should visually indicate
1821      * as the drop location during a DnD operation over the component,
1822      * or {@code null} if no location is to currently be shown.
1823      * <p>
1824      * This method is not meant for querying the drop location
1825      * from a {@code TransferHandler}, as the drop location is only
1826      * set after the {@code TransferHandler}'s <code>canImport</code>
1827      * has returned and has allowed for the location to be shown.
1828      * <p>
1829      * When this property changes, a property change event with
1830      * name "dropLocation" is fired by the component.
1831      *
1832      * @return the drop location
1833      * @see #setDropMode
1834      * @see TransferHandler#canImport(TransferHandler.TransferSupport)
1835      * @since 1.6
1836      */
1837     public final DropLocation getDropLocation() {
1838         return dropLocation;
1839     }
1840 
1841     /**
1842      * Specifies whether a {@code RowSorter} should be created for the
1843      * table whenever its model changes.
1844      * <p>
1845      * When {@code setAutoCreateRowSorter(true)} is invoked, a {@code
1846      * TableRowSorter} is immediately created and installed on the


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


1952     }
1953 
1954     /**
1955      * Returns the object responsible for sorting.
1956      *
1957      * @return the object responsible for sorting
1958      * @since 1.6
1959      */
1960     public RowSorter<? extends TableModel> getRowSorter() {
1961         return (sortManager != null) ? sortManager.sorter : null;
1962     }
1963 
1964 //
1965 // Selection methods
1966 //
1967     /**
1968      * Sets the table's selection mode to allow only single selections, a single
1969      * contiguous interval, or multiple intervals.
1970      * <P>
1971      * <b>Note:</b>
1972      * <code>JTable</code> provides all the methods for handling
1973      * column and row selection.  When setting states,
1974      * such as <code>setSelectionMode</code>, it not only
1975      * updates the mode for the row selection model but also sets similar
1976      * values in the selection model of the <code>columnModel</code>.
1977      * If you want to have the row and column selection models operating
1978      * in different modes, set them both directly.
1979      * <p>
1980      * Both the row and column selection models for <code>JTable</code>
1981      * default to using a <code>DefaultListSelectionModel</code>
1982      * so that <code>JTable</code> works the same way as the
1983      * <code>JList</code>. See the <code>setSelectionMode</code> method
1984      * in <code>JList</code> for details about the modes.
1985      *
1986      * @param selectionMode the mode used by the row and column selection models
1987      * @see JList#setSelectionMode
1988      * @beaninfo
1989      * description: The selection mode used by the row and column selection models.
1990      *        enum: SINGLE_SELECTION            ListSelectionModel.SINGLE_SELECTION
1991      *              SINGLE_INTERVAL_SELECTION   ListSelectionModel.SINGLE_INTERVAL_SELECTION
1992      *              MULTIPLE_INTERVAL_SELECTION ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
1993      */
1994     public void setSelectionMode(int selectionMode) {
1995         clearSelection();
1996         getSelectionModel().setSelectionMode(selectionMode);
1997         getColumnModel().getSelectionModel().setSelectionMode(selectionMode);
1998     }
1999 
2000     /**
2001      * Sets whether the rows in this model can be selected.
2002      *
2003      * @param rowSelectionAllowed   true if this model will allow row selection
2004      * @see #getRowSelectionAllowed


2042         if (old != columnSelectionAllowed) {
2043             repaint();
2044         }
2045         firePropertyChange("columnSelectionAllowed", old, columnSelectionAllowed);
2046     }
2047 
2048     /**
2049      * Returns true if columns can be selected.
2050      *
2051      * @return true if columns can be selected, otherwise false
2052      * @see #setColumnSelectionAllowed
2053      */
2054     public boolean getColumnSelectionAllowed() {
2055         return columnModel.getColumnSelectionAllowed();
2056     }
2057 
2058     /**
2059      * Sets whether this table allows both a column selection and a
2060      * row selection to exist simultaneously. When set,
2061      * the table treats the intersection of the row and column selection
2062      * models as the selected cells. Override <code>isCellSelected</code> to
2063      * change this default behavior. This method is equivalent to setting
2064      * both the <code>rowSelectionAllowed</code> property and
2065      * <code>columnSelectionAllowed</code> property of the
2066      * <code>columnModel</code> to the supplied value.
2067      *
2068      * @param  cellSelectionEnabled     true if simultaneous row and column
2069      *                                  selection is allowed
2070      * @see #getCellSelectionEnabled
2071      * @see #isCellSelected
2072      * @beaninfo
2073      *  bound: true
2074      *    attribute: visualUpdate true
2075      *  description: Select a rectangular region of cells rather than
2076      *               rows or columns.
2077      */
2078     public void setCellSelectionEnabled(boolean cellSelectionEnabled) {
2079         setRowSelectionAllowed(cellSelectionEnabled);
2080         setColumnSelectionAllowed(cellSelectionEnabled);
2081         boolean old = this.cellSelectionEnabled;
2082         this.cellSelectionEnabled = cellSelectionEnabled;
2083         firePropertyChange("cellSelectionEnabled", old, cellSelectionEnabled);
2084     }
2085 
2086     /**
2087      * Returns true if both row and column selection models are enabled.
2088      * Equivalent to <code>getRowSelectionAllowed() &amp;&amp;
2089      * getColumnSelectionAllowed()</code>.
2090      *
2091      * @return true if both row and column selection models are enabled
2092      *
2093      * @see #setCellSelectionEnabled
2094      */
2095     public boolean getCellSelectionEnabled() {
2096         return getRowSelectionAllowed() && getColumnSelectionAllowed();
2097     }
2098 
2099     /**
2100      *  Selects all rows, columns, and cells in the table.
2101      */
2102     public void selectAll() {
2103         // If I'm currently editing, then I should stop editing
2104         if (isEditing()) {
2105             removeEditor();
2106         }
2107         if (getRowCount() > 0 && getColumnCount() > 0) {
2108             int oldLead;
2109             int oldAnchor;


2161     private int getAdjustedIndex(int index, boolean row) {
2162         int compare = row ? getRowCount() : getColumnCount();
2163         return index < compare ? index : -1;
2164     }
2165 
2166     private int boundRow(int row) throws IllegalArgumentException {
2167         if (row < 0 || row >= getRowCount()) {
2168             throw new IllegalArgumentException("Row index out of range");
2169         }
2170         return row;
2171     }
2172 
2173     private int boundColumn(int col) {
2174         if (col< 0 || col >= getColumnCount()) {
2175             throw new IllegalArgumentException("Column index out of range");
2176         }
2177         return col;
2178     }
2179 
2180     /**
2181      * Selects the rows from <code>index0</code> to <code>index1</code>,
2182      * inclusive.
2183      *
2184      * @exception IllegalArgumentException      if <code>index0</code> or
2185      *                                          <code>index1</code> lie outside
2186      *                                          [0, <code>getRowCount()</code>-1]
2187      * @param   index0 one end of the interval
2188      * @param   index1 the other end of the interval
2189      */
2190     public void setRowSelectionInterval(int index0, int index1) {
2191         selectionModel.setSelectionInterval(boundRow(index0), boundRow(index1));
2192     }
2193 
2194     /**
2195      * Selects the columns from <code>index0</code> to <code>index1</code>,
2196      * inclusive.
2197      *
2198      * @exception IllegalArgumentException      if <code>index0</code> or
2199      *                                          <code>index1</code> lie outside
2200      *                                          [0, <code>getColumnCount()</code>-1]
2201      * @param   index0 one end of the interval
2202      * @param   index1 the other end of the interval
2203      */
2204     public void setColumnSelectionInterval(int index0, int index1) {
2205         columnModel.getSelectionModel().setSelectionInterval(boundColumn(index0), boundColumn(index1));
2206     }
2207 
2208     /**
2209      * Adds the rows from <code>index0</code> to <code>index1</code>, inclusive, to
2210      * the current selection.
2211      *
2212      * @exception IllegalArgumentException      if <code>index0</code> or <code>index1</code>
2213      *                                          lie outside [0, <code>getRowCount()</code>-1]
2214      * @param   index0 one end of the interval
2215      * @param   index1 the other end of the interval
2216      */
2217     public void addRowSelectionInterval(int index0, int index1) {
2218         selectionModel.addSelectionInterval(boundRow(index0), boundRow(index1));
2219     }
2220 
2221     /**
2222      * Adds the columns from <code>index0</code> to <code>index1</code>,
2223      * inclusive, to the current selection.
2224      *
2225      * @exception IllegalArgumentException      if <code>index0</code> or
2226      *                                          <code>index1</code> lie outside
2227      *                                          [0, <code>getColumnCount()</code>-1]
2228      * @param   index0 one end of the interval
2229      * @param   index1 the other end of the interval
2230      */
2231     public void addColumnSelectionInterval(int index0, int index1) {
2232         columnModel.getSelectionModel().addSelectionInterval(boundColumn(index0), boundColumn(index1));
2233     }
2234 
2235     /**
2236      * Deselects the rows from <code>index0</code> to <code>index1</code>, inclusive.
2237      *
2238      * @exception IllegalArgumentException      if <code>index0</code> or
2239      *                                          <code>index1</code> lie outside
2240      *                                          [0, <code>getRowCount()</code>-1]
2241      * @param   index0 one end of the interval
2242      * @param   index1 the other end of the interval
2243      */
2244     public void removeRowSelectionInterval(int index0, int index1) {
2245         selectionModel.removeSelectionInterval(boundRow(index0), boundRow(index1));
2246     }
2247 
2248     /**
2249      * Deselects the columns from <code>index0</code> to <code>index1</code>, inclusive.
2250      *
2251      * @exception IllegalArgumentException      if <code>index0</code> or
2252      *                                          <code>index1</code> lie outside
2253      *                                          [0, <code>getColumnCount()</code>-1]
2254      * @param   index0 one end of the interval
2255      * @param   index1 the other end of the interval
2256      */
2257     public void removeColumnSelectionInterval(int index0, int index1) {
2258         columnModel.getSelectionModel().removeSelectionInterval(boundColumn(index0), boundColumn(index1));
2259     }
2260 
2261     /**
2262      * Returns the index of the first selected row, -1 if no row is selected.
2263      * @return the index of the first selected row
2264      */
2265     public int getSelectedRow() {
2266         return selectionModel.getMinSelectionIndex();
2267     }
2268 
2269     /**
2270      * Returns the index of the first selected column,
2271      * -1 if no column is selected.
2272      * @return the index of the first selected column
2273      */


2328                 count++;
2329             }
2330         }
2331         return count;
2332     }
2333 
2334     /**
2335      * Returns the number of selected columns.
2336      *
2337      * @return the number of selected columns, 0 if no columns are selected
2338      */
2339     public int getSelectedColumnCount() {
2340         return columnModel.getSelectedColumnCount();
2341     }
2342 
2343     /**
2344      * Returns true if the specified index is in the valid range of rows,
2345      * and the row at that index is selected.
2346      *
2347      * @param row a row in the row model
2348      * @return true if <code>row</code> is a valid index and the row at
2349      *              that index is selected (where 0 is the first row)
2350      */
2351     public boolean isRowSelected(int row) {
2352         return selectionModel.isSelectedIndex(row);
2353     }
2354 
2355     /**
2356      * Returns true if the specified index is in the valid range of columns,
2357      * and the column at that index is selected.
2358      *
2359      * @param   column   the column in the column model
2360      * @return true if <code>column</code> is a valid index and the column at
2361      *              that index is selected (where 0 is the first column)
2362      */
2363     public boolean isColumnSelected(int column) {
2364         return columnModel.getSelectionModel().isSelectedIndex(column);
2365     }
2366 
2367     /**
2368      * Returns true if the specified indices are in the valid range of rows
2369      * and columns and the cell at the specified position is selected.
2370      * @param row   the row being queried
2371      * @param column  the column being queried
2372      *
2373      * @return true if <code>row</code> and <code>column</code> are valid indices
2374      *              and the cell at index <code>(row, column)</code> is selected,
2375      *              where the first row and first column are at index 0
2376      */
2377     public boolean isCellSelected(int row, int column) {
2378         if (!getRowSelectionAllowed() && !getColumnSelectionAllowed()) {
2379             return false;
2380         }
2381         return (!getRowSelectionAllowed() || isRowSelected(row)) &&
2382                (!getColumnSelectionAllowed() || isColumnSelected(column));
2383     }
2384 
2385     private void changeSelectionModel(ListSelectionModel sm, int index,
2386                                       boolean toggle, boolean extend, boolean selected,
2387                                       int anchor, boolean anchorSelected) {
2388         if (extend) {
2389             if (toggle) {
2390                 if (anchorSelected) {
2391                     sm.addSelectionInterval(anchor, index);
2392                 } else {
2393                     sm.removeSelectionInterval(anchor, index);
2394                     // this is a Windows-only behavior that we want for file lists


2402                 sm.setSelectionInterval(anchor, index);
2403             }
2404         }
2405         else {
2406             if (toggle) {
2407                 if (selected) {
2408                     sm.removeSelectionInterval(index, index);
2409                 }
2410                 else {
2411                     sm.addSelectionInterval(index, index);
2412                 }
2413             }
2414             else {
2415                 sm.setSelectionInterval(index, index);
2416             }
2417         }
2418     }
2419 
2420     /**
2421      * Updates the selection models of the table, depending on the state of the
2422      * two flags: <code>toggle</code> and <code>extend</code>. Most changes
2423      * to the selection that are the result of keyboard or mouse events received
2424      * by the UI are channeled through this method so that the behavior may be
2425      * overridden by a subclass. Some UIs may need more functionality than
2426      * this method provides, such as when manipulating the lead for discontiguous
2427      * selection, and may not call into this method for some selection changes.
2428      * <p>
2429      * This implementation uses the following conventions:
2430      * <ul>
2431      * <li> <code>toggle</code>: <em>false</em>, <code>extend</code>: <em>false</em>.
2432      *      Clear the previous selection and ensure the new cell is selected.
2433      * <li> <code>toggle</code>: <em>false</em>, <code>extend</code>: <em>true</em>.
2434      *      Extend the previous selection from the anchor to the specified cell,
2435      *      clearing all other selections.
2436      * <li> <code>toggle</code>: <em>true</em>, <code>extend</code>: <em>false</em>.
2437      *      If the specified cell is selected, deselect it. If it is not selected, select it.
2438      * <li> <code>toggle</code>: <em>true</em>, <code>extend</code>: <em>true</em>.
2439      *      Apply the selection state of the anchor to all cells between it and the
2440      *      specified cell.
2441      * </ul>
2442      * @param  rowIndex   affects the selection at <code>row</code>
2443      * @param  columnIndex  affects the selection at <code>column</code>
2444      * @param  toggle  see description above
2445      * @param  extend  if true, extend the current selection
2446      *
2447      * @since 1.3
2448      */
2449     public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
2450         ListSelectionModel rsm = getSelectionModel();
2451         ListSelectionModel csm = getColumnModel().getSelectionModel();
2452 
2453         int anchorRow = getAdjustedIndex(rsm.getAnchorSelectionIndex(), true);
2454         int anchorCol = getAdjustedIndex(csm.getAnchorSelectionIndex(), false);
2455 
2456         boolean anchorSelected = true;
2457 
2458         if (anchorRow == -1) {
2459             if (getRowCount() > 0) {
2460                 anchorRow = 0;
2461             }
2462             anchorSelected = false;
2463         }


2481 
2482         changeSelectionModel(csm, columnIndex, toggle, extend, selected,
2483                              anchorCol, anchorSelected);
2484         changeSelectionModel(rsm, rowIndex, toggle, extend, selected,
2485                              anchorRow, anchorSelected);
2486 
2487         // Scroll after changing the selection as blit scrolling is immediate,
2488         // so that if we cause the repaint after the scroll we end up painting
2489         // everything!
2490         if (getAutoscrolls()) {
2491             Rectangle cellRect = getCellRect(rowIndex, columnIndex, false);
2492             if (cellRect != null) {
2493                 scrollRectToVisible(cellRect);
2494             }
2495         }
2496     }
2497 
2498     /**
2499      * Returns the foreground color for selected cells.
2500      *
2501      * @return the <code>Color</code> object for the foreground property
2502      * @see #setSelectionForeground
2503      * @see #setSelectionBackground
2504      */
2505     public Color getSelectionForeground() {
2506         return selectionForeground;
2507     }
2508 
2509     /**
2510      * Sets the foreground color for selected cells.  Cell renderers
2511      * can use this color to render text and graphics for selected
2512      * cells.
2513      * <p>
2514      * The default value of this property is defined by the look
2515      * and feel implementation.
2516      * <p>
2517      * This is a <a href="http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html">JavaBeans</a> bound property.
2518      *
2519      * @param selectionForeground  the <code>Color</code> to use in the foreground
2520      *                             for selected list items
2521      * @see #getSelectionForeground
2522      * @see #setSelectionBackground
2523      * @see #setForeground
2524      * @see #setBackground
2525      * @see #setFont
2526      * @beaninfo
2527      *       bound: true
2528      * description: A default foreground color for selected cells.
2529      */
2530     public void setSelectionForeground(Color selectionForeground) {
2531         Color old = this.selectionForeground;
2532         this.selectionForeground = selectionForeground;
2533         firePropertyChange("selectionForeground", old, selectionForeground);
2534         repaint();
2535     }
2536 
2537     /**
2538      * Returns the background color for selected cells.
2539      *
2540      * @return the <code>Color</code> used for the background of selected list items
2541      * @see #setSelectionBackground
2542      * @see #setSelectionForeground
2543      */
2544     public Color getSelectionBackground() {
2545         return selectionBackground;
2546     }
2547 
2548     /**
2549      * Sets the background color for selected cells.  Cell renderers
2550      * can use this color to the fill selected cells.
2551      * <p>
2552      * The default value of this property is defined by the look
2553      * and feel implementation.
2554      * <p>
2555      * This is a <a href="http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html">JavaBeans</a> bound property.
2556      *
2557      * @param selectionBackground  the <code>Color</code> to use for the background
2558      *                             of selected cells
2559      * @see #getSelectionBackground
2560      * @see #setSelectionForeground
2561      * @see #setForeground
2562      * @see #setBackground
2563      * @see #setFont
2564      * @beaninfo
2565      *       bound: true
2566      * description: A default background color for selected cells.
2567      */
2568     public void setSelectionBackground(Color selectionBackground) {
2569         Color old = this.selectionBackground;
2570         this.selectionBackground = selectionBackground;
2571         firePropertyChange("selectionBackground", old, selectionBackground);
2572         repaint();
2573     }
2574 
2575     /**
2576      * Returns the <code>TableColumn</code> object for the column in the table
2577      * whose identifier is equal to <code>identifier</code>, when compared using
2578      * <code>equals</code>.
2579      *
2580      * @return  the <code>TableColumn</code> object that matches the identifier
2581      * @exception IllegalArgumentException      if <code>identifier</code> is <code>null</code> or no <code>TableColumn</code> has this identifier
2582      *
2583      * @param   identifier                      the identifier object
2584      */
2585     public TableColumn getColumn(Object identifier) {
2586         TableColumnModel cm = getColumnModel();
2587         int columnIndex = cm.getColumnIndex(identifier);
2588         return cm.getColumn(columnIndex);
2589     }
2590 
2591 //
2592 // Informally implement the TableModel interface.
2593 //
2594 
2595     /**
2596      * Maps the index of the column in the view at
2597      * <code>viewColumnIndex</code> to the index of the column
2598      * in the table model.  Returns the index of the corresponding
2599      * column in the model.  If <code>viewColumnIndex</code>
2600      * is less than zero, returns <code>viewColumnIndex</code>.
2601      *
2602      * @param   viewColumnIndex     the index of the column in the view
2603      * @return  the index of the corresponding column in the model
2604      *
2605      * @see #convertColumnIndexToView
2606      */
2607     public int convertColumnIndexToModel(int viewColumnIndex) {
2608         return SwingUtilities2.convertColumnIndexToModel(
2609                 getColumnModel(), viewColumnIndex);
2610     }
2611 
2612     /**
2613      * Maps the index of the column in the table model at
2614      * <code>modelColumnIndex</code> to the index of the column
2615      * in the view.  Returns the index of the
2616      * corresponding column in the view; returns -1 if this column is not
2617      * being displayed.  If <code>modelColumnIndex</code> is less than zero,
2618      * returns <code>modelColumnIndex</code>.
2619      *
2620      * @param   modelColumnIndex     the index of the column in the model
2621      * @return   the index of the corresponding column in the view
2622      *
2623      * @see #convertColumnIndexToModel
2624      */
2625     public int convertColumnIndexToView(int modelColumnIndex) {
2626         return SwingUtilities2.convertColumnIndexToView(
2627                 getColumnModel(), modelColumnIndex);
2628     }
2629 
2630     /**
2631      * Maps the index of the row in terms of the
2632      * <code>TableModel</code> to the view.  If the contents of the
2633      * model are not sorted the model and view indices are the same.
2634      *
2635      * @param modelRowIndex the index of the row in terms of the model
2636      * @return the index of the corresponding row in the view, or -1 if
2637      *         the row isn't visible
2638      * @throws IndexOutOfBoundsException if sorting is enabled and passed an
2639      *         index outside the number of rows of the <code>TableModel</code>
2640      * @see javax.swing.table.TableRowSorter
2641      * @since 1.6
2642      */
2643     public int convertRowIndexToView(int modelRowIndex) {
2644         RowSorter<?> sorter = getRowSorter();
2645         if (sorter != null) {
2646             return sorter.convertRowIndexToView(modelRowIndex);
2647         }
2648         return modelRowIndex;
2649     }
2650 
2651     /**
2652      * Maps the index of the row in terms of the view to the
2653      * underlying <code>TableModel</code>.  If the contents of the
2654      * model are not sorted the model and view indices are the same.
2655      *
2656      * @param viewRowIndex the index of the row in the view
2657      * @return the index of the corresponding row in the model
2658      * @throws IndexOutOfBoundsException if sorting is enabled and passed an
2659      *         index outside the range of the <code>JTable</code> as
2660      *         determined by the method <code>getRowCount</code>
2661      * @see javax.swing.table.TableRowSorter
2662      * @see #getRowCount
2663      * @since 1.6
2664      */
2665     public int convertRowIndexToModel(int viewRowIndex) {
2666         RowSorter<?> sorter = getRowSorter();
2667         if (sorter != null) {
2668             return sorter.convertRowIndexToModel(viewRowIndex);
2669         }
2670         return viewRowIndex;
2671     }
2672 
2673     /**
2674      * Returns the number of rows that can be shown in the
2675      * <code>JTable</code>, given unlimited space.  If a
2676      * <code>RowSorter</code> with a filter has been specified, the
2677      * number of rows returned may differ from that of the underlying
2678      * <code>TableModel</code>.
2679      *
2680      * @return the number of rows shown in the <code>JTable</code>
2681      * @see #getColumnCount
2682      */
2683     public int getRowCount() {
2684         RowSorter<?> sorter = getRowSorter();
2685         if (sorter != null) {
2686             return sorter.getViewRowCount();
2687         }
2688         return getModel().getRowCount();
2689     }
2690 
2691     /**
2692      * Returns the number of columns in the column model. Note that this may
2693      * be different from the number of columns in the table model.
2694      *
2695      * @return  the number of columns in the table
2696      * @see #getRowCount
2697      * @see #removeColumn
2698      */
2699     public int getColumnCount() {
2700         return getColumnModel().getColumnCount();
2701     }
2702 
2703     /**
2704      * Returns the name of the column appearing in the view at
2705      * column position <code>column</code>.
2706      *
2707      * @param  column    the column in the view being queried
2708      * @return the name of the column at position <code>column</code>
2709                         in the view where the first column is column 0
2710      */
2711     public String getColumnName(int column) {
2712         return getModel().getColumnName(convertColumnIndexToModel(column));
2713     }
2714 
2715     /**
2716      * Returns the type of the column appearing in the view at
2717      * column position <code>column</code>.
2718      *
2719      * @param   column   the column in the view being queried
2720      * @return the type of the column at position <code>column</code>
2721      *          in the view where the first column is column 0
2722      */
2723     public Class<?> getColumnClass(int column) {
2724         return getModel().getColumnClass(convertColumnIndexToModel(column));
2725     }
2726 
2727     /**
2728      * Returns the cell value at <code>row</code> and <code>column</code>.
2729      * <p>
2730      * <b>Note</b>: The column is specified in the table view's display
2731      *              order, and not in the <code>TableModel</code>'s column
2732      *              order.  This is an important distinction because as the
2733      *              user rearranges the columns in the table,
2734      *              the column at a given index in the view will change.
2735      *              Meanwhile the user's actions never affect the model's
2736      *              column ordering.
2737      *
2738      * @param   row             the row whose value is to be queried
2739      * @param   column          the column whose value is to be queried
2740      * @return  the Object at the specified cell
2741      */
2742     public Object getValueAt(int row, int column) {
2743         return getModel().getValueAt(convertRowIndexToModel(row),
2744                                      convertColumnIndexToModel(column));
2745     }
2746 
2747     /**
2748      * Sets the value for the cell in the table model at <code>row</code>
2749      * and <code>column</code>.
2750      * <p>
2751      * <b>Note</b>: The column is specified in the table view's display
2752      *              order, and not in the <code>TableModel</code>'s column
2753      *              order.  This is an important distinction because as the
2754      *              user rearranges the columns in the table,
2755      *              the column at a given index in the view will change.
2756      *              Meanwhile the user's actions never affect the model's
2757      *              column ordering.
2758      *
2759      * <code>aValue</code> is the new value.
2760      *
2761      * @param   aValue          the new value
2762      * @param   row             the row of the cell to be changed
2763      * @param   column          the column of the cell to be changed
2764      * @see #getValueAt
2765      */
2766     public void setValueAt(Object aValue, int row, int column) {
2767         getModel().setValueAt(aValue, convertRowIndexToModel(row),
2768                               convertColumnIndexToModel(column));
2769     }
2770 
2771     /**
2772      * Returns true if the cell at <code>row</code> and <code>column</code>
2773      * is editable.  Otherwise, invoking <code>setValueAt</code> on the cell
2774      * will have no effect.
2775      * <p>
2776      * <b>Note</b>: The column is specified in the table view's display
2777      *              order, and not in the <code>TableModel</code>'s column
2778      *              order.  This is an important distinction because as the
2779      *              user rearranges the columns in the table,
2780      *              the column at a given index in the view will change.
2781      *              Meanwhile the user's actions never affect the model's
2782      *              column ordering.
2783      *
2784      *
2785      * @param   row      the row whose value is to be queried
2786      * @param   column   the column whose value is to be queried
2787      * @return  true if the cell is editable
2788      * @see #setValueAt
2789      */
2790     public boolean isCellEditable(int row, int column) {
2791         return getModel().isCellEditable(convertRowIndexToModel(row),
2792                                          convertColumnIndexToModel(column));
2793     }
2794 //
2795 // Adding and removing columns in the view
2796 //
2797 
2798     /**
2799      *  Appends <code>aColumn</code> to the end of the array of columns held by
2800      *  this <code>JTable</code>'s column model.
2801      *  If the column name of <code>aColumn</code> is <code>null</code>,
2802      *  sets the column name of <code>aColumn</code> to the name
2803      *  returned by <code>getModel().getColumnName()</code>.
2804      *  <p>
2805      *  To add a column to this <code>JTable</code> to display the
2806      *  <code>modelColumn</code>'th column of data in the model with a
2807      *  given <code>width</code>, <code>cellRenderer</code>,
2808      *  and <code>cellEditor</code> you can use:
2809      *  <pre>
2810      *
2811      *      addColumn(new TableColumn(modelColumn, width, cellRenderer, cellEditor));
2812      *
2813      *  </pre>
2814      *  [Any of the <code>TableColumn</code> constructors can be used
2815      *  instead of this one.]
2816      *  The model column number is stored inside the <code>TableColumn</code>
2817      *  and is used during rendering and editing to locate the appropriates
2818      *  data values in the model. The model column number does not change
2819      *  when columns are reordered in the view.
2820      *
2821      *  @param  aColumn         the <code>TableColumn</code> to be added
2822      *  @see    #removeColumn
2823      */
2824     public void addColumn(TableColumn aColumn) {
2825         if (aColumn.getHeaderValue() == null) {
2826             int modelColumn = aColumn.getModelIndex();
2827             String columnName = getModel().getColumnName(modelColumn);
2828             aColumn.setHeaderValue(columnName);
2829         }
2830         getColumnModel().addColumn(aColumn);
2831     }
2832 
2833     /**
2834      *  Removes <code>aColumn</code> from this <code>JTable</code>'s
2835      *  array of columns.  Note: this method does not remove the column
2836      *  of data from the model; it just removes the <code>TableColumn</code>
2837      *  that was responsible for displaying it.
2838      *
2839      *  @param  aColumn         the <code>TableColumn</code> to be removed
2840      *  @see    #addColumn
2841      */
2842     public void removeColumn(TableColumn aColumn) {
2843         getColumnModel().removeColumn(aColumn);
2844     }
2845 
2846     /**
2847      * Moves the column <code>column</code> to the position currently
2848      * occupied by the column <code>targetColumn</code> in the view.
2849      * The old column at <code>targetColumn</code> is
2850      * shifted left or right to make room.
2851      *
2852      * @param   column                  the index of column to be moved
2853      * @param   targetColumn            the new index of the column
2854      */
2855     public void moveColumn(int column, int targetColumn) {
2856         getColumnModel().moveColumn(column, targetColumn);
2857     }
2858 
2859 //
2860 // Cover methods for various models and helper methods
2861 //
2862 
2863     /**
2864      * Returns the index of the column that <code>point</code> lies in,
2865      * or -1 if the result is not in the range
2866      * [0, <code>getColumnCount()</code>-1].
2867      *
2868      * @param   point   the location of interest
2869      * @return  the index of the column that <code>point</code> lies in,
2870      *          or -1 if the result is not in the range
2871      *          [0, <code>getColumnCount()</code>-1]
2872      * @see     #rowAtPoint
2873      */
2874     public int columnAtPoint(Point point) {
2875         int x = point.x;
2876         if( !getComponentOrientation().isLeftToRight() ) {
2877             x = getWidth() - x - 1;
2878         }
2879         return getColumnModel().getColumnIndexAtX(x);
2880     }
2881 
2882     /**
2883      * Returns the index of the row that <code>point</code> lies in,
2884      * or -1 if the result is not in the range
2885      * [0, <code>getRowCount()</code>-1].
2886      *
2887      * @param   point   the location of interest
2888      * @return  the index of the row that <code>point</code> lies in,
2889      *          or -1 if the result is not in the range
2890      *          [0, <code>getRowCount()</code>-1]
2891      * @see     #columnAtPoint
2892      */
2893     public int rowAtPoint(Point point) {
2894         int y = point.y;
2895         int result = (rowModel == null) ?  y/getRowHeight() : rowModel.getIndex(y);
2896         if (result < 0) {
2897             return -1;
2898         }
2899         else if (result >= getRowCount()) {
2900             return -1;
2901         }
2902         else {
2903             return result;
2904         }
2905     }
2906 
2907     /**
2908      * Returns a rectangle for the cell that lies at the intersection of
2909      * <code>row</code> and <code>column</code>.
2910      * If <code>includeSpacing</code> is true then the value returned
2911      * has the full height and width of the row and column
2912      * specified. If it is false, the returned rectangle is inset by the
2913      * intercell spacing to return the true bounds of the rendering or
2914      * editing component as it will be set during rendering.
2915      * <p>
2916      * If the column index is valid but the row index is less
2917      * than zero the method returns a rectangle with the
2918      * <code>y</code> and <code>height</code> values set appropriately
2919      * and the <code>x</code> and <code>width</code> values both set
2920      * to zero. In general, when either the row or column indices indicate a
2921      * cell outside the appropriate range, the method returns a rectangle
2922      * depicting the closest edge of the closest cell that is within
2923      * the table's range. When both row and column indices are out
2924      * of range the returned rectangle covers the closest
2925      * point of the closest cell.
2926      * <p>
2927      * In all cases, calculations that use this method to calculate
2928      * results along one axis will not fail because of anomalies in
2929      * calculations along the other axis. When the cell is not valid
2930      * the <code>includeSpacing</code> parameter is ignored.
2931      *
2932      * @param   row                   the row index where the desired cell
2933      *                                is located
2934      * @param   column                the column index where the desired cell
2935      *                                is located in the display; this is not
2936      *                                necessarily the same as the column index
2937      *                                in the data model for the table; the
2938      *                                {@link #convertColumnIndexToView(int)}
2939      *                                method may be used to convert a data
2940      *                                model column index to a display
2941      *                                column index
2942      * @param   includeSpacing        if false, return the true cell bounds -
2943      *                                computed by subtracting the intercell
2944      *                                spacing from the height and widths of
2945      *                                the column and row models
2946      *
2947      * @return  the rectangle containing the cell at location
2948      *          <code>row</code>,<code>column</code>
2949      * @see #getIntercellSpacing
2950      */
2951     public Rectangle getCellRect(int row, int column, boolean includeSpacing) {
2952         Rectangle r = new Rectangle();
2953         boolean valid = true;
2954         if (row < 0) {
2955             // y = height = 0;
2956             valid = false;
2957         }
2958         else if (row >= getRowCount()) {
2959             r.y = getHeight();
2960             valid = false;
2961         }
2962         else {
2963             r.height = getRowHeight(row);
2964             r.y = (rowModel == null) ? row * r.height : rowModel.getPosition(row);
2965         }
2966 
2967         if (column < 0) {
2968             if( !getComponentOrientation().isLeftToRight() ) {


3001             r.setBounds(r.x + cm/2, r.y + rm/2, r.width - cm, r.height - rm);
3002         }
3003         return r;
3004     }
3005 
3006     private int viewIndexForColumn(TableColumn aColumn) {
3007         TableColumnModel cm = getColumnModel();
3008         for (int column = 0; column < cm.getColumnCount(); column++) {
3009             if (cm.getColumn(column) == aColumn) {
3010                 return column;
3011             }
3012         }
3013         return -1;
3014     }
3015 
3016     /**
3017      * Causes this table to lay out its rows and columns.  Overridden so
3018      * that columns can be resized to accommodate a change in the size of
3019      * a containing parent.
3020      * Resizes one or more of the columns in the table
3021      * so that the total width of all of this <code>JTable</code>'s
3022      * columns is equal to the width of the table.
3023      * <p>
3024      * Before the layout begins the method gets the
3025      * <code>resizingColumn</code> of the <code>tableHeader</code>.
3026      * When the method is called as a result of the resizing of an enclosing window,
3027      * the <code>resizingColumn</code> is <code>null</code>. This means that resizing
3028      * has taken place "outside" the <code>JTable</code> and the change -
3029      * or "delta" - should be distributed to all of the columns regardless
3030      * of this <code>JTable</code>'s automatic resize mode.
3031      * <p>
3032      * If the <code>resizingColumn</code> is not <code>null</code>, it is one of
3033      * the columns in the table that has changed size rather than
3034      * the table itself. In this case the auto-resize modes govern
3035      * the way the extra (or deficit) space is distributed
3036      * amongst the available columns.
3037      * <p>
3038      * The modes are:
3039      * <ul>
3040      * <li>  AUTO_RESIZE_OFF: Don't automatically adjust the column's
3041      * widths at all. Use a horizontal scrollbar to accommodate the
3042      * columns when their sum exceeds the width of the
3043      * <code>Viewport</code>.  If the <code>JTable</code> is not
3044      * enclosed in a <code>JScrollPane</code> this may
3045      * leave parts of the table invisible.
3046      * <li>  AUTO_RESIZE_NEXT_COLUMN: Use just the column after the
3047      * resizing column. This results in the "boundary" or divider
3048      * between adjacent cells being independently adjustable.
3049      * <li>  AUTO_RESIZE_SUBSEQUENT_COLUMNS: Use all columns after the
3050      * one being adjusted to absorb the changes.  This is the
3051      * default behavior.
3052      * <li>  AUTO_RESIZE_LAST_COLUMN: Automatically adjust the
3053      * size of the last column only. If the bounds of the last column
3054      * prevent the desired size from being allocated, set the
3055      * width of the last column to the appropriate limit and make
3056      * no further adjustments.
3057      * <li>  AUTO_RESIZE_ALL_COLUMNS: Spread the delta amongst all the columns
3058      * in the <code>JTable</code>, including the one that is being
3059      * adjusted.
3060      * </ul>
3061      * <p>
3062      * <b>Note:</b> When a <code>JTable</code> makes adjustments
3063      *   to the widths of the columns it respects their minimum and
3064      *   maximum values absolutely.  It is therefore possible that,
3065      *   even after this method is called, the total width of the columns
3066      *   is still not equal to the width of the table. When this happens
3067      *   the <code>JTable</code> does not put itself
3068      *   in AUTO_RESIZE_OFF mode to bring up a scroll bar, or break other
3069      *   commitments of its current auto-resize mode -- instead it
3070      *   allows its bounds to be set larger (or smaller) than the total of the
3071      *   column minimum or maximum, meaning, either that there
3072      *   will not be enough room to display all of the columns, or that the
3073      *   columns will not fill the <code>JTable</code>'s bounds.
3074      *   These respectively, result in the clipping of some columns
3075      *   or an area being painted in the <code>JTable</code>'s
3076      *   background color during painting.
3077      * <p>
3078      *   The mechanism for distributing the delta amongst the available
3079      *   columns is provided in a private method in the <code>JTable</code>
3080      *   class:
3081      * <pre>
3082      *   adjustSizes(long targetSize, final Resizable3 r, boolean inverse)
3083      * </pre>
3084      *   an explanation of which is provided in the following section.
3085      *   <code>Resizable3</code> is a private
3086      *   interface that allows any data structure containing a collection
3087      *   of elements with a size, preferred size, maximum size and minimum size
3088      *   to have its elements manipulated by the algorithm.
3089      *
3090      * <H3> Distributing the delta </H3>
3091      *
3092      * <H4> Overview </H4>
3093      * <P>
3094      * Call "DELTA" the difference between the target size and the
3095      * sum of the preferred sizes of the elements in r. The individual
3096      * sizes are calculated by taking the original preferred
3097      * sizes and adding a share of the DELTA - that share being based on
3098      * how far each preferred size is from its limiting bound (minimum or
3099      * maximum).
3100      *
3101      * <H4>Definition</H4>
3102      * <P>
3103      * Call the individual constraints min[i], max[i], and pref[i].
3104      * <p>
3105      * Call their respective sums: MIN, MAX, and PREF.


3121      * If (DELTA &gt; 0) we are in expand mode where:
3122      *
3123      * <PRE>
3124      *                        DELTA
3125      *          delta[i] = ------------ * (max[i] - pref[i])
3126      *                      (MAX - PREF)
3127      * </PRE>
3128      * <P>
3129      * The overall effect is that the total size moves that same percentage,
3130      * k, towards the total minimum or maximum and that percentage guarantees
3131      * accommodation of the required space, DELTA.
3132      *
3133      * <H4>Details</H4>
3134      * <P>
3135      * Naive evaluation of the formulae presented here would be subject to
3136      * the aggregated rounding errors caused by doing this operation in finite
3137      * precision (using ints). To deal with this, the multiplying factor above,
3138      * is constantly recalculated and this takes account of the rounding
3139      * errors in the previous iterations. The result is an algorithm that
3140      * produces a set of integers whose values exactly sum to the supplied
3141      * <code>targetSize</code>, and does so by spreading the rounding
3142      * errors evenly over the given elements.
3143      *
3144      * <H4>When the MAX and MIN bounds are hit</H4>
3145      * <P>
3146      * When <code>targetSize</code> is outside the [MIN, MAX] range,
3147      * the algorithm sets all sizes to their appropriate limiting value
3148      * (maximum or minimum).
3149      *
3150      */
3151     public void doLayout() {
3152         TableColumn resizingColumn = getResizingColumn();
3153         if (resizingColumn == null) {
3154             setWidthsFromPreferredWidths(false);
3155         }
3156         else {
3157             // JTable behaves like a layout manger - but one in which the
3158             // user can come along and dictate how big one of the children
3159             // (columns) is supposed to be.
3160 
3161             // A column has been resized and JTable may need to distribute
3162             // any overall delta to other columns, according to the resize mode.
3163             int columnIndex = viewIndexForColumn(resizingColumn);
3164             int delta = getWidth() - getColumnModel().getTotalColumnWidth();
3165             accommodateDelta(columnIndex, delta);
3166             delta = getWidth() - getColumnModel().getTotalColumnWidth();


3184             // Thereafter, during window resizing etc. it has to work off
3185             // the preferred sizes as usual - the idea being that, whatever
3186             // the user does, everything stays in synch and things don't jump
3187             // around.
3188             setWidthsFromPreferredWidths(true);
3189         }
3190 
3191         super.doLayout();
3192     }
3193 
3194     private TableColumn getResizingColumn() {
3195         return (tableHeader == null) ? null
3196                                      : tableHeader.getResizingColumn();
3197     }
3198 
3199     /**
3200      * Sizes the table columns to fit the available space.
3201      *
3202      * @param lastColumnOnly determines whether to resize last column only
3203      * @deprecated As of Swing version 1.0.3,
3204      * replaced by <code>doLayout()</code>.
3205      * @see #doLayout
3206      */
3207     @Deprecated
3208     public void sizeColumnsToFit(boolean lastColumnOnly) {
3209         int oldAutoResizeMode = autoResizeMode;
3210         setAutoResizeMode(lastColumnOnly ? AUTO_RESIZE_LAST_COLUMN
3211                                          : AUTO_RESIZE_ALL_COLUMNS);
3212         sizeColumnsToFit(-1);
3213         setAutoResizeMode(oldAutoResizeMode);
3214     }
3215 
3216     /**
3217      * Obsolete as of Java 2 platform v1.4.  Please use the
3218      * <code>doLayout()</code> method instead.
3219      * @param resizingColumn    the column whose resizing made this adjustment
3220      *                          necessary or -1 if there is no such column
3221      * @see  #doLayout
3222      */
3223     public void sizeColumnsToFit(int resizingColumn) {
3224         if (resizingColumn == -1) {
3225             setWidthsFromPreferredWidths(false);
3226         }
3227         else {
3228             if (autoResizeMode == AUTO_RESIZE_OFF) {
3229                 TableColumn aColumn = getColumnModel().getColumn(resizingColumn);
3230                 aColumn.setPreferredWidth(aColumn.getWidth());
3231             }
3232             else {
3233                 int delta = getWidth() - getColumnModel().getTotalColumnWidth();
3234                 accommodateDelta(resizingColumn, delta);
3235                 setWidthsFromPreferredWidths(true);
3236             }
3237         }
3238     }


3374             // In this case, lowerBound == upperBound, for all subsequent terms.
3375             int newSize;
3376             if (totalLowerBound == totalUpperBound) {
3377                 newSize = lowerBound;
3378             }
3379             else {
3380                 double f = (double)(target - totalLowerBound)/(totalUpperBound - totalLowerBound);
3381                 newSize = (int)Math.round(lowerBound+f*(upperBound - lowerBound));
3382                 // We'd need to round manually in an all integer version.
3383                 // size[i] = (int)(((totalUpperBound - target) * lowerBound +
3384                 //     (target - totalLowerBound) * upperBound)/(totalUpperBound-totalLowerBound));
3385             }
3386             r.setSizeAt(newSize, i);
3387             target -= newSize;
3388             totalLowerBound -= lowerBound;
3389             totalUpperBound -= upperBound;
3390         }
3391     }
3392 
3393     /**
3394      * Overrides <code>JComponent</code>'s <code>getToolTipText</code>
3395      * method in order to allow the renderer's tips to be used
3396      * if it has text set.
3397      * <p>
3398      * <b>Note:</b> For <code>JTable</code> to properly display
3399      * tooltips of its renderers
3400      * <code>JTable</code> must be a registered component with the
3401      * <code>ToolTipManager</code>.
3402      * This is done automatically in <code>initializeLocalVars</code>,
3403      * but if at a later point <code>JTable</code> is told
3404      * <code>setToolTipText(null)</code> it will unregister the table
3405      * component, and no tips from renderers will display anymore.
3406      *
3407      * @see JComponent#getToolTipText
3408      */
3409     public String getToolTipText(MouseEvent event) {
3410         String tip = null;
3411         Point p = event.getPoint();
3412 
3413         // Locate the renderer under the event location
3414         int hitColumnIndex = columnAtPoint(p);
3415         int hitRowIndex = rowAtPoint(p);
3416 
3417         if ((hitColumnIndex != -1) && (hitRowIndex != -1)) {
3418             TableCellRenderer renderer = getCellRenderer(hitRowIndex, hitColumnIndex);
3419             Component component = prepareRenderer(renderer, hitRowIndex, hitColumnIndex);
3420 
3421             // Now have to see if the component is a JComponent before
3422             // getting the tip
3423             if (component instanceof JComponent) {
3424                 // Convert the event to the renderer's coordinate system


3466     public void setSurrendersFocusOnKeystroke(boolean surrendersFocusOnKeystroke) {
3467         this.surrendersFocusOnKeystroke = surrendersFocusOnKeystroke;
3468     }
3469 
3470     /**
3471      * Returns true if the editor should get the focus
3472      * when keystrokes cause the editor to be activated
3473      *
3474      * @return  true if the editor should get the focus
3475      *          when keystrokes cause the editor to be
3476      *          activated
3477      *
3478      * @see #setSurrendersFocusOnKeystroke
3479      * @since 1.4
3480      */
3481     public boolean getSurrendersFocusOnKeystroke() {
3482         return surrendersFocusOnKeystroke;
3483     }
3484 
3485     /**
3486      * Programmatically starts editing the cell at <code>row</code> and
3487      * <code>column</code>, if those indices are in the valid range, and
3488      * the cell at those indices is editable.
3489      * Note that this is a convenience method for
3490      * <code>editCellAt(int, int, null)</code>.
3491      *
3492      * @param   row                             the row to be edited
3493      * @param   column                          the column to be edited
3494      * @return  false if for any reason the cell cannot be edited,
3495      *                or if the indices are invalid
3496      */
3497     public boolean editCellAt(int row, int column) {
3498         return editCellAt(row, column, null);
3499     }
3500 
3501     /**
3502      * Programmatically starts editing the cell at <code>row</code> and
3503      * <code>column</code>, if those indices are in the valid range, and
3504      * the cell at those indices is editable.
3505      * To prevent the <code>JTable</code> from
3506      * editing a particular table, column or cell value, return false from
3507      * the <code>isCellEditable</code> method in the <code>TableModel</code>
3508      * interface.
3509      *
3510      * @param   row     the row to be edited
3511      * @param   column  the column to be edited
3512      * @param   e       event to pass into <code>shouldSelectCell</code>;
3513      *                  note that as of Java 2 platform v1.2, the call to
3514      *                  <code>shouldSelectCell</code> is no longer made
3515      * @return  false if for any reason the cell cannot be edited,
3516      *                or if the indices are invalid
3517      */
3518     public boolean editCellAt(int row, int column, EventObject e){
3519         if (cellEditor != null && !cellEditor.stopCellEditing()) {
3520             return false;
3521         }
3522 
3523         if (row < 0 || row >= getRowCount() ||
3524             column < 0 || column >= getColumnCount()) {
3525             return false;
3526         }
3527 
3528         if (!isCellEditable(row, column))
3529             return false;
3530 
3531         if (editorRemover == null) {
3532             KeyboardFocusManager fm =
3533                 KeyboardFocusManager.getCurrentKeyboardFocusManager();
3534             editorRemover = new CellEditorRemover(fm);


3592 
3593     /**
3594      * Returns the index of the row that contains the cell currently
3595      * being edited.  If nothing is being edited, returns -1.
3596      *
3597      * @return  the index of the row that contains the cell currently
3598      *          being edited; returns -1 if nothing being edited
3599      * @see #editingColumn
3600      */
3601     public int getEditingRow() {
3602         return editingRow;
3603     }
3604 
3605 //
3606 // Managing TableUI
3607 //
3608 
3609     /**
3610      * Returns the L&amp;F object that renders this component.
3611      *
3612      * @return the <code>TableUI</code> object that renders this component
3613      */
3614     public TableUI getUI() {
3615         return (TableUI)ui;
3616     }
3617 
3618     /**
3619      * Sets the L&amp;F object that renders this component and repaints.
3620      *
3621      * @param ui  the TableUI L&amp;F object
3622      * @see UIDefaults#getUI
3623      * @beaninfo
3624      *        bound: true
3625      *       hidden: true
3626      *    attribute: visualUpdate true
3627      *  description: The UI object that implements the Component's LookAndFeel.
3628      */
3629     public void setUI(TableUI ui) {
3630         if (this.ui != ui) {
3631             super.setUI(ui);
3632             repaint();
3633         }
3634     }
3635 
3636     /**
3637      * Notification from the <code>UIManager</code> that the L&amp;F has changed.
3638      * Replaces the current UI object with the latest version from the
3639      * <code>UIManager</code>.
3640      *
3641      * @see JComponent#updateUI
3642      */
3643     public void updateUI() {
3644         // Update the UIs of the cell renderers, cell editors and header renderers.
3645         TableColumnModel cm = getColumnModel();
3646         for(int column = 0; column < cm.getColumnCount(); column++) {
3647             TableColumn aColumn = cm.getColumn(column);
3648             SwingUtilities.updateRendererOrEditorUI(aColumn.getCellRenderer());
3649             SwingUtilities.updateRendererOrEditorUI(aColumn.getCellEditor());
3650             SwingUtilities.updateRendererOrEditorUI(aColumn.getHeaderRenderer());
3651         }
3652 
3653         // Update the UIs of all the default renderers.
3654         Enumeration<?> defaultRenderers = defaultRenderersByColumnClass.elements();
3655         while (defaultRenderers.hasMoreElements()) {
3656             SwingUtilities.updateRendererOrEditorUI(defaultRenderers.nextElement());
3657         }
3658 
3659         // Update the UIs of all the default editors.


3812         }
3813     }
3814 
3815     /**
3816      * Returns the {@code ListSelectionModel} that is used to maintain row
3817      * selection state.
3818      *
3819      * @return the object that provides row selection state, {@code null} if row
3820      *         selection is not allowed
3821      * @see #setSelectionModel
3822      */
3823     public ListSelectionModel getSelectionModel() {
3824         return selectionModel;
3825     }
3826 
3827 //
3828 // RowSorterListener
3829 //
3830 
3831     /**
3832      * <code>RowSorterListener</code> notification that the
3833      * <code>RowSorter</code> has changed in some way.
3834      *
3835      * @param e the <code>RowSorterEvent</code> describing the change
3836      * @throws NullPointerException if <code>e</code> is <code>null</code>
3837      * @since 1.6
3838      */
3839     public void sorterChanged(RowSorterEvent e) {
3840         if (e.getType() == RowSorterEvent.Type.SORT_ORDER_CHANGED) {
3841             JTableHeader header = getTableHeader();
3842             if (header != null) {
3843                 header.repaint();
3844             }
3845         }
3846         else if (e.getType() == RowSorterEvent.Type.SORTED) {
3847             sorterChanged = true;
3848             if (!ignoreSortChange) {
3849                 sortedTableChanged(e, null);
3850             }
3851         }
3852     }
3853 
3854 
3855     /**
3856      * SortManager provides support for managing the selection and variable


4108         int length;
4109 
4110         // True if the event indicates all the contents have changed
4111         boolean allRowsChanged;
4112 
4113         ModelChange(TableModelEvent e) {
4114             startModelIndex = Math.max(0, e.getFirstRow());
4115             endModelIndex = e.getLastRow();
4116             modelRowCount = getModel().getRowCount();
4117             if (endModelIndex < 0) {
4118                 endModelIndex = Math.max(0, modelRowCount - 1);
4119             }
4120             length = endModelIndex - startModelIndex + 1;
4121             type = e.getType();
4122             event = e;
4123             allRowsChanged = (e.getLastRow() == Integer.MAX_VALUE);
4124         }
4125     }
4126 
4127     /**
4128      * Invoked when <code>sorterChanged</code> is invoked, or
4129      * when <code>tableChanged</code> is invoked and sorting is enabled.
4130      */
4131     private void sortedTableChanged(RowSorterEvent sortedEvent,
4132                                     TableModelEvent e) {
4133         int editingModelIndex = -1;
4134         ModelChange change = (e != null) ? new ModelChange(e) : null;
4135 
4136         if ((change == null || !change.allRowsChanged) &&
4137                 this.editingRow != -1) {
4138             editingModelIndex = convertRowIndexToModel(sortedEvent,
4139                                                        this.editingRow);
4140         }
4141 
4142         sortManager.prepareForChange(sortedEvent, change);
4143 
4144         if (e != null) {
4145             if (change.type == TableModelEvent.UPDATE) {
4146                 repaintSortedRows(change);
4147             }
4148             notifySorter(change);
4149             if (change.type != TableModelEvent.UPDATE) {


4365     private int convertRowIndexToModel(RowSorterEvent e, int viewIndex) {
4366         if (e != null) {
4367             if (e.getPreviousRowCount() == 0) {
4368                 return viewIndex;
4369             }
4370             // range checking handled by RowSorterEvent
4371             return e.convertPreviousRowIndexToModel(viewIndex);
4372         }
4373         // Make sure the viewIndex is valid
4374         if (viewIndex < 0 || viewIndex >= getRowCount()) {
4375             return -1;
4376         }
4377         return convertRowIndexToModel(viewIndex);
4378     }
4379 
4380 //
4381 // Implementing TableModelListener interface
4382 //
4383 
4384     /**
4385      * Invoked when this table's <code>TableModel</code> generates
4386      * a <code>TableModelEvent</code>.
4387      * The <code>TableModelEvent</code> should be constructed in the
4388      * coordinate system of the model; the appropriate mapping to the
4389      * view coordinate system is performed by this <code>JTable</code>
4390      * when it receives the event.
4391      * <p>
4392      * Application code will not use these methods explicitly, they
4393      * are used internally by <code>JTable</code>.
4394      * <p>
4395      * Note that as of 1.3, this method clears the selection, if any.
4396      */
4397     public void tableChanged(TableModelEvent e) {
4398         if (e == null || e.getFirstRow() == TableModelEvent.HEADER_ROW) {
4399             // The whole thing changed
4400             clearSelectionAndLeadAnchor();
4401 
4402             rowModel = null;
4403 
4404             if (sortManager != null) {
4405                 try {
4406                     ignoreSortChange = true;
4407                     sortManager.sorter.modelStructureChanged();
4408                 } finally {
4409                     ignoreSortChange = false;
4410                 }
4411                 sortManager.allChanged();
4412             }
4413 


4624      * @see TableColumnModelListener
4625      */
4626     public void columnMarginChanged(ChangeEvent e) {
4627         if (isEditing() && !getCellEditor().stopCellEditing()) {
4628             getCellEditor().cancelCellEditing();
4629         }
4630         TableColumn resizingColumn = getResizingColumn();
4631         // Need to do this here, before the parent's
4632         // layout manager calls getPreferredSize().
4633         if (resizingColumn != null && autoResizeMode == AUTO_RESIZE_OFF) {
4634             resizingColumn.setPreferredWidth(resizingColumn.getWidth());
4635         }
4636         resizeAndRepaint();
4637     }
4638 
4639     private int limit(int i, int a, int b) {
4640         return Math.min(b, Math.max(i, a));
4641     }
4642 
4643     /**
4644      * Invoked when the selection model of the <code>TableColumnModel</code>
4645      * is changed.
4646      * <p>
4647      * Application code will not use these methods explicitly, they
4648      * are used internally by JTable.
4649      *
4650      * @param  e  the event received
4651      * @see TableColumnModelListener
4652      */
4653     public void columnSelectionChanged(ListSelectionEvent e) {
4654         boolean isAdjusting = e.getValueIsAdjusting();
4655         if (columnSelectionAdjusting && !isAdjusting) {
4656             // The assumption is that when the model is no longer adjusting
4657             // we will have already gotten all the changes, and therefore
4658             // don't need to do an additional paint.
4659             columnSelectionAdjusting = false;
4660             return;
4661         }
4662         columnSelectionAdjusting = isAdjusting;
4663         // The getCellRect() call will fail unless there is at least one row.
4664         if (getRowCount() <= 0 || getColumnCount() <= 0) {


4764      * Invoked when editing is canceled. The editor object is discarded
4765      * and the cell is rendered once again.
4766      * <p>
4767      * Application code will not use these methods explicitly, they
4768      * are used internally by JTable.
4769      *
4770      * @param  e  the event received
4771      * @see CellEditorListener
4772      */
4773     public void editingCanceled(ChangeEvent e) {
4774         removeEditor();
4775     }
4776 
4777 //
4778 // Implementing the Scrollable interface
4779 //
4780 
4781     /**
4782      * Sets the preferred size of the viewport for this table.
4783      *
4784      * @param size  a <code>Dimension</code> object specifying the <code>preferredSize</code> of a
4785      *              <code>JViewport</code> whose view is this table
4786      * @see Scrollable#getPreferredScrollableViewportSize
4787      * @beaninfo
4788      * description: The preferred size of the viewport.
4789      */
4790     public void setPreferredScrollableViewportSize(Dimension size) {
4791         preferredViewportSize = size;
4792     }
4793 
4794     /**
4795      * Returns the preferred size of the viewport for this table.
4796      *
4797      * @return a <code>Dimension</code> object containing the <code>preferredSize</code> of the <code>JViewport</code>
4798      *         which displays this table
4799      * @see Scrollable#getPreferredScrollableViewportSize
4800      */
4801     public Dimension getPreferredScrollableViewportSize() {
4802         return preferredViewportSize;
4803     }
4804 
4805     /**
4806      * Returns the scroll increment (in pixels) that completely exposes one new
4807      * row or column (depending on the orientation).
4808      * <p>
4809      * This method is called each time the user requests a unit scroll.
4810      *
4811      * @param visibleRect the view area visible within the viewport
4812      * @param orientation either <code>SwingConstants.VERTICAL</code>
4813      *                  or <code>SwingConstants.HORIZONTAL</code>
4814      * @param direction less than zero to scroll up/left,
4815      *                  greater than zero for down/right
4816      * @return the "unit" increment for scrolling in the specified direction
4817      * @see Scrollable#getScrollableUnitIncrement
4818      */
4819     public int getScrollableUnitIncrement(Rectangle visibleRect,
4820                                           int orientation,
4821                                           int direction) {
4822         int leadingRow;
4823         int leadingCol;
4824         Rectangle leadingCellRect;
4825 
4826         int leadingVisibleEdge;
4827         int leadingCellEdge;
4828         int leadingCellSize;
4829 
4830         leadingRow = getLeadingRow(visibleRect);
4831         leadingCol = getLeadingCol(visibleRect);
4832         if (orientation == SwingConstants.VERTICAL && leadingRow < 0) {
4833             // Couldn't find leading row - return some default value


4888             else { // Case #2: hide leading cell
4889                 return leadingCellSize;
4890             }
4891         }
4892         else { // Leading cell is partially hidden
4893             // Compute visible, hidden portions
4894             int hiddenAmt = Math.abs(leadingVisibleEdge - leadingCellEdge);
4895             int visibleAmt = leadingCellSize - hiddenAmt;
4896 
4897             if (direction > 0) {
4898                 // Case #3: hide showing portion of leading cell
4899                 return visibleAmt;
4900             }
4901             else { // Case #4: reveal hidden portion of leading cell
4902                 return hiddenAmt;
4903             }
4904         }
4905     }
4906 
4907     /**
4908      * Returns <code>visibleRect.height</code> or
4909      * <code>visibleRect.width</code>,
4910      * depending on this table's orientation.  Note that as of Swing 1.1.1
4911      * (Java 2 v 1.2.2) the value
4912      * returned will ensure that the viewport is cleanly aligned on
4913      * a row boundary.
4914      *
4915      * @return <code>visibleRect.height</code> or
4916      *                                  <code>visibleRect.width</code>
4917      *                                  per the orientation
4918      * @see Scrollable#getScrollableBlockIncrement
4919      */
4920     public int getScrollableBlockIncrement(Rectangle visibleRect,
4921             int orientation, int direction) {
4922 
4923         if (getRowCount() == 0) {
4924             // Short-circuit empty table model
4925             if (SwingConstants.VERTICAL == orientation) {
4926                 int rh = getRowHeight();
4927                 return (rh > 0) ? Math.max(rh, (visibleRect.height / rh) * rh) :
4928                                   visibleRect.height;
4929             }
4930             else {
4931                 return visibleRect.width;
4932             }
4933         }
4934         // Shortcut for vertical scrolling of a table w/ uniform row height
4935         if (null == rowModel && SwingConstants.VERTICAL == orientation) {
4936             int row = rowAtPoint(visibleRect.getLocation());


5196     }
5197 
5198     /*
5199      * Returns the trailing edge ("end") of the given Rectangle.
5200      * For VERTICAL, this is the bottom, for left-to-right, the right side, and
5201      * for right-to-left, the left side.
5202      */
5203     private int trailingEdge(Rectangle rect, int orientation) {
5204         if (orientation == SwingConstants.VERTICAL) {
5205             return rect.y + rect.height;
5206         }
5207         else if (getComponentOrientation().isLeftToRight()) {
5208             return rect.x + rect.width;
5209         }
5210         else { // Horizontal, right-to-left
5211             return rect.x;
5212         }
5213     }
5214 
5215     /**
5216      * Returns false if <code>autoResizeMode</code> is set to
5217      * <code>AUTO_RESIZE_OFF</code>, which indicates that the
5218      * width of the viewport does not determine the width
5219      * of the table.  Otherwise returns true.
5220      *
5221      * @return false if <code>autoResizeMode</code> is set
5222      *   to <code>AUTO_RESIZE_OFF</code>, otherwise returns true
5223      * @see Scrollable#getScrollableTracksViewportWidth
5224      */
5225     public boolean getScrollableTracksViewportWidth() {
5226         return !(autoResizeMode == AUTO_RESIZE_OFF);
5227     }
5228 
5229     /**
5230      * Returns {@code false} to indicate that the height of the viewport does
5231      * not determine the height of the table, unless
5232      * {@code getFillsViewportHeight} is {@code true} and the preferred height
5233      * of the table is smaller than the viewport's height.
5234      *
5235      * @return {@code false} unless {@code getFillsViewportHeight} is
5236      *         {@code true} and the table needs to be stretched to fill
5237      *         the viewport
5238      * @see Scrollable#getScrollableTracksViewportHeight
5239      * @see #setFillsViewportHeight
5240      * @see #getFillsViewportHeight
5241      */
5242     public boolean getScrollableTracksViewportHeight() {


5572         setAutoResizeMode(AUTO_RESIZE_SUBSEQUENT_COLUMNS);
5573         setRowHeight(16);
5574         isRowHeightSet = false;
5575         setRowMargin(1);
5576         setRowSelectionAllowed(true);
5577         setCellEditor(null);
5578         setEditingColumn(-1);
5579         setEditingRow(-1);
5580         setSurrendersFocusOnKeystroke(false);
5581         setPreferredScrollableViewportSize(new Dimension(450, 400));
5582 
5583         // I'm registered to do tool tips so we can draw tips for the renderers
5584         ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
5585         toolTipManager.registerComponent(this);
5586 
5587         setAutoscrolls(true);
5588     }
5589 
5590     /**
5591      * Returns the default table model object, which is
5592      * a <code>DefaultTableModel</code>.  A subclass can override this
5593      * method to return a different table model object.
5594      *
5595      * @return the default table model object
5596      * @see javax.swing.table.DefaultTableModel
5597      */
5598     protected TableModel createDefaultDataModel() {
5599         return new DefaultTableModel();
5600     }
5601 
5602     /**
5603      * Returns the default column model object, which is
5604      * a <code>DefaultTableColumnModel</code>.  A subclass can override this
5605      * method to return a different column model object.
5606      *
5607      * @return the default column model object
5608      * @see javax.swing.table.DefaultTableColumnModel
5609      */
5610     protected TableColumnModel createDefaultColumnModel() {
5611         return new DefaultTableColumnModel();
5612     }
5613 
5614     /**
5615      * Returns the default selection model object, which is
5616      * a <code>DefaultListSelectionModel</code>.  A subclass can override this
5617      * method to return a different selection model object.
5618      *
5619      * @return the default selection model object
5620      * @see javax.swing.DefaultListSelectionModel
5621      */
5622     protected ListSelectionModel createDefaultSelectionModel() {
5623         return new DefaultListSelectionModel();
5624     }
5625 
5626     /**
5627      * Returns the default table header object, which is
5628      * a <code>JTableHeader</code>.  A subclass can override this
5629      * method to return a different table header object.
5630      *
5631      * @return the default table header object
5632      * @see javax.swing.table.JTableHeader
5633      */
5634     protected JTableHeader createDefaultTableHeader() {
5635         return new JTableHeader(columnModel);
5636     }
5637 
5638     /**
5639      * Equivalent to <code>revalidate</code> followed by <code>repaint</code>.
5640      */
5641     protected void resizeAndRepaint() {
5642         revalidate();
5643         repaint();
5644     }
5645 
5646     /**
5647      * Returns the active cell editor, which is {@code null} if the table
5648      * is not currently editing.
5649      *
5650      * @return the {@code TableCellEditor} that does the editing,
5651      *         or {@code null} if the table is not currently editing.
5652      * @see #cellEditor
5653      * @see #getCellEditor(int, int)
5654      */
5655     public TableCellEditor getCellEditor() {
5656         return cellEditor;
5657     }
5658 
5659     /**
5660      * Sets the active cell editor.
5661      *
5662      * @param anEditor the active cell editor
5663      * @see #cellEditor
5664      * @beaninfo
5665      *  bound: true
5666      *  description: The table's active cell editor.
5667      */
5668     public void setCellEditor(TableCellEditor anEditor) {
5669         TableCellEditor oldEditor = cellEditor;
5670         cellEditor = anEditor;
5671         firePropertyChange("tableCellEditor", oldEditor, anEditor);
5672     }
5673 
5674     /**
5675      * Sets the <code>editingColumn</code> variable.
5676      * @param aColumn  the column of the cell to be edited
5677      *
5678      * @see #editingColumn
5679      */
5680     public void setEditingColumn(int aColumn) {
5681         editingColumn = aColumn;
5682     }
5683 
5684     /**
5685      * Sets the <code>editingRow</code> variable.
5686      * @param aRow  the row of the cell to be edited
5687      *
5688      * @see #editingRow
5689      */
5690     public void setEditingRow(int aRow) {
5691         editingRow = aRow;
5692     }
5693 
5694     /**
5695      * Returns an appropriate renderer for the cell specified by this row and
5696      * column. If the <code>TableColumn</code> for this column has a non-null
5697      * renderer, returns that.  If not, finds the class of the data in
5698      * this column (using <code>getColumnClass</code>)
5699      * and returns the default renderer for this type of data.
5700      * <p>
5701      * <b>Note:</b>
5702      * Throughout the table package, the internal implementations always
5703      * use this method to provide renderers so that this default behavior
5704      * can be safely overridden by a subclass.
5705      *
5706      * @param row       the row of the cell to render, where 0 is the first row
5707      * @param column    the column of the cell to render,
5708      *                  where 0 is the first column
5709      * @return the assigned renderer; if <code>null</code>
5710      *                  returns the default renderer
5711      *                  for this type of object
5712      * @see javax.swing.table.DefaultTableCellRenderer
5713      * @see javax.swing.table.TableColumn#setCellRenderer
5714      * @see #setDefaultRenderer
5715      */
5716     public TableCellRenderer getCellRenderer(int row, int column) {
5717         TableColumn tableColumn = getColumnModel().getColumn(column);
5718         TableCellRenderer renderer = tableColumn.getCellRenderer();
5719         if (renderer == null) {
5720             renderer = getDefaultRenderer(getColumnClass(column));
5721         }
5722         return renderer;
5723     }
5724 
5725     /**
5726      * Prepares the renderer by querying the data model for the
5727      * value and selection state
5728      * of the cell at <code>row</code>, <code>column</code>.
5729      * Returns the component (may be a <code>Component</code>
5730      * or a <code>JComponent</code>) under the event location.
5731      * <p>
5732      * During a printing operation, this method will configure the
5733      * renderer without indicating selection or focus, to prevent
5734      * them from appearing in the printed output. To do other
5735      * customizations based on whether or not the table is being
5736      * printed, you can check the value of
5737      * {@link javax.swing.JComponent#isPaintingForPrint()}, either here
5738      * or within custom renderers.
5739      * <p>
5740      * <b>Note:</b>
5741      * Throughout the table package, the internal implementations always
5742      * use this method to prepare renderers so that this default behavior
5743      * can be safely overridden by a subclass.
5744      *
5745      * @param renderer  the <code>TableCellRenderer</code> to prepare
5746      * @param row       the row of the cell to render, where 0 is the first row
5747      * @param column    the column of the cell to render,
5748      *                  where 0 is the first column
5749      * @return          the <code>Component</code> under the event location
5750      */
5751     public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
5752         Object value = getValueAt(row, column);
5753 
5754         boolean isSelected = false;
5755         boolean hasFocus = false;
5756 
5757         // Only indicate the selection and focused cell if not printing
5758         if (!isPaintingForPrint()) {
5759             isSelected = isCellSelected(row, column);
5760 
5761             boolean rowIsLead =
5762                 (selectionModel.getLeadSelectionIndex() == row);
5763             boolean colIsLead =
5764                 (columnModel.getSelectionModel().getLeadSelectionIndex() == column);
5765 
5766             hasFocus = (rowIsLead && colIsLead) && isFocusOwner();
5767         }
5768 
5769         return renderer.getTableCellRendererComponent(this, value,
5770                                                       isSelected, hasFocus,
5771                                                       row, column);
5772     }
5773 
5774     /**
5775      * Returns an appropriate editor for the cell specified by
5776      * <code>row</code> and <code>column</code>. If the
5777      * <code>TableColumn</code> for this column has a non-null editor,
5778      * returns that.  If not, finds the class of the data in this
5779      * column (using <code>getColumnClass</code>)
5780      * and returns the default editor for this type of data.
5781      * <p>
5782      * <b>Note:</b>
5783      * Throughout the table package, the internal implementations always
5784      * use this method to provide editors so that this default behavior
5785      * can be safely overridden by a subclass.
5786      *
5787      * @param row       the row of the cell to edit, where 0 is the first row
5788      * @param column    the column of the cell to edit,
5789      *                  where 0 is the first column
5790      * @return          the editor for this cell;
5791      *                  if <code>null</code> return the default editor for
5792      *                  this type of cell
5793      * @see DefaultCellEditor
5794      */
5795     public TableCellEditor getCellEditor(int row, int column) {
5796         TableColumn tableColumn = getColumnModel().getColumn(column);
5797         TableCellEditor editor = tableColumn.getCellEditor();
5798         if (editor == null) {
5799             editor = getDefaultEditor(getColumnClass(column));
5800         }
5801         return editor;
5802     }
5803 
5804 
5805     /**
5806      * Prepares the editor by querying the data model for the value and
5807      * selection state of the cell at <code>row</code>, <code>column</code>.
5808      * <p>
5809      * <b>Note:</b>
5810      * Throughout the table package, the internal implementations always
5811      * use this method to prepare editors so that this default behavior
5812      * can be safely overridden by a subclass.
5813      *
5814      * @param editor  the <code>TableCellEditor</code> to set up
5815      * @param row     the row of the cell to edit,
5816      *                where 0 is the first row
5817      * @param column  the column of the cell to edit,
5818      *                where 0 is the first column
5819      * @return the <code>Component</code> being edited
5820      */
5821     @SuppressWarnings("deprecation")
5822     public Component prepareEditor(TableCellEditor editor, int row, int column) {
5823         Object value = getValueAt(row, column);
5824         boolean isSelected = isCellSelected(row, column);
5825         Component comp = editor.getTableCellEditorComponent(this, value, isSelected,
5826                                                   row, column);
5827         if (comp instanceof JComponent) {
5828             JComponent jComp = (JComponent)comp;
5829             if (jComp.getNextFocusableComponent() == null) {
5830                 jComp.setNextFocusableComponent(this);
5831             }
5832         }
5833         return comp;
5834     }
5835 
5836     /**
5837      * Discards the editor object and frees the real estate it used for
5838      * cell rendering.
5839      */


5972          }
5973     }
5974 
5975     /* Called from the JComponent's EnableSerializationFocusListener to
5976      * do any Swing-specific pre-serialization configuration.
5977      */
5978     void compWriteObjectNotify() {
5979         super.compWriteObjectNotify();
5980         // If ToolTipText != null, then the tooltip has already been
5981         // unregistered by JComponent.compWriteObjectNotify()
5982         if (getToolTipText() == null) {
5983             ToolTipManager.sharedInstance().unregisterComponent(this);
5984         }
5985     }
5986 
5987     /**
5988      * Returns a string representation of this table. This method
5989      * is intended to be used only for debugging purposes, and the
5990      * content and format of the returned string may vary between
5991      * implementations. The returned string may be empty but may not
5992      * be <code>null</code>.
5993      *
5994      * @return  a string representation of this table
5995      */
5996     protected String paramString() {
5997         String gridColorString = (gridColor != null ?
5998                                   gridColor.toString() : "");
5999         String showHorizontalLinesString = (showHorizontalLines ?
6000                                             "true" : "false");
6001         String showVerticalLinesString = (showVerticalLines ?
6002                                           "true" : "false");
6003         String autoResizeModeString;
6004         if (autoResizeMode == AUTO_RESIZE_OFF) {
6005             autoResizeModeString = "AUTO_RESIZE_OFF";
6006         } else if (autoResizeMode == AUTO_RESIZE_NEXT_COLUMN) {
6007             autoResizeModeString = "AUTO_RESIZE_NEXT_COLUMN";
6008         } else if (autoResizeMode == AUTO_RESIZE_SUBSEQUENT_COLUMNS) {
6009             autoResizeModeString = "AUTO_RESIZE_SUBSEQUENT_COLUMNS";
6010         } else if (autoResizeMode == AUTO_RESIZE_LAST_COLUMN) {
6011             autoResizeModeString = "AUTO_RESIZE_LAST_COLUMN";
6012         } else if (autoResizeMode == AUTO_RESIZE_ALL_COLUMNS)  {


6069                 } else if ((c instanceof Window) ||
6070                            (c instanceof Applet && c.getParent() == null)) {
6071                     if (c == SwingUtilities.getRoot(JTable.this)) {
6072                         if (!getCellEditor().stopCellEditing()) {
6073                             getCellEditor().cancelCellEditing();
6074                         }
6075                     }
6076                     break;
6077                 }
6078                 c = c.getParent();
6079             }
6080         }
6081     }
6082 
6083 /////////////////
6084 // Printing Support
6085 /////////////////
6086 
6087     /**
6088      * A convenience method that displays a printing dialog, and then prints
6089      * this <code>JTable</code> in mode <code>PrintMode.FIT_WIDTH</code>,
6090      * with no header or footer text. A modal progress dialog, with an abort
6091      * option, will be shown for the duration of printing.
6092      * <p>
6093      * Note: In headless mode, no dialogs are shown and printing
6094      * occurs on the default printer.
6095      *
6096      * @return true, unless printing is cancelled by the user
6097      * @throws SecurityException if this thread is not allowed to
6098      *                           initiate a print job request
6099      * @throws PrinterException if an error in the print system causes the job
6100      *                          to be aborted
6101      * @see #print(JTable.PrintMode, MessageFormat, MessageFormat,
6102      *             boolean, PrintRequestAttributeSet, boolean, PrintService)
6103      * @see #getPrintable
6104      *
6105      * @since 1.5
6106      */
6107     public boolean print() throws PrinterException {
6108 
6109         return print(PrintMode.FIT_WIDTH);
6110     }
6111 
6112     /**
6113      * A convenience method that displays a printing dialog, and then prints
6114      * this <code>JTable</code> in the given printing mode,
6115      * with no header or footer text. A modal progress dialog, with an abort
6116      * option, will be shown for the duration of printing.
6117      * <p>
6118      * Note: In headless mode, no dialogs are shown and printing
6119      * occurs on the default printer.
6120      *
6121      * @param  printMode        the printing mode that the printable should use
6122      * @return true, unless printing is cancelled by the user
6123      * @throws SecurityException if this thread is not allowed to
6124      *                           initiate a print job request
6125      * @throws PrinterException if an error in the print system causes the job
6126      *                          to be aborted
6127      * @see #print(JTable.PrintMode, MessageFormat, MessageFormat,
6128      *             boolean, PrintRequestAttributeSet, boolean, PrintService)
6129      * @see #getPrintable
6130      *
6131      * @since 1.5
6132      */
6133     public boolean print(PrintMode printMode) throws PrinterException {
6134 
6135         return print(printMode, null, null);
6136     }
6137 
6138     /**
6139      * A convenience method that displays a printing dialog, and then prints
6140      * this <code>JTable</code> in the given printing mode,
6141      * with the specified header and footer text. A modal progress dialog,
6142      * with an abort option, will be shown for the duration of printing.
6143      * <p>
6144      * Note: In headless mode, no dialogs are shown and printing
6145      * occurs on the default printer.
6146      *
6147      * @param  printMode        the printing mode that the printable should use
6148      * @param  headerFormat     a <code>MessageFormat</code> specifying the text
6149      *                          to be used in printing a header,
6150      *                          or null for none
6151      * @param  footerFormat     a <code>MessageFormat</code> specifying the text
6152      *                          to be used in printing a footer,
6153      *                          or null for none
6154      * @return true, unless printing is cancelled by the user
6155      * @throws SecurityException if this thread is not allowed to
6156      *                           initiate a print job request
6157      * @throws PrinterException if an error in the print system causes the job
6158      *                          to be aborted
6159      * @see #print(JTable.PrintMode, MessageFormat, MessageFormat,
6160      *             boolean, PrintRequestAttributeSet, boolean, PrintService)
6161      * @see #getPrintable
6162      *
6163      * @since 1.5
6164      */
6165     public boolean print(PrintMode printMode,
6166                          MessageFormat headerFormat,
6167                          MessageFormat footerFormat) throws PrinterException {
6168 
6169         boolean showDialogs = !GraphicsEnvironment.isHeadless();
6170         return print(printMode, headerFormat, footerFormat,
6171                      showDialogs, null, showDialogs);
6172     }
6173 
6174     /**
6175      * Prints this table, as specified by the fully featured
6176      * {@link #print(JTable.PrintMode, MessageFormat, MessageFormat,
6177      * boolean, PrintRequestAttributeSet, boolean, PrintService) print}
6178      * method, with the default printer specified as the print service.
6179      *
6180      * @param  printMode        the printing mode that the printable should use
6181      * @param  headerFormat     a <code>MessageFormat</code> specifying the text
6182      *                          to be used in printing a header,
6183      *                          or <code>null</code> for none
6184      * @param  footerFormat     a <code>MessageFormat</code> specifying the text
6185      *                          to be used in printing a footer,
6186      *                          or <code>null</code> for none
6187      * @param  showPrintDialog  whether or not to display a print dialog
6188      * @param  attr             a <code>PrintRequestAttributeSet</code>
6189      *                          specifying any printing attributes,
6190      *                          or <code>null</code> for none
6191      * @param  interactive      whether or not to print in an interactive mode
6192      * @return true, unless printing is cancelled by the user
6193      * @throws HeadlessException if the method is asked to show a printing
6194      *                           dialog or run interactively, and
6195      *                           <code>GraphicsEnvironment.isHeadless</code>
6196      *                           returns <code>true</code>
6197      * @throws SecurityException if this thread is not allowed to
6198      *                           initiate a print job request
6199      * @throws PrinterException if an error in the print system causes the job
6200      *                          to be aborted
6201      * @see #print(JTable.PrintMode, MessageFormat, MessageFormat,
6202      *             boolean, PrintRequestAttributeSet, boolean, PrintService)
6203      * @see #getPrintable
6204      *
6205      * @since 1.5
6206      */
6207     public boolean print(PrintMode printMode,
6208                          MessageFormat headerFormat,
6209                          MessageFormat footerFormat,
6210                          boolean showPrintDialog,
6211                          PrintRequestAttributeSet attr,
6212                          boolean interactive) throws PrinterException,
6213                                                      HeadlessException {
6214 
6215         return print(printMode,
6216                      headerFormat,
6217                      footerFormat,
6218                      showPrintDialog,
6219                      attr,
6220                      interactive,
6221                      null);
6222     }
6223 
6224     /**
6225      * Prints this <code>JTable</code>. Takes steps that the majority of
6226      * developers would take in order to print a <code>JTable</code>.
6227      * In short, it prepares the table, calls <code>getPrintable</code> to
6228      * fetch an appropriate <code>Printable</code>, and then sends it to the
6229      * printer.
6230      * <p>
6231      * A <code>boolean</code> parameter allows you to specify whether or not
6232      * a printing dialog is displayed to the user. When it is, the user may
6233      * use the dialog to change the destination printer or printing attributes,
6234      * or even to cancel the print. Another two parameters allow for a
6235      * <code>PrintService</code> and printing attributes to be specified.
6236      * These parameters can be used either to provide initial values for the
6237      * print dialog, or to specify values when the dialog is not shown.
6238      * <p>
6239      * A second <code>boolean</code> parameter allows you to specify whether
6240      * or not to perform printing in an interactive mode. If <code>true</code>,
6241      * a modal progress dialog, with an abort option, is displayed for the
6242      * duration of printing . This dialog also prevents any user action which
6243      * may affect the table. However, it can not prevent the table from being
6244      * modified by code (for example, another thread that posts updates using
6245      * <code>SwingUtilities.invokeLater</code>). It is therefore the
6246      * responsibility of the developer to ensure that no other code modifies
6247      * the table in any way during printing (invalid modifications include
6248      * changes in: size, renderers, or underlying data). Printing behavior is
6249      * undefined when the table is changed during printing.
6250      * <p>
6251      * If <code>false</code> is specified for this parameter, no dialog will
6252      * be displayed and printing will begin immediately on the event-dispatch
6253      * thread. This blocks any other events, including repaints, from being
6254      * processed until printing is complete. Although this effectively prevents
6255      * the table from being changed, it doesn't provide a good user experience.
6256      * For this reason, specifying <code>false</code> is only recommended when
6257      * printing from an application with no visible GUI.
6258      * <p>
6259      * Note: Attempting to show the printing dialog or run interactively, while
6260      * in headless mode, will result in a <code>HeadlessException</code>.
6261      * <p>
6262      * Before fetching the printable, this method will gracefully terminate
6263      * editing, if necessary, to prevent an editor from showing in the printed
6264      * result. Additionally, <code>JTable</code> will prepare its renderers
6265      * during printing such that selection and focus are not indicated.
6266      * As far as customizing further how the table looks in the printout,
6267      * developers can provide custom renderers or paint code that conditionalize
6268      * on the value of {@link javax.swing.JComponent#isPaintingForPrint()}.
6269      * <p>
6270      * See {@link #getPrintable} for more description on how the table is
6271      * printed.
6272      *
6273      * @param  printMode        the printing mode that the printable should use
6274      * @param  headerFormat     a <code>MessageFormat</code> specifying the text
6275      *                          to be used in printing a header,
6276      *                          or <code>null</code> for none
6277      * @param  footerFormat     a <code>MessageFormat</code> specifying the text
6278      *                          to be used in printing a footer,
6279      *                          or <code>null</code> for none
6280      * @param  showPrintDialog  whether or not to display a print dialog
6281      * @param  attr             a <code>PrintRequestAttributeSet</code>
6282      *                          specifying any printing attributes,
6283      *                          or <code>null</code> for none
6284      * @param  interactive      whether or not to print in an interactive mode
6285      * @param  service          the destination <code>PrintService</code>,
6286      *                          or <code>null</code> to use the default printer
6287      * @return true, unless printing is cancelled by the user
6288      * @throws HeadlessException if the method is asked to show a printing
6289      *                           dialog or run interactively, and
6290      *                           <code>GraphicsEnvironment.isHeadless</code>
6291      *                           returns <code>true</code>
6292      * @throws  SecurityException if a security manager exists and its
6293      *          {@link java.lang.SecurityManager#checkPrintJobAccess}
6294      *          method disallows this thread from creating a print job request
6295      * @throws PrinterException if an error in the print system causes the job
6296      *                          to be aborted
6297      * @see #getPrintable
6298      * @see java.awt.GraphicsEnvironment#isHeadless
6299      *
6300      * @since 1.6
6301      */
6302     public boolean print(PrintMode printMode,
6303                          MessageFormat headerFormat,
6304                          MessageFormat footerFormat,
6305                          boolean showPrintDialog,
6306                          PrintRequestAttributeSet attr,
6307                          boolean interactive,
6308                          PrintService service) throws PrinterException,
6309                                                       HeadlessException {
6310 
6311         // complain early if an invalid parameter is specified for headless mode


6419             // a subclass of PrinterException meaning the job was aborted,
6420             // in this case, by the user
6421             if (pe instanceof PrinterAbortException) {
6422                 return false;
6423             } else if (pe instanceof PrinterException) {
6424                 throw (PrinterException)pe;
6425             } else if (pe instanceof RuntimeException) {
6426                 throw (RuntimeException)pe;
6427             } else if (pe instanceof Error) {
6428                 throw (Error)pe;
6429             }
6430 
6431             // can not happen
6432             throw new AssertionError(pe);
6433         }
6434 
6435         return true;
6436     }
6437 
6438     /**
6439      * Return a <code>Printable</code> for use in printing this JTable.
6440      * <p>
6441      * This method is meant for those wishing to customize the default
6442      * <code>Printable</code> implementation used by <code>JTable</code>'s
6443      * <code>print</code> methods. Developers wanting simply to print the table
6444      * should use one of those methods directly.
6445      * <p>
6446      * The <code>Printable</code> can be requested in one of two printing modes.
6447      * In both modes, it spreads table rows naturally in sequence across
6448      * multiple pages, fitting as many rows as possible per page.
6449      * <code>PrintMode.NORMAL</code> specifies that the table be
6450      * printed at its current size. In this mode, there may be a need to spread
6451      * columns across pages in a similar manner to that of the rows. When the
6452      * need arises, columns are distributed in an order consistent with the
6453      * table's <code>ComponentOrientation</code>.
6454      * <code>PrintMode.FIT_WIDTH</code> specifies that the output be
6455      * scaled smaller, if necessary, to fit the table's entire width
6456      * (and thereby all columns) on each page. Width and height are scaled
6457      * equally, maintaining the aspect ratio of the output.
6458      * <p>
6459      * The <code>Printable</code> heads the portion of table on each page
6460      * with the appropriate section from the table's <code>JTableHeader</code>,
6461      * if it has one.
6462      * <p>
6463      * Header and footer text can be added to the output by providing
6464      * <code>MessageFormat</code> arguments. The printing code requests
6465      * Strings from the formats, providing a single item which may be included
6466      * in the formatted string: an <code>Integer</code> representing the current
6467      * page number.
6468      * <p>
6469      * You are encouraged to read the documentation for
6470      * <code>MessageFormat</code> as some characters, such as single-quote,
6471      * are special and need to be escaped.
6472      * <p>
6473      * Here's an example of creating a <code>MessageFormat</code> that can be
6474      * used to print "Duke's Table: Page - " and the current page number:
6475      *
6476      * <pre>
6477      *     // notice the escaping of the single quote
6478      *     // notice how the page number is included with "{0}"
6479      *     MessageFormat format = new MessageFormat("Duke''s Table: Page - {0}");
6480      * </pre>
6481      * <p>
6482      * The <code>Printable</code> constrains what it draws to the printable
6483      * area of each page that it prints. Under certain circumstances, it may
6484      * find it impossible to fit all of a page's content into that area. In
6485      * these cases the output may be clipped, but the implementation
6486      * makes an effort to do something reasonable. Here are a few situations
6487      * where this is known to occur, and how they may be handled by this
6488      * particular implementation:
6489      * <ul>
6490      *   <li>In any mode, when the header or footer text is too wide to fit
6491      *       completely in the printable area -- print as much of the text as
6492      *       possible starting from the beginning, as determined by the table's
6493      *       <code>ComponentOrientation</code>.
6494      *   <li>In any mode, when a row is too tall to fit in the
6495      *       printable area -- print the upper-most portion of the row
6496      *       and paint no lower border on the table.
6497      *   <li>In <code>PrintMode.NORMAL</code> when a column
6498      *       is too wide to fit in the printable area -- print the center
6499      *       portion of the column and leave the left and right borders
6500      *       off the table.
6501      * </ul>
6502      * <p>
6503      * It is entirely valid for this <code>Printable</code> to be wrapped
6504      * inside another in order to create complex reports and documents. You may
6505      * even request that different pages be rendered into different sized
6506      * printable areas. The implementation must be prepared to handle this
6507      * (possibly by doing its layout calculations on the fly). However,
6508      * providing different heights to each page will likely not work well
6509      * with <code>PrintMode.NORMAL</code> when it has to spread columns
6510      * across pages.
6511      * <p>
6512      * As far as customizing how the table looks in the printed result,
6513      * <code>JTable</code> itself will take care of hiding the selection
6514      * and focus during printing. For additional customizations, your
6515      * renderers or painting code can customize the look based on the value
6516      * of {@link javax.swing.JComponent#isPaintingForPrint()}
6517      * <p>
6518      * Also, <i>before</i> calling this method you may wish to <i>first</i>
6519      * modify the state of the table, such as to cancel cell editing or
6520      * have the user size the table appropriately. However, you must not
6521      * modify the state of the table <i>after</i> this <code>Printable</code>
6522      * has been fetched (invalid modifications include changes in size or
6523      * underlying data). The behavior of the returned <code>Printable</code>
6524      * is undefined once the table has been changed.
6525      *
6526      * @param  printMode     the printing mode that the printable should use
6527      * @param  headerFormat  a <code>MessageFormat</code> specifying the text to
6528      *                       be used in printing a header, or null for none
6529      * @param  footerFormat  a <code>MessageFormat</code> specifying the text to
6530      *                       be used in printing a footer, or null for none
6531      * @return a <code>Printable</code> for printing this JTable
6532      * @see #print(JTable.PrintMode, MessageFormat, MessageFormat,
6533      *             boolean, PrintRequestAttributeSet, boolean)
6534      * @see Printable
6535      * @see PrinterJob
6536      *
6537      * @since 1.5
6538      */
6539     public Printable getPrintable(PrintMode printMode,
6540                                   MessageFormat headerFormat,
6541                                   MessageFormat footerFormat) {
6542 
6543         return new TablePrintable(this, printMode, headerFormat, footerFormat);
6544     }
6545 
6546 
6547     /**
6548      * A <code>Printable</code> implementation that wraps another
6549      * <code>Printable</code>, making it safe for printing on another thread.
6550      */
6551     private class ThreadSafePrintable implements Printable {
6552 
6553         /** The delegate <code>Printable</code>. */
6554         private Printable printDelegate;
6555 
6556         /**
6557          * To communicate any return value when delegating.
6558          */
6559         private int retVal;
6560 
6561         /**
6562          * To communicate any <code>Throwable</code> when delegating.
6563          */
6564         private Throwable retThrowable;
6565 
6566         /**
6567          * Construct a <code>ThreadSafePrintable</code> around the given
6568          * delegate.
6569          *
6570          * @param printDelegate the <code>Printable</code> to delegate to
6571          */
6572         public ThreadSafePrintable(Printable printDelegate) {
6573             this.printDelegate = printDelegate;
6574         }
6575 
6576         /**
6577          * Prints the specified page into the given {@link Graphics}
6578          * context, in the specified format.
6579          * <p>
6580          * Regardless of what thread this method is called on, all calls into
6581          * the delegate will be done on the event-dispatch thread.
6582          *
6583          * @param   graphics    the context into which the page is drawn
6584          * @param   pageFormat  the size and orientation of the page being drawn
6585          * @param   pageIndex   the zero based index of the page to be drawn
6586          * @return  PAGE_EXISTS if the page is rendered successfully, or
6587          *          NO_SUCH_PAGE if a non-existent page index is specified
6588          * @throws  PrinterException if an error causes printing to be aborted
6589          */
6590         public int print(final Graphics graphics,


6652      * For tables, the AccessibleContext takes the form of an
6653      * AccessibleJTable.
6654      * A new AccessibleJTable instance is created if necessary.
6655      *
6656      * @return an AccessibleJTable that serves as the
6657      *         AccessibleContext of this JTable
6658      */
6659     public AccessibleContext getAccessibleContext() {
6660         if (accessibleContext == null) {
6661             accessibleContext = new AccessibleJTable();
6662         }
6663         return accessibleContext;
6664     }
6665 
6666     //
6667     // *** should also implement AccessibleSelection?
6668     // *** and what's up with keyboard navigation/manipulation?
6669     //
6670     /**
6671      * This class implements accessibility support for the
6672      * <code>JTable</code> class.  It provides an implementation of the
6673      * Java Accessibility API appropriate to table user-interface elements.
6674      * <p>
6675      * <strong>Warning:</strong>
6676      * Serialized objects of this class will not be compatible with
6677      * future Swing releases. The current serialization support is
6678      * appropriate for short term storage or RMI between applications running
6679      * the same version of Swing.  As of 1.4, support for long term storage
6680      * of all JavaBeans&trade;
6681      * has been added to the <code>java.beans</code> package.
6682      * Please see {@link java.beans.XMLEncoder}.
6683      */
6684     @SuppressWarnings("serial") // Same-version serialization only
6685     protected class AccessibleJTable extends AccessibleJComponent
6686     implements AccessibleSelection, ListSelectionListener, TableModelListener,
6687     TableColumnModelListener, CellEditorListener, PropertyChangeListener,
6688     AccessibleExtendedTable {
6689 
6690         int previousFocusedRow;
6691         int previousFocusedCol;
6692 
6693         /**
6694          * AccessibleJTable constructor
6695          *
6696          * @since 1.5
6697          */
6698         protected AccessibleJTable() {
6699             super();
6700             JTable.this.addPropertyChangeListener(this);
6701             JTable.this.getSelectionModel().addListSelectionListener(this);


7102          * AccessibleSelection interface on behalf of itself.
7103          *
7104          * @return this object
7105          */
7106         public AccessibleSelection getAccessibleSelection() {
7107             return this;
7108         }
7109 
7110         /**
7111          * Gets the role of this object.
7112          *
7113          * @return an instance of AccessibleRole describing the role of the
7114          * object
7115          * @see AccessibleRole
7116          */
7117         public AccessibleRole getAccessibleRole() {
7118             return AccessibleRole.TABLE;
7119         }
7120 
7121         /**
7122          * Returns the <code>Accessible</code> child, if one exists,
7123          * contained at the local coordinate <code>Point</code>.
7124          *
7125          * @param p the point defining the top-left corner of the
7126          *    <code>Accessible</code>, given in the coordinate space
7127          *    of the object's parent
7128          * @return the <code>Accessible</code>, if it exists,
7129          *    at the specified location; else <code>null</code>
7130          */
7131         public Accessible getAccessibleAt(Point p) {
7132             int column = columnAtPoint(p);
7133             int row = rowAtPoint(p);
7134 
7135             if ((column != -1) && (row != -1)) {
7136                 TableColumn aColumn = getColumnModel().getColumn(column);
7137                 TableCellRenderer renderer = aColumn.getCellRenderer();
7138                 if (renderer == null) {
7139                     Class<?> columnClass = getColumnClass(column);
7140                     renderer = getDefaultRenderer(columnClass);
7141                 }
7142                 Component component = renderer.getTableCellRendererComponent(
7143                                   JTable.this, null, false, false,
7144                                   row, column);
7145                 return new AccessibleJTableCell(JTable.this, row, column,
7146                       getAccessibleIndexAt(row, column));
7147             }
7148             return null;
7149         }
7150 
7151         /**
7152          * Returns the number of accessible children in the object.  If all
7153          * of the children of this object implement <code>Accessible</code>,
7154          * then this method should return the number of children of this object.
7155          *
7156          * @return the number of accessible children in the object
7157          */
7158         public int getAccessibleChildrenCount() {
7159             return (JTable.this.getColumnCount() * JTable.this.getRowCount());
7160         }
7161 
7162         /**
7163          * Returns the nth <code>Accessible</code> child of the object.
7164          *
7165          * @param i zero-based index of child
7166          * @return the nth Accessible child of the object
7167          */
7168         public Accessible getAccessibleChild(int i) {
7169             if (i < 0 || i >= getAccessibleChildrenCount()) {
7170                 return null;
7171             } else {
7172                 // children increase across, and then down, for tables
7173                 // (arbitrary decision)
7174                 int column = getAccessibleColumnAtIndex(i);
7175                 int row = getAccessibleRowAtIndex(i);
7176 
7177                 TableColumn aColumn = getColumnModel().getColumn(column);
7178                 TableCellRenderer renderer = aColumn.getCellRenderer();
7179                 if (renderer == null) {
7180                     Class<?> columnClass = getColumnClass(column);
7181                     renderer = getDefaultRenderer(columnClass);
7182                 }
7183                 Component component = renderer.getTableCellRendererComponent(
7184                                   JTable.this, null, false, false,
7185                                   row, column);
7186                 return new AccessibleJTableCell(JTable.this, row, column,
7187                       getAccessibleIndexAt(row, column));
7188             }
7189         }
7190 
7191     // AccessibleSelection support
7192 
7193         /**
7194          * Returns the number of <code>Accessible</code> children
7195          * currently selected.
7196          * If no children are selected, the return value will be 0.
7197          *
7198          * @return the number of items currently selected
7199          */
7200         public int getAccessibleSelectionCount() {
7201             int rowsSel = JTable.this.getSelectedRowCount();
7202             int colsSel = JTable.this.getSelectedColumnCount();
7203 
7204             if (JTable.this.cellSelectionEnabled) { // a contiguous block
7205                 return rowsSel * colsSel;
7206 
7207             } else {
7208                 // a column swath and a row swath, with a shared block
7209                 if (JTable.this.getRowSelectionAllowed() &&
7210                     JTable.this.getColumnSelectionAllowed()) {
7211                     return rowsSel * JTable.this.getColumnCount() +
7212                            colsSel * JTable.this.getRowCount() -
7213                            rowsSel * colsSel;
7214 
7215                 // just one or more rows in selection
7216                 } else if (JTable.this.getRowSelectionAllowed()) {
7217                     return rowsSel * JTable.this.getColumnCount();
7218 
7219                 // just one or more rows in selection
7220                 } else if (JTable.this.getColumnSelectionAllowed()) {
7221                     return colsSel * JTable.this.getRowCount();
7222 
7223                 } else {
7224                     return 0;    // JTable doesn't allow selections
7225                 }
7226             }
7227         }
7228 
7229         /**
7230          * Returns an <code>Accessible</code> representing the
7231          * specified selected child in the object.  If there
7232          * isn't a selection, or there are fewer children selected
7233          * than the integer passed in, the return
7234          * value will be <code>null</code>.
7235          * <p>Note that the index represents the i-th selected child, which
7236          * is different from the i-th child.
7237          *
7238          * @param i the zero-based index of selected children
7239          * @return the i-th selected child
7240          * @see #getAccessibleSelectionCount
7241          */
7242         public Accessible getAccessibleSelection(int i) {
7243             if (i < 0 || i > getAccessibleSelectionCount()) {
7244                 return null;
7245             }
7246 
7247             int rowsSel = JTable.this.getSelectedRowCount();
7248             int colsSel = JTable.this.getSelectedColumnCount();
7249             int rowIndicies[] = getSelectedRows();
7250             int colIndicies[] = getSelectedColumns();
7251             int ttlCols = JTable.this.getColumnCount();
7252             int ttlRows = JTable.this.getRowCount();
7253             int r;
7254             int c;


7344                 // one or more rows selected
7345                 } else if (JTable.this.getRowSelectionAllowed()) {
7346                     c = i % ttlCols;
7347                     r = rowIndicies[i / ttlCols];
7348                     return getAccessibleChild((r * ttlCols) + c);
7349 
7350                 // one or more columns selected
7351                 } else if (JTable.this.getColumnSelectionAllowed()) {
7352                     c = colIndicies[i % colsSel];
7353                     r = i / colsSel;
7354                     return getAccessibleChild((r * ttlCols) + c);
7355                 }
7356             }
7357             return null;
7358         }
7359 
7360         /**
7361          * Determines if the current child of this object is selected.
7362          *
7363          * @param i the zero-based index of the child in this
7364          *    <code>Accessible</code> object
7365          * @return true if the current child of this object is selected
7366          * @see AccessibleContext#getAccessibleChild
7367          */
7368         public boolean isAccessibleChildSelected(int i) {
7369             int column = getAccessibleColumnAtIndex(i);
7370             int row = getAccessibleRowAtIndex(i);
7371             return JTable.this.isCellSelected(row, column);
7372         }
7373 
7374         /**
7375          * Adds the specified <code>Accessible</code> child of the
7376          * object to the object's selection.  If the object supports
7377          * multiple selections, the specified child is added to
7378          * any existing selection, otherwise
7379          * it replaces any existing selection in the object.  If the
7380          * specified child is already selected, this method has no effect.
7381          * <p>
7382          * This method only works on <code>JTable</code>s which have
7383          * individual cell selection enabled.
7384          *
7385          * @param i the zero-based index of the child
7386          * @see AccessibleContext#getAccessibleChild
7387          */
7388         public void addAccessibleSelection(int i) {
7389             // TIGER - 4495286
7390             int column = getAccessibleColumnAtIndex(i);
7391             int row = getAccessibleRowAtIndex(i);
7392             JTable.this.changeSelection(row, column, true, false);
7393         }
7394 
7395         /**
7396          * Removes the specified child of the object from the object's
7397          * selection.  If the specified item isn't currently selected, this
7398          * method has no effect.
7399          * <p>
7400          * This method only works on <code>JTables</code> which have
7401          * individual cell selection enabled.
7402          *
7403          * @param i the zero-based index of the child
7404          * @see AccessibleContext#getAccessibleChild
7405          */
7406         public void removeAccessibleSelection(int i) {
7407             if (JTable.this.cellSelectionEnabled) {
7408                 int column = getAccessibleColumnAtIndex(i);
7409                 int row = getAccessibleRowAtIndex(i);
7410                 JTable.this.removeRowSelectionInterval(row, row);
7411                 JTable.this.removeColumnSelectionInterval(column, column);
7412             }
7413         }
7414 
7415         /**
7416          * Clears the selection in the object, so that no children in the
7417          * object are selected.
7418          */
7419         public void clearAccessibleSelection() {
7420             JTable.this.clearSelection();
7421         }
7422 
7423         /**
7424          * Causes every child of the object to be selected, but only
7425          * if the <code>JTable</code> supports multiple selections,
7426          * and if individual cell selection is enabled.
7427          */
7428         public void selectAllAccessibleSelection() {
7429             if (JTable.this.cellSelectionEnabled) {
7430                 JTable.this.selectAll();
7431             }
7432         }
7433 
7434         // begin AccessibleExtendedTable implementation -------------
7435 
7436         /**
7437          * Returns the row number of an index in the table.
7438          *
7439          * @param index the zero-based index in the table
7440          * @return the zero-based row of the table if one exists;
7441          * otherwise -1.
7442          * @since 1.4
7443          */
7444         public int getAccessibleRow(int index) {
7445             return getAccessibleRowAtIndex(index);


7463          * @param r zero-based row of the table
7464          * @param c zero-based column of the table
7465          * @return the zero-based index in the table if one exists;
7466          * otherwise -1.
7467          * @since 1.4
7468          */
7469         public int getAccessibleIndex(int r, int c) {
7470             return getAccessibleIndexAt(r, c);
7471         }
7472 
7473         // end of AccessibleExtendedTable implementation ------------
7474 
7475         // start of AccessibleTable implementation ------------------
7476 
7477         private Accessible caption;
7478         private Accessible summary;
7479         private Accessible [] rowDescription;
7480         private Accessible [] columnDescription;
7481 
7482         /**
7483          * Gets the <code>AccessibleTable</code> associated with this
7484          * object.  In the implementation of the Java Accessibility
7485          * API for this class, return this object, which is responsible
7486          * for implementing the <code>AccessibleTables</code> interface
7487          * on behalf of itself.
7488          *
7489          * @return this object
7490          * @since 1.3
7491          */
7492         public AccessibleTable getAccessibleTable() {
7493             return this;
7494         }
7495 
7496         /**
7497          * Returns the caption for the table.
7498          *
7499          * @return the caption for the table
7500          * @since 1.3
7501          */
7502         public Accessible getAccessibleCaption() {
7503             return this.caption;
7504         }
7505 
7506         /**


7541 
7542         /*
7543          * Returns the total number of rows in this table.
7544          *
7545          * @return the total number of rows in this table
7546          */
7547         public int getAccessibleRowCount() {
7548             return JTable.this.getRowCount();
7549         }
7550 
7551         /*
7552          * Returns the total number of columns in the table.
7553          *
7554          * @return the total number of columns in the table
7555          */
7556         public int getAccessibleColumnCount() {
7557             return JTable.this.getColumnCount();
7558         }
7559 
7560         /*
7561          * Returns the <code>Accessible</code> at a specified row
7562          * and column in the table.
7563          *
7564          * @param r zero-based row of the table
7565          * @param c zero-based column of the table
7566          * @return the <code>Accessible</code> at the specified row and column
7567          * in the table
7568          */
7569         public Accessible getAccessibleAt(int r, int c) {
7570             return getAccessibleChild((r * getAccessibleColumnCount()) + c);
7571         }
7572 
7573         /**
7574          * Returns the number of rows occupied by the <code>Accessible</code>
7575          * at a specified row and column in the table.
7576          *
7577          * @return the number of rows occupied by the <code>Accessible</code>
7578          *     at a specified row and column in the table
7579          * @since 1.3
7580          */
7581         public int getAccessibleRowExtentAt(int r, int c) {
7582             return 1;
7583         }
7584 
7585         /**
7586          * Returns the number of columns occupied by the
7587          * <code>Accessible</code> at a given (row, column).
7588          *
7589          * @return the number of columns occupied by the <code>Accessible</code>
7590          *     at a specified row and column in the table
7591          * @since 1.3
7592          */
7593         public int getAccessibleColumnExtentAt(int r, int c) {
7594             return 1;
7595         }
7596 
7597         /**
7598          * Returns the row headers as an <code>AccessibleTable</code>.
7599          *
7600          * @return an <code>AccessibleTable</code> representing the row
7601          * headers
7602          * @since 1.3
7603          */
7604         public AccessibleTable getAccessibleRowHeader() {
7605             // row headers are not supported
7606             return null;
7607         }
7608 
7609         /**
7610          * Sets the row headers as an <code>AccessibleTable</code>.
7611          *
7612          * @param a an <code>AccessibleTable</code> representing the row
7613          *  headers
7614          * @since 1.3
7615          */
7616         public void setAccessibleRowHeader(AccessibleTable a) {
7617             // row headers are not supported
7618         }
7619 
7620         /**
7621          * Returns the column headers as an <code>AccessibleTable</code>.
7622          *
7623          *  @return an <code>AccessibleTable</code> representing the column
7624          *          headers, or <code>null</code> if the table header is
7625          *          <code>null</code>
7626          * @since 1.3
7627          */
7628         public AccessibleTable getAccessibleColumnHeader() {
7629             JTableHeader header = JTable.this.getTableHeader();
7630             return header == null ? null : new AccessibleTableHeader(header);
7631         }
7632 
7633         /*
7634          * Private class representing a table column header
7635          */
7636         private class AccessibleTableHeader implements AccessibleTable {
7637             private JTableHeader header;
7638             private TableColumnModel headerModel;
7639 
7640             AccessibleTableHeader(JTableHeader header) {
7641                 this.header = header;
7642                 this.headerModel = header.getColumnModel();
7643             }
7644 
7645             /**


7840              * Returns the selected rows in a table.
7841              *
7842              * @return an array of selected rows where each element is a
7843              * zero-based row of the table
7844              * @since 1.3
7845              */
7846             public int [] getSelectedAccessibleRows() { return new int[0]; }
7847 
7848             /**
7849              * Returns the selected columns in a table.
7850              *
7851              * @return an array of selected columns where each element is a
7852              * zero-based column of the table
7853              * @since 1.3
7854              */
7855             public int [] getSelectedAccessibleColumns() { return new int[0]; }
7856         }
7857 
7858 
7859         /**
7860          * Sets the column headers as an <code>AccessibleTable</code>.
7861          *
7862          * @param a an <code>AccessibleTable</code> representing the
7863          * column headers
7864          * @since 1.3
7865          */
7866         public void setAccessibleColumnHeader(AccessibleTable a) {
7867             // XXX not implemented
7868         }
7869 
7870         /**
7871          * Returns the description of the specified row in the table.
7872          *
7873          * @param r zero-based row of the table
7874          * @return the description of the row
7875          * @since 1.3
7876          */
7877         public Accessible getAccessibleRowDescription(int r) {
7878             if (r < 0 || r >= getAccessibleRowCount()) {
7879                 throw new IllegalArgumentException(Integer.toString(r));
7880             }
7881             if (rowDescription == null) {
7882                 return null;


8043          */
8044         public int getAccessibleIndexAt(int r, int c) {
8045             return ((r * getAccessibleColumnCount()) + c);
8046         }
8047 
8048         // end of AccessibleTable implementation --------------------
8049 
8050         /**
8051          * The class provides an implementation of the Java Accessibility
8052          * API appropriate to table cells.
8053          */
8054         protected class AccessibleJTableCell extends AccessibleContext
8055             implements Accessible, AccessibleComponent {
8056 
8057             private JTable parent;
8058             private int row;
8059             private int column;
8060             private int index;
8061 
8062             /**
8063              *  Constructs an <code>AccessibleJTableHeaderEntry</code>.
8064              *
8065              * @param t a {@code JTable}
8066              * @param r an {@code int} specifying a row
8067              * @param c an {@code int} specifying a column
8068              * @param i an {@code int} specifying the index to this cell
8069              * @since 1.4
8070              */
8071             public AccessibleJTableCell(JTable t, int r, int c, int i) {
8072                 parent = t;
8073                 row = r;
8074                 column = c;
8075                 index = i;
8076                 this.setAccessibleParent(parent);
8077             }
8078 
8079             /**
8080              * Gets the <code>AccessibleContext</code> associated with this
8081              * component. In the implementation of the Java Accessibility
8082              * API for this class, return this object, which is its own
8083              * <code>AccessibleContext</code>.
8084              *
8085              * @return this object
8086              */
8087             public AccessibleContext getAccessibleContext() {
8088                 return this;
8089             }
8090 
8091             /**
8092              * Gets the AccessibleContext for the table cell renderer.
8093              *
8094              * @return the <code>AccessibleContext</code> for the table
8095              * cell renderer if one exists;
8096              * otherwise, returns <code>null</code>.
8097              * @since 1.6
8098              */
8099             protected AccessibleContext getCurrentAccessibleContext() {
8100                 TableColumn aColumn = getColumnModel().getColumn(column);
8101                 TableCellRenderer renderer = aColumn.getCellRenderer();
8102                 if (renderer == null) {
8103                     Class<?> columnClass = getColumnClass(column);
8104                     renderer = getDefaultRenderer(columnClass);
8105                 }
8106                 Component component = renderer.getTableCellRendererComponent(
8107                                   JTable.this, getValueAt(row, column),
8108                                   false, false, row, column);
8109                 if (component instanceof Accessible) {
8110                     return component.getAccessibleContext();
8111                 } else {
8112                     return null;
8113                 }
8114             }
8115 
8116             /**
8117              * Gets the table cell renderer component.
8118              *
8119              * @return the table cell renderer component if one exists;
8120              * otherwise, returns <code>null</code>.
8121              * @since 1.6
8122              */
8123             protected Component getCurrentComponent() {
8124                 TableColumn aColumn = getColumnModel().getColumn(column);
8125                 TableCellRenderer renderer = aColumn.getCellRenderer();
8126                 if (renderer == null) {
8127                     Class<?> columnClass = getColumnClass(column);
8128                     renderer = getDefaultRenderer(columnClass);
8129                 }
8130                 return renderer.getTableCellRendererComponent(
8131                                   JTable.this, null, false, false,
8132                                   row, column);
8133             }
8134 
8135         // AccessibleContext methods
8136 
8137             /**
8138              * Gets the accessible name of this object.
8139              *
8140              * @return the localized name of the object; <code>null</code>
8141              *     if this object does not have a name
8142              */
8143             public String getAccessibleName() {
8144                 AccessibleContext ac = getCurrentAccessibleContext();
8145                 if (ac != null) {
8146                     String name = ac.getAccessibleName();
8147                     if ((name != null) && (name != "")) {
8148                         // return the cell renderer's AccessibleName
8149                         return name;
8150                     }
8151                 }
8152                 if ((accessibleName != null) && (accessibleName != "")) {
8153                     return accessibleName;
8154                 } else {
8155                     // fall back to the client property
8156                     return (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
8157                 }
8158             }
8159 
8160             /**
8161              * Sets the localized accessible name of this object.
8162              *
8163              * @param s the new localized name of the object
8164              */
8165             public void setAccessibleName(String s) {
8166                 AccessibleContext ac = getCurrentAccessibleContext();
8167                 if (ac != null) {
8168                     ac.setAccessibleName(s);
8169                 } else {
8170                     super.setAccessibleName(s);
8171                 }
8172             }
8173 
8174             //
8175             // *** should check toolTip text for desc. (needs MouseEvent)
8176             //
8177             /**
8178              * Gets the accessible description of this object.
8179              *
8180              * @return the localized description of the object;
8181              *     <code>null</code> if this object does not have
8182              *     a description
8183              */
8184             public String getAccessibleDescription() {
8185                 AccessibleContext ac = getCurrentAccessibleContext();
8186                 if (ac != null) {
8187                     return ac.getAccessibleDescription();
8188                 } else {
8189                     return super.getAccessibleDescription();
8190                 }
8191             }
8192 
8193             /**
8194              * Sets the accessible description of this object.
8195              *
8196              * @param s the new localized description of the object
8197              */
8198             public void setAccessibleDescription(String s) {
8199                 AccessibleContext ac = getCurrentAccessibleContext();
8200                 if (ac != null) {
8201                     ac.setAccessibleDescription(s);
8202                 } else {
8203                     super.setAccessibleDescription(s);
8204                 }
8205             }
8206 
8207             /**
8208              * Gets the role of this object.
8209              *
8210              * @return an instance of <code>AccessibleRole</code>
8211              *      describing the role of the object
8212              * @see AccessibleRole
8213              */
8214             public AccessibleRole getAccessibleRole() {
8215                 AccessibleContext ac = getCurrentAccessibleContext();
8216                 if (ac != null) {
8217                     return ac.getAccessibleRole();
8218                 } else {
8219                     return AccessibleRole.UNKNOWN;
8220                 }
8221             }
8222 
8223             /**
8224              * Gets the state set of this object.
8225              *
8226              * @return an instance of <code>AccessibleStateSet</code>
8227              *     containing the current state set of the object
8228              * @see AccessibleState
8229              */
8230             public AccessibleStateSet getAccessibleStateSet() {
8231                 AccessibleContext ac = getCurrentAccessibleContext();
8232                 AccessibleStateSet as = null;
8233 
8234                 if (ac != null) {
8235                     as = ac.getAccessibleStateSet();
8236                 }
8237                 if (as == null) {
8238                     as = new AccessibleStateSet();
8239                 }
8240                 Rectangle rjt = JTable.this.getVisibleRect();
8241                 Rectangle rcell = JTable.this.getCellRect(row, column, false);
8242                 if (rjt.intersects(rcell)) {
8243                     as.add(AccessibleState.SHOWING);
8244                 } else {
8245                     if (as.contains(AccessibleState.SHOWING)) {
8246                          as.remove(AccessibleState.SHOWING);
8247                     }
8248                 }
8249                 if (parent.isCellSelected(row, column)) {
8250                     as.add(AccessibleState.SELECTED);
8251                 } else if (as.contains(AccessibleState.SELECTED)) {
8252                     as.remove(AccessibleState.SELECTED);
8253                 }
8254                 if ((row == getSelectedRow()) && (column == getSelectedColumn())) {
8255                     as.add(AccessibleState.ACTIVE);
8256                 }
8257                 as.add(AccessibleState.TRANSIENT);
8258                 return as;
8259             }
8260 
8261             /**
8262              * Gets the <code>Accessible</code> parent of this object.
8263              *
8264              * @return the Accessible parent of this object;
8265              *     <code>null</code> if this object does not
8266              *     have an <code>Accessible</code> parent
8267              */
8268             public Accessible getAccessibleParent() {
8269                 return parent;
8270             }
8271 
8272             /**
8273              * Gets the index of this object in its accessible parent.
8274              *
8275              * @return the index of this object in its parent; -1 if this
8276              *     object does not have an accessible parent
8277              * @see #getAccessibleParent
8278              */
8279             public int getAccessibleIndexInParent() {
8280                 return index;
8281             }
8282 
8283             /**
8284              * Returns the number of accessible children in the object.
8285              *
8286              * @return the number of accessible children in the object
8287              */
8288             public int getAccessibleChildrenCount() {
8289                 AccessibleContext ac = getCurrentAccessibleContext();
8290                 if (ac != null) {
8291                     return ac.getAccessibleChildrenCount();
8292                 } else {
8293                     return 0;
8294                 }
8295             }
8296 
8297             /**
8298              * Returns the specified <code>Accessible</code> child of the
8299              * object.
8300              *
8301              * @param i zero-based index of child
8302              * @return the <code>Accessible</code> child of the object
8303              */
8304             public Accessible getAccessibleChild(int i) {
8305                 AccessibleContext ac = getCurrentAccessibleContext();
8306                 if (ac != null) {
8307                     Accessible accessibleChild = ac.getAccessibleChild(i);
8308                     ac.setAccessibleParent(this);
8309                     return accessibleChild;
8310                 } else {
8311                     return null;
8312                 }
8313             }
8314 
8315             /**
8316              * Gets the locale of the component. If the component
8317              * does not have a locale, then the locale of its parent
8318              * is returned.
8319              *
8320              * @return this component's locale; if this component does
8321              *    not have a locale, the locale of its parent is returned
8322              * @exception IllegalComponentStateException if the
8323              *    <code>Component</code> does not have its own locale
8324              *    and has not yet been added to a containment hierarchy
8325              *    such that the locale can be determined from the
8326              *    containing parent
8327              * @see #setLocale
8328              */
8329             public Locale getLocale() {
8330                 AccessibleContext ac = getCurrentAccessibleContext();
8331                 if (ac != null) {
8332                     return ac.getLocale();
8333                 } else {
8334                     return null;
8335                 }
8336             }
8337 
8338             /**
8339              * Adds a <code>PropertyChangeListener</code> to the listener list.
8340              * The listener is registered for all properties.
8341              *
8342              * @param l  the <code>PropertyChangeListener</code>
8343              *     to be added
8344              */
8345             public void addPropertyChangeListener(PropertyChangeListener l) {
8346                 AccessibleContext ac = getCurrentAccessibleContext();
8347                 if (ac != null) {
8348                     ac.addPropertyChangeListener(l);
8349                 } else {
8350                     super.addPropertyChangeListener(l);
8351                 }
8352             }
8353 
8354             /**
8355              * Removes a <code>PropertyChangeListener</code> from the
8356              * listener list. This removes a <code>PropertyChangeListener</code>
8357              * that was registered for all properties.
8358              *
8359              * @param l  the <code>PropertyChangeListener</code>
8360              *    to be removed
8361              */
8362             public void removePropertyChangeListener(PropertyChangeListener l) {
8363                 AccessibleContext ac = getCurrentAccessibleContext();
8364                 if (ac != null) {
8365                     ac.removePropertyChangeListener(l);
8366                 } else {
8367                     super.removePropertyChangeListener(l);
8368                 }
8369             }
8370 
8371             /**
8372              * Gets the <code>AccessibleAction</code> associated with this
8373              * object if one exists.  Otherwise returns <code>null</code>.
8374              *
8375              * @return the <code>AccessibleAction</code>, or <code>null</code>
8376              */
8377             public AccessibleAction getAccessibleAction() {
8378                 return getCurrentAccessibleContext().getAccessibleAction();
8379             }
8380 
8381             /**
8382              * Gets the <code>AccessibleComponent</code> associated with
8383              * this object if one exists.  Otherwise returns <code>null</code>.
8384              *
8385              * @return the <code>AccessibleComponent</code>, or
8386              *    <code>null</code>
8387              */
8388             public AccessibleComponent getAccessibleComponent() {
8389                 return this; // to override getBounds()
8390             }
8391 
8392             /**
8393              * Gets the <code>AccessibleSelection</code> associated with
8394              * this object if one exists.  Otherwise returns <code>null</code>.
8395              *
8396              * @return the <code>AccessibleSelection</code>, or
8397              *    <code>null</code>
8398              */
8399             public AccessibleSelection getAccessibleSelection() {
8400                 return getCurrentAccessibleContext().getAccessibleSelection();
8401             }
8402 
8403             /**
8404              * Gets the <code>AccessibleText</code> associated with this
8405              * object if one exists.  Otherwise returns <code>null</code>.
8406              *
8407              * @return the <code>AccessibleText</code>, or <code>null</code>
8408              */
8409             public AccessibleText getAccessibleText() {
8410                 return getCurrentAccessibleContext().getAccessibleText();
8411             }
8412 
8413             /**
8414              * Gets the <code>AccessibleValue</code> associated with
8415              * this object if one exists.  Otherwise returns <code>null</code>.
8416              *
8417              * @return the <code>AccessibleValue</code>, or <code>null</code>
8418              */
8419             public AccessibleValue getAccessibleValue() {
8420                 return getCurrentAccessibleContext().getAccessibleValue();
8421             }
8422 
8423 
8424         // AccessibleComponent methods
8425 
8426             /**
8427              * Gets the background color of this object.
8428              *
8429              * @return the background color, if supported, of the object;
8430              *     otherwise, <code>null</code>
8431              */
8432             public Color getBackground() {
8433                 AccessibleContext ac = getCurrentAccessibleContext();
8434                 if (ac instanceof AccessibleComponent) {
8435                     return ((AccessibleComponent) ac).getBackground();
8436                 } else {
8437                     Component c = getCurrentComponent();
8438                     if (c != null) {
8439                         return c.getBackground();
8440                     } else {
8441                         return null;
8442                     }
8443                 }
8444             }
8445 
8446             /**
8447              * Sets the background color of this object.
8448              *
8449              * @param c the new <code>Color</code> for the background
8450              */
8451             public void setBackground(Color c) {
8452                 AccessibleContext ac = getCurrentAccessibleContext();
8453                 if (ac instanceof AccessibleComponent) {
8454                     ((AccessibleComponent) ac).setBackground(c);
8455                 } else {
8456                     Component cp = getCurrentComponent();
8457                     if (cp != null) {
8458                         cp.setBackground(c);
8459                     }
8460                 }
8461             }
8462 
8463             /**
8464              * Gets the foreground color of this object.
8465              *
8466              * @return the foreground color, if supported, of the object;
8467              *     otherwise, <code>null</code>
8468              */
8469             public Color getForeground() {
8470                 AccessibleContext ac = getCurrentAccessibleContext();
8471                 if (ac instanceof AccessibleComponent) {
8472                     return ((AccessibleComponent) ac).getForeground();
8473                 } else {
8474                     Component c = getCurrentComponent();
8475                     if (c != null) {
8476                         return c.getForeground();
8477                     } else {
8478                         return null;
8479                     }
8480                 }
8481             }
8482 
8483             /**
8484              * Sets the foreground color of this object.
8485              *
8486              * @param c the new <code>Color</code> for the foreground
8487              */
8488             public void setForeground(Color c) {
8489                 AccessibleContext ac = getCurrentAccessibleContext();
8490                 if (ac instanceof AccessibleComponent) {
8491                     ((AccessibleComponent) ac).setForeground(c);
8492                 } else {
8493                     Component cp = getCurrentComponent();
8494                     if (cp != null) {
8495                         cp.setForeground(c);
8496                     }
8497                 }
8498             }
8499 
8500             /**
8501              * Gets the <code>Cursor</code> of this object.
8502              *
8503              * @return the <code>Cursor</code>, if supported,
8504              *    of the object; otherwise, <code>null</code>
8505              */
8506             public Cursor getCursor() {
8507                 AccessibleContext ac = getCurrentAccessibleContext();
8508                 if (ac instanceof AccessibleComponent) {
8509                     return ((AccessibleComponent) ac).getCursor();
8510                 } else {
8511                     Component c = getCurrentComponent();
8512                     if (c != null) {
8513                         return c.getCursor();
8514                     } else {
8515                         Accessible ap = getAccessibleParent();
8516                         if (ap instanceof AccessibleComponent) {
8517                             return ((AccessibleComponent) ap).getCursor();
8518                         } else {
8519                             return null;
8520                         }
8521                     }
8522                 }
8523             }
8524 
8525             /**
8526              * Sets the <code>Cursor</code> of this object.
8527              *
8528              * @param c the new <code>Cursor</code> for the object
8529              */
8530             public void setCursor(Cursor c) {
8531                 AccessibleContext ac = getCurrentAccessibleContext();
8532                 if (ac instanceof AccessibleComponent) {
8533                     ((AccessibleComponent) ac).setCursor(c);
8534                 } else {
8535                     Component cp = getCurrentComponent();
8536                     if (cp != null) {
8537                         cp.setCursor(c);
8538                     }
8539                 }
8540             }
8541 
8542             /**
8543              * Gets the <code>Font</code> of this object.
8544              *
8545              * @return the <code>Font</code>,if supported,
8546              *   for the object; otherwise, <code>null</code>
8547              */
8548             public Font getFont() {
8549                 AccessibleContext ac = getCurrentAccessibleContext();
8550                 if (ac instanceof AccessibleComponent) {
8551                     return ((AccessibleComponent) ac).getFont();
8552                 } else {
8553                     Component c = getCurrentComponent();
8554                     if (c != null) {
8555                         return c.getFont();
8556                     } else {
8557                         return null;
8558                     }
8559                 }
8560             }
8561 
8562             /**
8563              * Sets the <code>Font</code> of this object.
8564              *
8565              * @param f the new <code>Font</code> for the object
8566              */
8567             public void setFont(Font f) {
8568                 AccessibleContext ac = getCurrentAccessibleContext();
8569                 if (ac instanceof AccessibleComponent) {
8570                     ((AccessibleComponent) ac).setFont(f);
8571                 } else {
8572                     Component c = getCurrentComponent();
8573                     if (c != null) {
8574                         c.setFont(f);
8575                     }
8576                 }
8577             }
8578 
8579             /**
8580              * Gets the <code>FontMetrics</code> of this object.
8581              *
8582              * @param f the <code>Font</code>
8583              * @return the <code>FontMetrics</code> object, if supported;
8584              *    otherwise <code>null</code>
8585              * @see #getFont
8586              */
8587             public FontMetrics getFontMetrics(Font f) {
8588                 AccessibleContext ac = getCurrentAccessibleContext();
8589                 if (ac instanceof AccessibleComponent) {
8590                     return ((AccessibleComponent) ac).getFontMetrics(f);
8591                 } else {
8592                     Component c = getCurrentComponent();
8593                     if (c != null) {
8594                         return c.getFontMetrics(f);
8595                     } else {
8596                         return null;
8597                     }
8598                 }
8599             }
8600 
8601             /**
8602              * Determines if the object is enabled.
8603              *
8604              * @return true if object is enabled; otherwise, false


8622              *
8623              * @param b if true, enables this object; otherwise, disables it
8624              */
8625             public void setEnabled(boolean b) {
8626                 AccessibleContext ac = getCurrentAccessibleContext();
8627                 if (ac instanceof AccessibleComponent) {
8628                     ((AccessibleComponent) ac).setEnabled(b);
8629                 } else {
8630                     Component c = getCurrentComponent();
8631                     if (c != null) {
8632                         c.setEnabled(b);
8633                     }
8634                 }
8635             }
8636 
8637             /**
8638              * Determines if this object is visible.  Note: this means that the
8639              * object intends to be visible; however, it may not in fact be
8640              * showing on the screen because one of the objects that this object
8641              * is contained by is not visible.  To determine if an object is
8642              * showing on the screen, use <code>isShowing</code>.
8643              *
8644              * @return true if object is visible; otherwise, false
8645              */
8646             public boolean isVisible() {
8647                 AccessibleContext ac = getCurrentAccessibleContext();
8648                 if (ac instanceof AccessibleComponent) {
8649                     return ((AccessibleComponent) ac).isVisible();
8650                 } else {
8651                     Component c = getCurrentComponent();
8652                     if (c != null) {
8653                         return c.isVisible();
8654                     } else {
8655                         return false;
8656                     }
8657                 }
8658             }
8659 
8660             /**
8661              * Sets the visible state of the object.
8662              *


8693                         // returns false when the cell on the screen
8694                         // if no parent
8695                         return isVisible();
8696                     }
8697                 } else {
8698                     Component c = getCurrentComponent();
8699                     if (c != null) {
8700                         return c.isShowing();
8701                     } else {
8702                         return false;
8703                     }
8704                 }
8705             }
8706 
8707             /**
8708              * Checks whether the specified point is within this
8709              * object's bounds, where the point's x and y coordinates
8710              * are defined to be relative to the coordinate system of
8711              * the object.
8712              *
8713              * @param p the <code>Point</code> relative to the
8714              *    coordinate system of the object
8715              * @return true if object contains <code>Point</code>;
8716              *    otherwise false
8717              */
8718             public boolean contains(Point p) {
8719                 AccessibleContext ac = getCurrentAccessibleContext();
8720                 if (ac instanceof AccessibleComponent) {
8721                     Rectangle r = ((AccessibleComponent) ac).getBounds();
8722                     return r.contains(p);
8723                 } else {
8724                     Component c = getCurrentComponent();
8725                     if (c != null) {
8726                         Rectangle r = c.getBounds();
8727                         return r.contains(p);
8728                     } else {
8729                         return getBounds().contains(p);
8730                     }
8731                 }
8732             }
8733 
8734             /**
8735              * Returns the location of the object on the screen.
8736              *
8737              * @return location of object on screen -- can be
8738              *    <code>null</code> if this object is not on the screen
8739              */
8740             public Point getLocationOnScreen() {
8741                 if (parent != null && parent.isShowing()) {
8742                     Point parentLocation = parent.getLocationOnScreen();
8743                     Point componentLocation = getLocation();
8744                     componentLocation.translate(parentLocation.x, parentLocation.y);
8745                     return componentLocation;
8746                 } else {
8747                     return null;
8748                 }
8749             }
8750 
8751             /**
8752              * Gets the location of the object relative to the parent
8753              * in the form of a point specifying the object's
8754              * top-left corner in the screen's coordinate space.
8755              *
8756              * @return an instance of <code>Point</code> representing
8757              *    the top-left corner of the object's bounds in the
8758              *    coordinate space of the screen; <code>null</code> if
8759              *    this object or its parent are not on the screen
8760              */
8761             public Point getLocation() {
8762                 if (parent != null) {
8763                     Rectangle r = parent.getCellRect(row, column, false);
8764                     if (r != null) {
8765                         return r.getLocation();
8766                     }
8767                 }
8768                 return null;
8769             }
8770 
8771             /**
8772              * Sets the location of the object relative to the parent.
8773              */
8774             public void setLocation(Point p) {
8775 //              if ((parent != null)  && (parent.contains(p))) {
8776 //                  ensureIndexIsVisible(indexInParent);
8777 //              }
8778             }


8878                     }
8879                 }
8880             }
8881 
8882         } // inner class AccessibleJTableCell
8883 
8884         // Begin AccessibleJTableHeader ========== // TIGER - 4715503
8885 
8886         /**
8887          * This class implements accessibility for JTable header cells.
8888          */
8889         private class AccessibleJTableHeaderCell extends AccessibleContext
8890             implements Accessible, AccessibleComponent {
8891 
8892             private int row;
8893             private int column;
8894             private JTableHeader parent;
8895             private Component rendererComponent;
8896 
8897             /**
8898              * Constructs an <code>AccessibleJTableHeaderEntry</code> instance.
8899              *
8900              * @param row header cell row index
8901              * @param column header cell column index
8902              * @param parent header cell parent
8903              * @param rendererComponent component that renders the header cell
8904              */
8905             public AccessibleJTableHeaderCell(int row, int column,
8906                                               JTableHeader parent,
8907                                               Component rendererComponent) {
8908                 this.row = row;
8909                 this.column = column;
8910                 this.parent = parent;
8911                 this.rendererComponent = rendererComponent;
8912                 this.setAccessibleParent(parent);
8913             }
8914 
8915             /**
8916              * Gets the <code>AccessibleContext</code> associated with this
8917              * component. In the implementation of the Java Accessibility
8918              * API for this class, return this object, which is its own
8919              * <code>AccessibleContext</code>.
8920              *
8921              * @return this object
8922              */
8923             public AccessibleContext getAccessibleContext() {
8924                 return this;
8925             }
8926 
8927             /*
8928              * Returns the AccessibleContext for the header cell
8929              * renderer.
8930              */
8931             private AccessibleContext getCurrentAccessibleContext() {
8932                 return rendererComponent.getAccessibleContext();
8933             }
8934 
8935             /*
8936              * Returns the component that renders the header cell.
8937              */
8938             private Component getCurrentComponent() {
8939                 return rendererComponent;
8940             }
8941 
8942             // AccessibleContext methods ==========
8943 
8944             /**
8945              * Gets the accessible name of this object.
8946              *
8947              * @return the localized name of the object; <code>null</code>
8948              *     if this object does not have a name
8949              */
8950             public String getAccessibleName() {
8951                 AccessibleContext ac = getCurrentAccessibleContext();
8952                 if (ac != null) {
8953                     String name = ac.getAccessibleName();
8954                     if ((name != null) && (name != "")) {
8955                         return ac.getAccessibleName();
8956                     }
8957                 }
8958                 if ((accessibleName != null) && (accessibleName != "")) {
8959                     return accessibleName;
8960                 } else {
8961                     return null;
8962                 }
8963             }
8964 
8965             /**
8966              * Sets the localized accessible name of this object.
8967              *
8968              * @param s the new localized name of the object
8969              */
8970             public void setAccessibleName(String s) {
8971                 AccessibleContext ac = getCurrentAccessibleContext();
8972                 if (ac != null) {
8973                     ac.setAccessibleName(s);
8974                 } else {
8975                     super.setAccessibleName(s);
8976                 }
8977             }
8978 
8979             /**
8980              * Gets the accessible description of this object.
8981              *
8982              * @return the localized description of the object;
8983              *     <code>null</code> if this object does not have
8984              *     a description
8985              */
8986             public String getAccessibleDescription() {
8987                 AccessibleContext ac = getCurrentAccessibleContext();
8988                 if (ac != null) {
8989                     return ac.getAccessibleDescription();
8990                 } else {
8991                     return super.getAccessibleDescription();
8992                 }
8993             }
8994 
8995             /**
8996              * Sets the accessible description of this object.
8997              *
8998              * @param s the new localized description of the object
8999              */
9000             public void setAccessibleDescription(String s) {
9001                 AccessibleContext ac = getCurrentAccessibleContext();
9002                 if (ac != null) {
9003                     ac.setAccessibleDescription(s);
9004                 } else {
9005                     super.setAccessibleDescription(s);
9006                 }
9007             }
9008 
9009             /**
9010              * Gets the role of this object.
9011              *
9012              * @return an instance of <code>AccessibleRole</code>
9013              *      describing the role of the object
9014              * @see AccessibleRole
9015              */
9016             public AccessibleRole getAccessibleRole() {
9017                 AccessibleContext ac = getCurrentAccessibleContext();
9018                 if (ac != null) {
9019                     return ac.getAccessibleRole();
9020                 } else {
9021                     return AccessibleRole.UNKNOWN;
9022                 }
9023             }
9024 
9025             /**
9026              * Gets the state set of this object.
9027              *
9028              * @return an instance of <code>AccessibleStateSet</code>
9029              *     containing the current state set of the object
9030              * @see AccessibleState
9031              */
9032             public AccessibleStateSet getAccessibleStateSet() {
9033                 AccessibleContext ac = getCurrentAccessibleContext();
9034                 AccessibleStateSet as = null;
9035 
9036                 if (ac != null) {
9037                     as = ac.getAccessibleStateSet();
9038                 }
9039                 if (as == null) {
9040                     as = new AccessibleStateSet();
9041                 }
9042                 Rectangle rjt = JTable.this.getVisibleRect();
9043                 Rectangle rcell = JTable.this.getCellRect(row, column, false);
9044                 if (rjt.intersects(rcell)) {
9045                     as.add(AccessibleState.SHOWING);
9046                 } else {
9047                     if (as.contains(AccessibleState.SHOWING)) {
9048                          as.remove(AccessibleState.SHOWING);
9049                     }
9050                 }
9051                 if (JTable.this.isCellSelected(row, column)) {
9052                     as.add(AccessibleState.SELECTED);
9053                 } else if (as.contains(AccessibleState.SELECTED)) {
9054                     as.remove(AccessibleState.SELECTED);
9055                 }
9056                 if ((row == getSelectedRow()) && (column == getSelectedColumn())) {
9057                     as.add(AccessibleState.ACTIVE);
9058                 }
9059                 as.add(AccessibleState.TRANSIENT);
9060                 return as;
9061             }
9062 
9063             /**
9064              * Gets the <code>Accessible</code> parent of this object.
9065              *
9066              * @return the Accessible parent of this object;
9067              *     <code>null</code> if this object does not
9068              *     have an <code>Accessible</code> parent
9069              */
9070             public Accessible getAccessibleParent() {
9071                 return parent;
9072             }
9073 
9074             /**
9075              * Gets the index of this object in its accessible parent.
9076              *
9077              * @return the index of this object in its parent; -1 if this
9078              *     object does not have an accessible parent
9079              * @see #getAccessibleParent
9080              */
9081             public int getAccessibleIndexInParent() {
9082                 return column;
9083             }
9084 
9085             /**
9086              * Returns the number of accessible children in the object.
9087              *
9088              * @return the number of accessible children in the object
9089              */
9090             public int getAccessibleChildrenCount() {
9091                 AccessibleContext ac = getCurrentAccessibleContext();
9092                 if (ac != null) {
9093                     return ac.getAccessibleChildrenCount();
9094                 } else {
9095                     return 0;
9096                 }
9097             }
9098 
9099             /**
9100              * Returns the specified <code>Accessible</code> child of the
9101              * object.
9102              *
9103              * @param i zero-based index of child
9104              * @return the <code>Accessible</code> child of the object
9105              */
9106             public Accessible getAccessibleChild(int i) {
9107                 AccessibleContext ac = getCurrentAccessibleContext();
9108                 if (ac != null) {
9109                     Accessible accessibleChild = ac.getAccessibleChild(i);
9110                     ac.setAccessibleParent(this);
9111                     return accessibleChild;
9112                 } else {
9113                     return null;
9114                 }
9115             }
9116 
9117             /**
9118              * Gets the locale of the component. If the component
9119              * does not have a locale, then the locale of its parent
9120              * is returned.
9121              *
9122              * @return this component's locale; if this component does
9123              *    not have a locale, the locale of its parent is returned
9124              * @exception IllegalComponentStateException if the
9125              *    <code>Component</code> does not have its own locale
9126              *    and has not yet been added to a containment hierarchy
9127              *    such that the locale can be determined from the
9128              *    containing parent
9129              * @see #setLocale
9130              */
9131             public Locale getLocale() {
9132                 AccessibleContext ac = getCurrentAccessibleContext();
9133                 if (ac != null) {
9134                     return ac.getLocale();
9135                 } else {
9136                     return null;
9137                 }
9138             }
9139 
9140             /**
9141              * Adds a <code>PropertyChangeListener</code> to the listener list.
9142              * The listener is registered for all properties.
9143              *
9144              * @param l  the <code>PropertyChangeListener</code>
9145              *     to be added
9146              */
9147             public void addPropertyChangeListener(PropertyChangeListener l) {
9148                 AccessibleContext ac = getCurrentAccessibleContext();
9149                 if (ac != null) {
9150                     ac.addPropertyChangeListener(l);
9151                 } else {
9152                     super.addPropertyChangeListener(l);
9153                 }
9154             }
9155 
9156             /**
9157              * Removes a <code>PropertyChangeListener</code> from the
9158              * listener list. This removes a <code>PropertyChangeListener</code>
9159              * that was registered for all properties.
9160              *
9161              * @param l  the <code>PropertyChangeListener</code>
9162              *    to be removed
9163              */
9164             public void removePropertyChangeListener(PropertyChangeListener l) {
9165                 AccessibleContext ac = getCurrentAccessibleContext();
9166                 if (ac != null) {
9167                     ac.removePropertyChangeListener(l);
9168                 } else {
9169                     super.removePropertyChangeListener(l);
9170                 }
9171             }
9172 
9173             /**
9174              * Gets the <code>AccessibleAction</code> associated with this
9175              * object if one exists.  Otherwise returns <code>null</code>.
9176              *
9177              * @return the <code>AccessibleAction</code>, or <code>null</code>
9178              */
9179             public AccessibleAction getAccessibleAction() {
9180                 return getCurrentAccessibleContext().getAccessibleAction();
9181             }
9182 
9183             /**
9184              * Gets the <code>AccessibleComponent</code> associated with
9185              * this object if one exists.  Otherwise returns <code>null</code>.
9186              *
9187              * @return the <code>AccessibleComponent</code>, or
9188              *    <code>null</code>
9189              */
9190             public AccessibleComponent getAccessibleComponent() {
9191                 return this; // to override getBounds()
9192             }
9193 
9194             /**
9195              * Gets the <code>AccessibleSelection</code> associated with
9196              * this object if one exists.  Otherwise returns <code>null</code>.
9197              *
9198              * @return the <code>AccessibleSelection</code>, or
9199              *    <code>null</code>
9200              */
9201             public AccessibleSelection getAccessibleSelection() {
9202                 return getCurrentAccessibleContext().getAccessibleSelection();
9203             }
9204 
9205             /**
9206              * Gets the <code>AccessibleText</code> associated with this
9207              * object if one exists.  Otherwise returns <code>null</code>.
9208              *
9209              * @return the <code>AccessibleText</code>, or <code>null</code>
9210              */
9211             public AccessibleText getAccessibleText() {
9212                 return getCurrentAccessibleContext().getAccessibleText();
9213             }
9214 
9215             /**
9216              * Gets the <code>AccessibleValue</code> associated with
9217              * this object if one exists.  Otherwise returns <code>null</code>.
9218              *
9219              * @return the <code>AccessibleValue</code>, or <code>null</code>
9220              */
9221             public AccessibleValue getAccessibleValue() {
9222                 return getCurrentAccessibleContext().getAccessibleValue();
9223             }
9224 
9225 
9226             // AccessibleComponent methods ==========
9227 
9228             /**
9229              * Gets the background color of this object.
9230              *
9231              * @return the background color, if supported, of the object;
9232              *     otherwise, <code>null</code>
9233              */
9234             public Color getBackground() {
9235                 AccessibleContext ac = getCurrentAccessibleContext();
9236                 if (ac instanceof AccessibleComponent) {
9237                     return ((AccessibleComponent) ac).getBackground();
9238                 } else {
9239                     Component c = getCurrentComponent();
9240                     if (c != null) {
9241                         return c.getBackground();
9242                     } else {
9243                         return null;
9244                     }
9245                 }
9246             }
9247 
9248             /**
9249              * Sets the background color of this object.
9250              *
9251              * @param c the new <code>Color</code> for the background
9252              */
9253             public void setBackground(Color c) {
9254                 AccessibleContext ac = getCurrentAccessibleContext();
9255                 if (ac instanceof AccessibleComponent) {
9256                     ((AccessibleComponent) ac).setBackground(c);
9257                 } else {
9258                     Component cp = getCurrentComponent();
9259                     if (cp != null) {
9260                         cp.setBackground(c);
9261                     }
9262                 }
9263             }
9264 
9265             /**
9266              * Gets the foreground color of this object.
9267              *
9268              * @return the foreground color, if supported, of the object;
9269              *     otherwise, <code>null</code>
9270              */
9271             public Color getForeground() {
9272                 AccessibleContext ac = getCurrentAccessibleContext();
9273                 if (ac instanceof AccessibleComponent) {
9274                     return ((AccessibleComponent) ac).getForeground();
9275                 } else {
9276                     Component c = getCurrentComponent();
9277                     if (c != null) {
9278                         return c.getForeground();
9279                     } else {
9280                         return null;
9281                     }
9282                 }
9283             }
9284 
9285             /**
9286              * Sets the foreground color of this object.
9287              *
9288              * @param c the new <code>Color</code> for the foreground
9289              */
9290             public void setForeground(Color c) {
9291                 AccessibleContext ac = getCurrentAccessibleContext();
9292                 if (ac instanceof AccessibleComponent) {
9293                     ((AccessibleComponent) ac).setForeground(c);
9294                 } else {
9295                     Component cp = getCurrentComponent();
9296                     if (cp != null) {
9297                         cp.setForeground(c);
9298                     }
9299                 }
9300             }
9301 
9302             /**
9303              * Gets the <code>Cursor</code> of this object.
9304              *
9305              * @return the <code>Cursor</code>, if supported,
9306              *    of the object; otherwise, <code>null</code>
9307              */
9308             public Cursor getCursor() {
9309                 AccessibleContext ac = getCurrentAccessibleContext();
9310                 if (ac instanceof AccessibleComponent) {
9311                     return ((AccessibleComponent) ac).getCursor();
9312                 } else {
9313                     Component c = getCurrentComponent();
9314                     if (c != null) {
9315                         return c.getCursor();
9316                     } else {
9317                         Accessible ap = getAccessibleParent();
9318                         if (ap instanceof AccessibleComponent) {
9319                             return ((AccessibleComponent) ap).getCursor();
9320                         } else {
9321                             return null;
9322                         }
9323                     }
9324                 }
9325             }
9326 
9327             /**
9328              * Sets the <code>Cursor</code> of this object.
9329              *
9330              * @param c the new <code>Cursor</code> for the object
9331              */
9332             public void setCursor(Cursor c) {
9333                 AccessibleContext ac = getCurrentAccessibleContext();
9334                 if (ac instanceof AccessibleComponent) {
9335                     ((AccessibleComponent) ac).setCursor(c);
9336                 } else {
9337                     Component cp = getCurrentComponent();
9338                     if (cp != null) {
9339                         cp.setCursor(c);
9340                     }
9341                 }
9342             }
9343 
9344             /**
9345              * Gets the <code>Font</code> of this object.
9346              *
9347              * @return the <code>Font</code>,if supported,
9348              *   for the object; otherwise, <code>null</code>
9349              */
9350             public Font getFont() {
9351                 AccessibleContext ac = getCurrentAccessibleContext();
9352                 if (ac instanceof AccessibleComponent) {
9353                     return ((AccessibleComponent) ac).getFont();
9354                 } else {
9355                     Component c = getCurrentComponent();
9356                     if (c != null) {
9357                         return c.getFont();
9358                     } else {
9359                         return null;
9360                     }
9361                 }
9362             }
9363 
9364             /**
9365              * Sets the <code>Font</code> of this object.
9366              *
9367              * @param f the new <code>Font</code> for the object
9368              */
9369             public void setFont(Font f) {
9370                 AccessibleContext ac = getCurrentAccessibleContext();
9371                 if (ac instanceof AccessibleComponent) {
9372                     ((AccessibleComponent) ac).setFont(f);
9373                 } else {
9374                     Component c = getCurrentComponent();
9375                     if (c != null) {
9376                         c.setFont(f);
9377                     }
9378                 }
9379             }
9380 
9381             /**
9382              * Gets the <code>FontMetrics</code> of this object.
9383              *
9384              * @param f the <code>Font</code>
9385              * @return the <code>FontMetrics</code> object, if supported;
9386              *    otherwise <code>null</code>
9387              * @see #getFont
9388              */
9389             public FontMetrics getFontMetrics(Font f) {
9390                 AccessibleContext ac = getCurrentAccessibleContext();
9391                 if (ac instanceof AccessibleComponent) {
9392                     return ((AccessibleComponent) ac).getFontMetrics(f);
9393                 } else {
9394                     Component c = getCurrentComponent();
9395                     if (c != null) {
9396                         return c.getFontMetrics(f);
9397                     } else {
9398                         return null;
9399                     }
9400                 }
9401             }
9402 
9403             /**
9404              * Determines if the object is enabled.
9405              *
9406              * @return true if object is enabled; otherwise, false


9424              *
9425              * @param b if true, enables this object; otherwise, disables it
9426              */
9427             public void setEnabled(boolean b) {
9428                 AccessibleContext ac = getCurrentAccessibleContext();
9429                 if (ac instanceof AccessibleComponent) {
9430                     ((AccessibleComponent) ac).setEnabled(b);
9431                 } else {
9432                     Component c = getCurrentComponent();
9433                     if (c != null) {
9434                         c.setEnabled(b);
9435                     }
9436                 }
9437             }
9438 
9439             /**
9440              * Determines if this object is visible.  Note: this means that the
9441              * object intends to be visible; however, it may not in fact be
9442              * showing on the screen because one of the objects that this object
9443              * is contained by is not visible.  To determine if an object is
9444              * showing on the screen, use <code>isShowing</code>.
9445              *
9446              * @return true if object is visible; otherwise, false
9447              */
9448             public boolean isVisible() {
9449                 AccessibleContext ac = getCurrentAccessibleContext();
9450                 if (ac instanceof AccessibleComponent) {
9451                     return ((AccessibleComponent) ac).isVisible();
9452                 } else {
9453                     Component c = getCurrentComponent();
9454                     if (c != null) {
9455                         return c.isVisible();
9456                     } else {
9457                         return false;
9458                     }
9459                 }
9460             }
9461 
9462             /**
9463              * Sets the visible state of the object.
9464              *


9495                         // returns false when the cell on the screen
9496                         // if no parent
9497                         return isVisible();
9498                     }
9499                 } else {
9500                     Component c = getCurrentComponent();
9501                     if (c != null) {
9502                         return c.isShowing();
9503                     } else {
9504                         return false;
9505                     }
9506                 }
9507             }
9508 
9509             /**
9510              * Checks whether the specified point is within this
9511              * object's bounds, where the point's x and y coordinates
9512              * are defined to be relative to the coordinate system of
9513              * the object.
9514              *
9515              * @param p the <code>Point</code> relative to the
9516              *    coordinate system of the object
9517              * @return true if object contains <code>Point</code>;
9518              *    otherwise false
9519              */
9520             public boolean contains(Point p) {
9521                 AccessibleContext ac = getCurrentAccessibleContext();
9522                 if (ac instanceof AccessibleComponent) {
9523                     Rectangle r = ((AccessibleComponent) ac).getBounds();
9524                     return r.contains(p);
9525                 } else {
9526                     Component c = getCurrentComponent();
9527                     if (c != null) {
9528                         Rectangle r = c.getBounds();
9529                         return r.contains(p);
9530                     } else {
9531                         return getBounds().contains(p);
9532                     }
9533                 }
9534             }
9535 
9536             /**
9537              * Returns the location of the object on the screen.
9538              *
9539              * @return location of object on screen -- can be
9540              *    <code>null</code> if this object is not on the screen
9541              */
9542             public Point getLocationOnScreen() {
9543                 if (parent != null && parent.isShowing()) {
9544                     Point parentLocation = parent.getLocationOnScreen();
9545                     Point componentLocation = getLocation();
9546                     componentLocation.translate(parentLocation.x, parentLocation.y);
9547                     return componentLocation;
9548                 } else {
9549                     return null;
9550                 }
9551             }
9552 
9553             /**
9554              * Gets the location of the object relative to the parent
9555              * in the form of a point specifying the object's
9556              * top-left corner in the screen's coordinate space.
9557              *
9558              * @return an instance of <code>Point</code> representing
9559              *    the top-left corner of the object's bounds in the
9560              *    coordinate space of the screen; <code>null</code> if
9561              *    this object or its parent are not on the screen
9562              */
9563             public Point getLocation() {
9564                 if (parent != null) {
9565                     Rectangle r = parent.getHeaderRect(column);
9566                     if (r != null) {
9567                         return r.getLocation();
9568                     }
9569                 }
9570                 return null;
9571             }
9572 
9573             /**
9574              * Sets the location of the object relative to the parent.
9575              * @param p the new position for the top-left corner
9576              * @see #getLocation
9577              */
9578             public void setLocation(Point p) {
9579             }
9580 




  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 import java.util.List;
  53 
  54 import javax.print.attribute.*;
  55 import javax.print.PrintService;
  56 
  57 import sun.misc.ManagedLocalsThread;
  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} 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}.
  71  *
  72  * <p>
  73  * The {@code JTable} 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:
  78  *
  79  * <pre>
  80  *      TableModel dataModel = new AbstractTableModel() {
  81  *          public int getColumnCount() { return 10; }
  82  *          public int getRowCount() { return 10;}
  83  *          public Object getValueAt(int row, int col) { return new Integer(row*col); }
  84  *      };
  85  *      JTable table = new JTable(dataModel);
  86  *      JScrollPane scrollpane = new JScrollPane(table);
  87  * </pre>
  88  * <p>
  89  * {@code JTable}s are typically placed inside of a {@code JScrollPane}.  By
  90  * default, a {@code JTable} will adjust its width such that
  91  * a horizontal scrollbar is unnecessary.  To allow for a horizontal scrollbar,
  92  * invoke {@link #setAutoResizeMode} with {@code AUTO_RESIZE_OFF}.
  93  * Note that if you wish to use a {@code JTable} in a standalone
  94  * view (outside of a {@code JScrollPane}) and want the header
  95  * displayed, you can get it using {@link #getTableHeader} and
  96  * display it separately.
  97  * <p>
  98  * To enable sorting and filtering of rows, use a
  99  * {@code RowSorter}.
 100  * You can set up a row sorter in either of two ways:
 101  * <ul>
 102  *   <li>Directly set the {@code RowSorter}. For example:
 103  *        {@code table.setRowSorter(new TableRowSorter(model))}.
 104  *   <li>Set the {@code autoCreateRowSorter}
 105  *       property to {@code true}, so that the {@code JTable}
 106  *       creates a {@code RowSorter} for
 107  *       you. For example: {@code setAutoCreateRowSorter(true)}.
 108  * </ul>
 109  * <p>
 110  * When designing applications that use the {@code JTable} it is worth paying
 111  * close attention to the data structures that will represent the table's data.
 112  * The {@code DefaultTableModel} is a model implementation that
 113  * uses a {@code Vector} of {@code Vector}s of {@code Object}s to
 114  * store the cell values. As well as copying the data from an
 115  * application into the {@code DefaultTableModel},
 116  * it is also possible to wrap the data in the methods of the
 117  * {@code TableModel} interface so that the data can be passed to the
 118  * {@code JTable} directly, as in the example above. This often results
 119  * in more efficient applications because the model is free to choose the
 120  * internal representation that best suits the data.
 121  * A good rule of thumb for deciding whether to use the {@code AbstractTableModel}
 122  * or the {@code DefaultTableModel} is to use the {@code AbstractTableModel}
 123  * as the base class for creating subclasses and the {@code DefaultTableModel}
 124  * when subclassing is not required.
 125  * <p>
 126  * The "TableExample" directory in the demo area of the source distribution
 127  * gives a number of complete examples of {@code JTable} usage,
 128  * covering how the {@code JTable} can be used to provide an
 129  * editable view of data taken from a database and how to modify
 130  * the columns in the display to use specialized renderers and editors.
 131  * <p>
 132  * The {@code JTable} uses integers exclusively to refer to both the rows and the columns
 133  * of the model that it displays. The {@code JTable} simply takes a tabular range of cells
 134  * and uses {@code getValueAt(int, int)} to retrieve the
 135  * values from the model during painting.  It is important to remember that
 136  * the column and row indexes returned by various {@code JTable} methods
 137  * are in terms of the {@code JTable} (the view) and are not
 138  * necessarily the same indexes used by the model.
 139  * <p>
 140  * By default, columns may be rearranged in the {@code JTable} so that the
 141  * view's columns appear in a different order to the columns in the model.
 142  * This does not affect the implementation of the model at all: when the
 143  * columns are reordered, the {@code JTable} maintains the new order of the columns
 144  * internally and converts its column indices before querying the model.
 145  * <p>
 146  * So, when writing a {@code TableModel}, it is not necessary to listen for column
 147  * reordering events as the model will be queried in its own coordinate
 148  * system regardless of what is happening in the view.
 149  * In the examples area there is a demonstration of a sorting algorithm making
 150  * use of exactly this technique to interpose yet another coordinate system
 151  * where the order of the rows is changed, rather than the order of the columns.
 152  * <p>
 153  * Similarly when using the sorting and filtering functionality
 154  * provided by {@code RowSorter} the underlying
 155  * {@code TableModel} does not need to know how to do sorting,
 156  * rather {@code RowSorter} will handle it.  Coordinate
 157  * conversions will be necessary when using the row based methods of
 158  * {@code JTable} with the underlying {@code TableModel}.
 159  * All of {@code JTable}s row based methods are in terms of the
 160  * {@code RowSorter}, which is not necessarily the same as that
 161  * of the underlying {@code TableModel}.  For example, the
 162  * selection is always in terms of {@code JTable} so that when
 163  * using {@code RowSorter} you will need to convert using
 164  * {@code convertRowIndexToView} or
 165  * {@code convertRowIndexToModel}.  The following shows how to
 166  * convert coordinates from {@code JTable} to that of the
 167  * underlying model:
 168  * <pre>
 169  *   int[] selection = table.getSelectedRows();
 170  *   for (int i = 0; i &lt; selection.length; i++) {
 171  *     selection[i] = table.convertRowIndexToModel(selection[i]);
 172  *   }
 173  *   // selection is now in terms of the underlying TableModel
 174  * </pre>
 175  * <p>
 176  * By default if sorting is enabled {@code JTable} will persist the
 177  * selection and variable row heights in terms of the model on
 178  * sorting.  For example if row 0, in terms of the underlying model,
 179  * is currently selected, after the sort row 0, in terms of the
 180  * underlying model will be selected.  Visually the selection may
 181  * change, but in terms of the underlying model it will remain the
 182  * same.  The one exception to that is if the model index is no longer
 183  * visible or was removed.  For example, if row 0 in terms of model
 184  * was filtered out the selection will be empty after the sort.
 185  * <p>
 186  * J2SE 5 adds methods to {@code JTable} to provide convenient access to some
 187  * common printing needs. Simple new {@link #print()} methods allow for quick
 188  * and easy addition of printing support to your application. In addition, a new
 189  * {@link #getPrintable} method is available for more advanced printing needs.
 190  * <p>
 191  * As for all {@code JComponent} 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} package.
 208  * Please see {@link java.beans.XMLEncoder}.
 209  *
 210  *
 211  * @beaninfo
 212  *   attribute: isContainer false
 213  * description: A component which displays data in a two dimensional grid.
 214  *
 215  * @author Philip Milne
 216  * @author Shannon Hickey (printing support)
 217  * @see javax.swing.table.DefaultTableModel
 218  * @see javax.swing.table.TableRowSorter
 219  * @since 1.2
 220  */
 221 /* The first versions of the JTable, contained in Swing-0.1 through
 222  * Swing-0.4, were written by Alan Chung.
 223  */
 224 @SuppressWarnings("serial") // Same-version serialization only
 225 public class JTable extends JComponent implements TableModelListener, Scrollable,
 226     TableColumnModelListener, ListSelectionListener, CellEditorListener,
 227     Accessible, RowSorterListener


 237     private static final String uiClassID = "TableUI";
 238 
 239     /** Do not adjust column widths automatically; use a horizontal scrollbar instead. */
 240     public static final int     AUTO_RESIZE_OFF = 0;
 241 
 242     /** When a column is adjusted in the UI, adjust the next column the opposite way. */
 243     public static final int     AUTO_RESIZE_NEXT_COLUMN = 1;
 244 
 245     /** During UI adjustment, change subsequent columns to preserve the total width;
 246       * this is the default behavior. */
 247     public static final int     AUTO_RESIZE_SUBSEQUENT_COLUMNS = 2;
 248 
 249     /** During all resize operations, apply adjustments to the last column only. */
 250     public static final int     AUTO_RESIZE_LAST_COLUMN = 3;
 251 
 252     /** During all resize operations, proportionately resize all columns. */
 253     public static final int     AUTO_RESIZE_ALL_COLUMNS = 4;
 254 
 255 
 256     /**
 257      * Printing modes, used in printing {@code JTable}s.
 258      *
 259      * @see #print(JTable.PrintMode, MessageFormat, MessageFormat,
 260      *             boolean, PrintRequestAttributeSet, boolean)
 261      * @see #getPrintable
 262      * @since 1.5
 263      */
 264     public enum PrintMode {
 265 
 266         /**
 267          * Printing mode that prints the table at its current size,
 268          * spreading both columns and rows across multiple pages if necessary.
 269          */
 270         NORMAL,
 271 
 272         /**
 273          * Printing mode that scales the output smaller, if necessary,
 274          * to fit the table's entire width (and thereby all columns) on each page;
 275          * Rows are spread across multiple pages as necessary.
 276          */
 277         FIT_WIDTH
 278     }
 279 
 280 
 281 //
 282 // Instance Variables
 283 //
 284 
 285     /** The {@code TableModel} of the table. */
 286     protected TableModel        dataModel;
 287 
 288     /** The {@code TableColumnModel} of the table. */
 289     protected TableColumnModel  columnModel;
 290 
 291     /** The {@code ListSelectionModel} of the table, used to keep track of row selections. */
 292     protected ListSelectionModel selectionModel;
 293 
 294     /** The {@code TableHeader} working with the table. */
 295     protected JTableHeader      tableHeader;
 296 
 297     /** The height in pixels of each row in the table. */
 298     protected int               rowHeight;
 299 
 300     /** The height in pixels of the margin between the cells in each row. */
 301     protected int               rowMargin;
 302 
 303     /** The color of the grid. */
 304     protected Color             gridColor;
 305 
 306     /** The table draws horizontal lines between cells if {@code showHorizontalLines} is true. */
 307     protected boolean           showHorizontalLines;
 308 
 309     /** The table draws vertical lines between cells if {@code showVerticalLines} is true. */
 310     protected boolean           showVerticalLines;
 311 
 312     /**
 313      *  Determines if the table automatically resizes the
 314      *  width of the table's columns to take up the entire width of the
 315      *  table, and how it does the resizing.
 316      */
 317     protected int               autoResizeMode;
 318 
 319     /**
 320      *  The table will query the {@code TableModel} to build the default
 321      *  set of columns if this is true.
 322      */
 323     protected boolean           autoCreateColumnsFromModel;
 324 
 325     /** Used by the {@code Scrollable} interface to determine the initial visible area. */
 326     protected Dimension         preferredViewportSize;
 327 
 328     /** True if row selection is allowed in this table. */
 329     protected boolean           rowSelectionAllowed;
 330 
 331     /**
 332      * Obsolete as of Java 2 platform v1.3.  Please use the
 333      * {@code rowSelectionAllowed} property and the
 334      * {@code columnSelectionAllowed} property of the
 335      * {@code columnModel} instead. Or use the
 336      * method {@code getCellSelectionEnabled}.
 337      */
 338     /*
 339      * If true, both a row selection and a column selection
 340      * can be non-empty at the same time, the selected cells are the
 341      * the cells whose row and column are both selected.
 342      */
 343     protected boolean           cellSelectionEnabled;
 344 
 345     /** If editing, the {@code Component} that is handling the editing. */
 346     protected transient Component       editorComp;
 347 
 348     /**
 349      * The active cell editor object, that overwrites the screen real estate
 350      * occupied by the current cell and allows the user to change its contents.
 351      * {@code null} if the table isn't currently editing.
 352      */
 353     protected transient TableCellEditor cellEditor;
 354 
 355     /** Identifies the column of the cell being edited. */
 356     protected transient int             editingColumn;
 357 
 358     /** Identifies the row of the cell being edited. */
 359     protected transient int             editingRow;
 360 
 361    /**
 362      * A table of objects that display the contents of a cell,
 363      * indexed by class as declared in {@code getColumnClass}
 364      * in the {@code TableModel} interface.
 365      */
 366     protected transient Hashtable<Object, Object> defaultRenderersByColumnClass;
 367     // Logicaly, the above is a Hashtable<Class<?>, TableCellRenderer>.
 368     // It is declared otherwise to accomodate using UIDefaults.
 369 
 370     /**
 371      * A table of objects that display and edit the contents of a cell,
 372      * indexed by class as declared in {@code getColumnClass}
 373      * in the {@code TableModel} interface.
 374      */
 375     protected transient Hashtable<Object, Object> defaultEditorsByColumnClass;
 376     // Logicaly, the above is a Hashtable<Class<?>, TableCellEditor>.
 377     // It is declared otherwise to accomodate using UIDefaults.
 378 
 379     /** The foreground color of selected cells. */
 380     protected Color selectionForeground;
 381 
 382     /** The background color of selected cells. */
 383     protected Color selectionBackground;
 384 
 385 //
 386 // Private state
 387 //
 388 
 389     // WARNING: If you directly access this field you should also change the
 390     // SortManager.modelRowSizes field as well.
 391     private SizeSequence rowModel;
 392     private boolean dragEnabled;
 393     private boolean surrendersFocusOnKeystroke;


 440     private boolean autoCreateRowSorter;
 441 
 442     /**
 443      * Whether or not the table always fills the viewport height.
 444      * @see #setFillsViewportHeight
 445      * @see #getScrollableTracksViewportHeight
 446      */
 447     private boolean fillsViewportHeight;
 448 
 449     /**
 450      * The drop mode for this component.
 451      */
 452     private DropMode dropMode = DropMode.USE_SELECTION;
 453 
 454     /**
 455      * The drop location.
 456      */
 457     private transient DropLocation dropLocation;
 458 
 459     /**
 460      * A subclass of {@code TransferHandler.DropLocation} representing
 461      * a drop location for a {@code JTable}.
 462      *
 463      * @see #getDropLocation
 464      * @since 1.6
 465      */
 466     public static final class DropLocation extends TransferHandler.DropLocation {
 467         private final int row;
 468         private final int col;
 469         private final boolean isInsertRow;
 470         private final boolean isInsertCol;
 471 
 472         private DropLocation(Point p, int row, int col,
 473                              boolean isInsertRow, boolean isInsertCol) {
 474 
 475             super(p);
 476             this.row = row;
 477             this.col = col;
 478             this.isInsertRow = isInsertRow;
 479             this.isInsertCol = isInsertCol;
 480         }
 481 
 482         /**
 483          * Returns the row index where a dropped item should be placed in the
 484          * table. Interpretation of the value depends on the return of
 485          * {@code isInsertRow()}. If that method returns
 486          * {@code true} this value indicates the index where a new
 487          * row should be inserted. Otherwise, it represents the value
 488          * of an existing row on which the data was dropped. This index is
 489          * in terms of the view.
 490          * <p>
 491          * {@code -1} indicates that the drop occurred over empty space,
 492          * and no row could be calculated.
 493          *
 494          * @return the drop row
 495          */
 496         public int getRow() {
 497             return row;
 498         }
 499 
 500         /**
 501          * Returns the column index where a dropped item should be placed in the
 502          * table. Interpretation of the value depends on the return of
 503          * {@code isInsertColumn()}. If that method returns
 504          * {@code true} this value indicates the index where a new
 505          * column should be inserted. Otherwise, it represents the value
 506          * of an existing column on which the data was dropped. This index is
 507          * in terms of the view.
 508          * <p>
 509          * {@code -1} indicates that the drop occurred over empty space,
 510          * and no column could be calculated.
 511          *
 512          * @return the drop row
 513          */
 514         public int getColumn() {
 515             return col;
 516         }
 517 
 518         /**
 519          * Returns whether or not this location represents an insert
 520          * of a row.
 521          *
 522          * @return whether or not this is an insert row
 523          */
 524         public boolean isInsertRow() {
 525             return isInsertRow;
 526         }
 527 
 528         /**
 529          * Returns whether or not this location represents an insert


 541          * and the content and format of the returned string may vary
 542          * between implementations.
 543          *
 544          * @return a string representation of this drop location
 545          */
 546         public String toString() {
 547             return getClass().getName()
 548                    + "[dropPoint=" + getDropPoint() + ","
 549                    + "row=" + row + ","
 550                    + "column=" + col + ","
 551                    + "insertRow=" + isInsertRow + ","
 552                    + "insertColumn=" + isInsertCol + "]";
 553         }
 554     }
 555 
 556 //
 557 // Constructors
 558 //
 559 
 560     /**
 561      * Constructs a default {@code JTable} that is initialized with a default
 562      * data model, a default column model, and a default selection
 563      * model.
 564      *
 565      * @see #createDefaultDataModel
 566      * @see #createDefaultColumnModel
 567      * @see #createDefaultSelectionModel
 568      */
 569     public JTable() {
 570         this(null, null, null);
 571     }
 572 
 573     /**
 574      * Constructs a {@code JTable} that is initialized with
 575      * {@code dm} as the data model, a default column model,
 576      * and a default selection model.
 577      *
 578      * @param dm        the data model for the table
 579      * @see #createDefaultColumnModel
 580      * @see #createDefaultSelectionModel
 581      */
 582     public JTable(TableModel dm) {
 583         this(dm, null, null);
 584     }
 585 
 586     /**
 587      * Constructs a {@code JTable} that is initialized with
 588      * {@code dm} as the data model, {@code cm}
 589      * as the column model, and a default selection model.
 590      *
 591      * @param dm        the data model for the table
 592      * @param cm        the column model for the table
 593      * @see #createDefaultSelectionModel
 594      */
 595     public JTable(TableModel dm, TableColumnModel cm) {
 596         this(dm, cm, null);
 597     }
 598 
 599     /**
 600      * Constructs a {@code JTable} that is initialized with
 601      * {@code dm} as the data model, {@code cm} as the
 602      * column model, and {@code sm} as the selection model.
 603      * If any of the parameters are {@code null} this method
 604      * will initialize the table with the corresponding default model.
 605      * The {@code autoCreateColumnsFromModel} flag is set to false
 606      * if {@code cm} is non-null, otherwise it is set to true
 607      * and the column model is populated with suitable
 608      * {@code TableColumns} for the columns in {@code dm}.
 609      *
 610      * @param dm        the data model for the table
 611      * @param cm        the column model for the table
 612      * @param sm        the row selection model for the table
 613      * @see #createDefaultDataModel
 614      * @see #createDefaultColumnModel
 615      * @see #createDefaultSelectionModel
 616      */
 617     public JTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) {
 618         super();
 619         setLayout(null);
 620 
 621         setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
 622                            JComponent.getManagingFocusForwardTraversalKeys());
 623         setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
 624                            JComponent.getManagingFocusBackwardTraversalKeys());
 625         if (cm == null) {
 626             cm = createDefaultColumnModel();
 627             autoCreateColumnsFromModel = true;
 628         }
 629         setColumnModel(cm);
 630 
 631         if (sm == null) {
 632             sm = createDefaultSelectionModel();
 633         }
 634         setSelectionModel(sm);
 635 
 636     // Set the model last, that way if the autoCreatColumnsFromModel has
 637     // been set above, we will automatically populate an empty columnModel
 638     // with suitable columns for the new model.
 639         if (dm == null) {
 640             dm = createDefaultDataModel();
 641         }
 642         setModel(dm);
 643 
 644         initializeLocalVars();
 645         updateUI();
 646     }
 647 
 648     /**
 649      * Constructs a {@code JTable} with {@code numRows}
 650      * and {@code numColumns} of empty cells using
 651      * {@code DefaultTableModel}.  The columns will have
 652      * names of the form "A", "B", "C", etc.
 653      *
 654      * @param numRows           the number of rows the table holds
 655      * @param numColumns        the number of columns the table holds
 656      * @see javax.swing.table.DefaultTableModel
 657      */
 658     public JTable(int numRows, int numColumns) {
 659         this(new DefaultTableModel(numRows, numColumns));
 660     }
 661 
 662     /**
 663      * Constructs a {@code JTable} to display the values in the
 664      * {@code Vector} of {@code Vectors}, {@code rowData},
 665      * with column names, {@code columnNames}.  The
 666      * {@code Vectors} contained in {@code rowData}
 667      * should contain the values for that row. In other words,
 668      * the value of the cell at row 1, column 5 can be obtained
 669      * with the following code:
 670      *
 671      * <pre>((Vector)rowData.elementAt(1)).elementAt(5);</pre>
 672      *
 673      * @param rowData           the data for the new table
 674      * @param columnNames       names of each column
 675      */
 676     @SuppressWarnings("rawtypes")
 677     public JTable(Vector<? extends Vector> rowData, Vector<?> columnNames) {
 678         this(new DefaultTableModel(rowData, columnNames));
 679     }
 680 
 681     /**
 682      * Constructs a {@code JTable} to display the values in the two dimensional array,
 683      * {@code rowData}, with column names, {@code columnNames}.
 684      * {@code rowData} is an array of rows, so the value of the cell at row 1,
 685      * column 5 can be obtained with the following code:
 686      *
 687      * <pre> rowData[1][5]; </pre>
 688      * <p>
 689      * All rows must be of the same length as {@code columnNames}.
 690      *
 691      * @param rowData           the data for the new table
 692      * @param columnNames       names of each column
 693      */
 694     public JTable(final Object[][] rowData, final Object[] columnNames) {
 695         this(new AbstractTableModel() {
 696             public String getColumnName(int column) { return columnNames[column].toString(); }
 697             public int getRowCount() { return rowData.length; }
 698             public int getColumnCount() { return columnNames.length; }
 699             public Object getValueAt(int row, int col) { return rowData[row][col]; }
 700             public boolean isCellEditable(int row, int column) { return true; }
 701             public void setValueAt(Object value, int row, int col) {
 702                 rowData[row][col] = value;
 703                 fireTableCellUpdated(row, col);
 704             }
 705         });
 706     }
 707 
 708     /**
 709      * Calls the {@code configureEnclosingScrollPane} method.
 710      *
 711      * @see #configureEnclosingScrollPane
 712      */
 713     public void addNotify() {
 714         super.addNotify();
 715         configureEnclosingScrollPane();
 716     }
 717 
 718     /**
 719      * If this {@code JTable} is the {@code viewportView} of an enclosing {@code JScrollPane}
 720      * (the usual situation), configure this {@code ScrollPane} by, amongst other things,
 721      * installing the table's {@code tableHeader} as the {@code columnHeaderView} of the scroll pane.
 722      * When a {@code JTable} is added to a {@code JScrollPane} in the usual way,
 723      * using {@code new JScrollPane(myTable)}, {@code addNotify} is
 724      * called in the {@code JTable} (when the table is added to the viewport).
 725      * {@code JTable}'s {@code addNotify} method in turn calls this method,
 726      * which is protected so that this default installation procedure can
 727      * be overridden by a subclass.
 728      *
 729      * @see #addNotify
 730      */
 731     protected void configureEnclosingScrollPane() {
 732         Container parent = SwingUtilities.getUnwrappedParent(this);
 733         if (parent instanceof JViewport) {
 734             JViewport port = (JViewport) parent;
 735             Container gp = port.getParent();
 736             if (gp instanceof JScrollPane) {
 737                 JScrollPane scrollPane = (JScrollPane)gp;
 738                 // Make certain we are the viewPort's view and not, for
 739                 // example, the rowHeaderView of the scrollPane -
 740                 // an implementor of fixed columns might do this.
 741                 JViewport viewport = scrollPane.getViewport();
 742                 if (viewport == null ||
 743                         SwingUtilities.getUnwrappedView(viewport) != this) {
 744                     return;
 745                 }


 788                 }
 789                 // add JScrollBar corner component if available from LAF and not already set by the user
 790                 Component corner =
 791                         scrollPane.getCorner(JScrollPane.UPPER_TRAILING_CORNER);
 792                 if (corner == null || corner instanceof UIResource){
 793                     corner = null;
 794                     try {
 795                         corner = (Component) UIManager.get(
 796                                 "Table.scrollPaneCornerComponent");
 797                     } catch (Exception e) {
 798                         // just ignore and don't set corner
 799                     }
 800                     scrollPane.setCorner(JScrollPane.UPPER_TRAILING_CORNER,
 801                             corner);
 802                 }
 803             }
 804         }
 805     }
 806 
 807     /**
 808      * Calls the {@code unconfigureEnclosingScrollPane} method.
 809      *
 810      * @see #unconfigureEnclosingScrollPane
 811      */
 812     public void removeNotify() {
 813         KeyboardFocusManager.getCurrentKeyboardFocusManager().
 814             removePropertyChangeListener("permanentFocusOwner", editorRemover);
 815         editorRemover = null;
 816         unconfigureEnclosingScrollPane();
 817         super.removeNotify();
 818     }
 819 
 820     /**
 821      * Reverses the effect of {@code configureEnclosingScrollPane}
 822      * by replacing the {@code columnHeaderView} of the enclosing
 823      * scroll pane with {@code null}. {@code JTable}'s
 824      * {@code removeNotify} method calls
 825      * this method, which is protected so that this default uninstallation
 826      * procedure can be overridden by a subclass.
 827      *
 828      * @see #removeNotify
 829      * @see #configureEnclosingScrollPane
 830      * @since 1.3
 831      */
 832     protected void unconfigureEnclosingScrollPane() {
 833         Container parent = SwingUtilities.getUnwrappedParent(this);
 834         if (parent instanceof JViewport) {
 835             JViewport port = (JViewport) parent;
 836             Container gp = port.getParent();
 837             if (gp instanceof JScrollPane) {
 838                 JScrollPane scrollPane = (JScrollPane)gp;
 839                 // Make certain we are the viewPort's view and not, for
 840                 // example, the rowHeaderView of the scrollPane -
 841                 // an implementor of fixed columns might do this.
 842                 JViewport viewport = scrollPane.getViewport();
 843                 if (viewport == null ||
 844                         SwingUtilities.getUnwrappedView(viewport) != this) {


 855             }
 856         }
 857     }
 858 
 859     void setUIProperty(String propertyName, Object value) {
 860         if (propertyName == "rowHeight") {
 861             if (!isRowHeightSet) {
 862                 setRowHeight(((Number)value).intValue());
 863                 isRowHeightSet = false;
 864             }
 865             return;
 866         }
 867         super.setUIProperty(propertyName, value);
 868     }
 869 
 870 //
 871 // Static Methods
 872 //
 873 
 874     /**
 875      * Equivalent to {@code new JScrollPane(aTable)}.
 876      *
 877      * @param aTable a {@code JTable} to be used for the scroll pane
 878      * @return a {@code JScrollPane} created using {@code aTable}
 879      * @deprecated As of Swing version 1.0.2,
 880      * replaced by {@code new JScrollPane(aTable)}.
 881      */
 882     @Deprecated
 883     public static JScrollPane createScrollPaneForTable(JTable aTable) {
 884         return new JScrollPane(aTable);
 885     }
 886 
 887 //
 888 // Table Attributes
 889 //
 890 
 891     /**
 892      * Sets the {@code tableHeader} working with this {@code JTable} to {@code newHeader}.
 893      * It is legal to have a {@code null tableHeader}.
 894      *
 895      * @param   tableHeader                       new tableHeader
 896      * @see     #getTableHeader
 897      * @beaninfo
 898      *  bound: true
 899      *  description: The JTableHeader instance which renders the column headers.
 900      */
 901     public void setTableHeader(JTableHeader tableHeader) {
 902         if (this.tableHeader != tableHeader) {
 903             JTableHeader old = this.tableHeader;
 904             // Release the old header
 905             if (old != null) {
 906                 old.setTable(null);
 907             }
 908             this.tableHeader = tableHeader;
 909             if (tableHeader != null) {
 910                 tableHeader.setTable(this);
 911             }
 912             firePropertyChange("tableHeader", old, tableHeader);
 913         }
 914     }
 915 
 916     /**
 917      * Returns the {@code tableHeader} used by this {@code JTable}.
 918      *
 919      * @return  the {@code tableHeader} used by this table
 920      * @see     #setTableHeader
 921      */
 922     public JTableHeader getTableHeader() {
 923         return tableHeader;
 924     }
 925 
 926     /**
 927      * Sets the height, in pixels, of all cells to {@code rowHeight},
 928      * revalidates, and repaints.
 929      * The height of the cells will be equal to the row height minus
 930      * the row margin.
 931      *
 932      * @param   rowHeight                       new row height
 933      * @exception IllegalArgumentException      if {@code rowHeight} is
 934      *                                          less than 1
 935      * @see     #getRowHeight
 936      * @beaninfo
 937      *  bound: true
 938      *  description: The height of the specified row.
 939      */
 940     public void setRowHeight(int rowHeight) {
 941         if (rowHeight <= 0) {
 942             throw new IllegalArgumentException("New row height less than 1");
 943         }
 944         int old = this.rowHeight;
 945         this.rowHeight = rowHeight;
 946         rowModel = null;
 947         if (sortManager != null) {
 948             sortManager.modelRowSizes = null;
 949         }
 950         isRowHeightSet = true;
 951         resizeAndRepaint();
 952         firePropertyChange("rowHeight", old, rowHeight);
 953     }
 954 
 955     /**
 956      * Returns the height of a table row, in pixels.
 957      *
 958      * @return  the height in pixels of a table row
 959      * @see     #setRowHeight
 960      */
 961     public int getRowHeight() {
 962         return rowHeight;
 963     }
 964 
 965     private SizeSequence getRowModel() {
 966         if (rowModel == null) {
 967             rowModel = new SizeSequence(getRowCount(), getRowHeight());
 968         }
 969         return rowModel;
 970     }
 971 
 972     /**
 973      * Sets the height for {@code row} to {@code rowHeight},
 974      * revalidates, and repaints. The height of the cells in this row
 975      * will be equal to the row height minus the row margin.
 976      *
 977      * @param   row                             the row whose height is being
 978                                                 changed
 979      * @param   rowHeight                       new row height, in pixels
 980      * @exception IllegalArgumentException      if {@code rowHeight} is
 981      *                                          less than 1
 982      * @beaninfo
 983      *  bound: true
 984      *  description: The height in pixels of the cells in {@code row}
 985      * @since 1.3
 986      */
 987     public void setRowHeight(int row, int rowHeight) {
 988         if (rowHeight <= 0) {
 989             throw new IllegalArgumentException("New row height less than 1");
 990         }
 991         getRowModel().setSize(row, rowHeight);
 992         if (sortManager != null) {
 993             sortManager.setViewRowHeight(row, rowHeight);
 994         }
 995         resizeAndRepaint();
 996     }
 997 
 998     /**
 999      * Returns the height, in pixels, of the cells in {@code row}.
1000      * @param   row              the row whose height is to be returned
1001      * @return the height, in pixels, of the cells in the row
1002      * @since 1.3
1003      */
1004     public int getRowHeight(int row) {
1005         return (rowModel == null) ? getRowHeight() : rowModel.getSize(row);
1006     }
1007 
1008     /**
1009      * Sets the amount of empty space between cells in adjacent rows.
1010      *
1011      * @param  rowMargin  the number of pixels between cells in a row
1012      * @see     #getRowMargin
1013      * @beaninfo
1014      *  bound: true
1015      *  description: The amount of space between cells.
1016      */
1017     public void setRowMargin(int rowMargin) {
1018         int old = this.rowMargin;
1019         this.rowMargin = rowMargin;
1020         resizeAndRepaint();
1021         firePropertyChange("rowMargin", old, rowMargin);
1022     }
1023 
1024     /**
1025      * Gets the amount of empty space, in pixels, between cells. Equivalent to:
1026      * {@code getIntercellSpacing().height}.
1027      * @return the number of pixels between cells in a row
1028      *
1029      * @see     #setRowMargin
1030      */
1031     public int getRowMargin() {
1032         return rowMargin;
1033     }
1034 
1035     /**
1036      * Sets the {@code rowMargin} and the {@code columnMargin} --
1037      * the height and width of the space between cells -- to
1038      * {@code intercellSpacing}.
1039      *
1040      * @param   intercellSpacing        a {@code Dimension}
1041      *                                  specifying the new width
1042      *                                  and height between cells
1043      * @see     #getIntercellSpacing
1044      * @beaninfo
1045      *  description: The spacing between the cells,
1046      *               drawn in the background color of the JTable.
1047      */
1048     public void setIntercellSpacing(Dimension intercellSpacing) {
1049         // Set the rowMargin here and columnMargin in the TableColumnModel
1050         setRowMargin(intercellSpacing.height);
1051         getColumnModel().setColumnMargin(intercellSpacing.width);
1052 
1053         resizeAndRepaint();
1054     }
1055 
1056     /**
1057      * Returns the horizontal and vertical space between cells.
1058      * The default spacing is look and feel dependent.
1059      *
1060      * @return  the horizontal and vertical spacing between cells
1061      * @see     #setIntercellSpacing
1062      */
1063     public Dimension getIntercellSpacing() {
1064         return new Dimension(getColumnModel().getColumnMargin(), rowMargin);
1065     }
1066 
1067     /**
1068      * Sets the color used to draw grid lines to {@code gridColor} and redisplays.
1069      * The default color is look and feel dependent.
1070      *
1071      * @param   gridColor                       the new color of the grid lines
1072      * @exception IllegalArgumentException      if {@code gridColor} is {@code null}
1073      * @see     #getGridColor
1074      * @beaninfo
1075      *  bound: true
1076      *  description: The grid color.
1077      */
1078     public void setGridColor(Color gridColor) {
1079         if (gridColor == null) {
1080             throw new IllegalArgumentException("New color is null");
1081         }
1082         Color old = this.gridColor;
1083         this.gridColor = gridColor;
1084         firePropertyChange("gridColor", old, gridColor);
1085         // Redraw
1086         repaint();
1087     }
1088 
1089     /**
1090      * Returns the color used to draw grid lines.
1091      * The default color is look and feel dependent.
1092      *
1093      * @return  the color used to draw grid lines
1094      * @see     #setGridColor
1095      */
1096     public Color getGridColor() {
1097         return gridColor;
1098     }
1099 
1100     /**
1101      *  Sets whether the table draws grid lines around cells.
1102      *  If {@code showGrid} is true it does; if it is false it doesn't.
1103      *  There is no {@code getShowGrid} method as this state is held
1104      *  in two variables -- {@code showHorizontalLines} and {@code showVerticalLines} --
1105      *  each of which can be queried independently.
1106      *
1107      * @param   showGrid                 true if table view should draw grid lines
1108      *
1109      * @see     #setShowVerticalLines
1110      * @see     #setShowHorizontalLines
1111      * @beaninfo
1112      *  description: The color used to draw the grid lines.
1113      */
1114     public void setShowGrid(boolean showGrid) {
1115         setShowHorizontalLines(showGrid);
1116         setShowVerticalLines(showGrid);
1117 
1118         // Redraw
1119         repaint();
1120     }
1121 
1122     /**
1123      *  Sets whether the table draws horizontal lines between cells.
1124      *  If {@code showHorizontalLines} is true it does; if it is false it doesn't.
1125      *
1126      * @param   showHorizontalLines      true if table view should draw horizontal lines
1127      * @see     #getShowHorizontalLines
1128      * @see     #setShowGrid
1129      * @see     #setShowVerticalLines
1130      * @beaninfo
1131      *  bound: true
1132      *  description: Whether horizontal lines should be drawn in between the cells.
1133      */
1134     public void setShowHorizontalLines(boolean showHorizontalLines) {
1135         boolean old = this.showHorizontalLines;
1136         this.showHorizontalLines = showHorizontalLines;
1137         firePropertyChange("showHorizontalLines", old, showHorizontalLines);
1138 
1139         // Redraw
1140         repaint();
1141     }
1142 
1143     /**
1144      *  Sets whether the table draws vertical lines between cells.
1145      *  If {@code showVerticalLines} is true it does; if it is false it doesn't.
1146      *
1147      * @param   showVerticalLines              true if table view should draw vertical lines
1148      * @see     #getShowVerticalLines
1149      * @see     #setShowGrid
1150      * @see     #setShowHorizontalLines
1151      * @beaninfo
1152      *  bound: true
1153      *  description: Whether vertical lines should be drawn in between the cells.
1154      */
1155     public void setShowVerticalLines(boolean showVerticalLines) {
1156         boolean old = this.showVerticalLines;
1157         this.showVerticalLines = showVerticalLines;
1158         firePropertyChange("showVerticalLines", old, showVerticalLines);
1159         // Redraw
1160         repaint();
1161     }
1162 
1163     /**
1164      * Returns true if the table draws horizontal lines between cells, false if it
1165      * doesn't. The default value is look and feel dependent.


1224                 || (mode == AUTO_RESIZE_NEXT_COLUMN)
1225                 || (mode == AUTO_RESIZE_SUBSEQUENT_COLUMNS)
1226                 || (mode == AUTO_RESIZE_LAST_COLUMN)
1227                 || (mode == AUTO_RESIZE_ALL_COLUMNS);
1228     }
1229 
1230     /**
1231      * Returns the auto resize mode of the table.  The default mode
1232      * is AUTO_RESIZE_SUBSEQUENT_COLUMNS.
1233      *
1234      * @return  the autoResizeMode of the table
1235      *
1236      * @see     #setAutoResizeMode
1237      * @see     #doLayout
1238      */
1239     public int getAutoResizeMode() {
1240         return autoResizeMode;
1241     }
1242 
1243     /**
1244      * Sets this table's {@code autoCreateColumnsFromModel} flag.
1245      * This method calls {@code createDefaultColumnsFromModel} if
1246      * {@code autoCreateColumnsFromModel} changes from false to true.
1247      *
1248      * @param   autoCreateColumnsFromModel   true if {@code JTable} should automatically create columns
1249      * @see     #getAutoCreateColumnsFromModel
1250      * @see     #createDefaultColumnsFromModel
1251      * @beaninfo
1252      *  bound: true
1253      *  description: Automatically populates the columnModel when a new TableModel is submitted.
1254      */
1255     public void setAutoCreateColumnsFromModel(boolean autoCreateColumnsFromModel) {
1256         if (this.autoCreateColumnsFromModel != autoCreateColumnsFromModel) {
1257             boolean old = this.autoCreateColumnsFromModel;
1258             this.autoCreateColumnsFromModel = autoCreateColumnsFromModel;
1259             if (autoCreateColumnsFromModel) {
1260                 createDefaultColumnsFromModel();
1261             }
1262             firePropertyChange("autoCreateColumnsFromModel", old, autoCreateColumnsFromModel);
1263         }
1264     }
1265 
1266     /**
1267      * Determines whether the table will create default columns from the model.
1268      * If true, {@code setModel} will clear any existing columns and
1269      * create new columns from the new model.  Also, if the event in
1270      * the {@code tableChanged} notification specifies that the
1271      * entire table changed, then the columns will be rebuilt.
1272      * The default is true.
1273      *
1274      * @return  the autoCreateColumnsFromModel of the table
1275      * @see     #setAutoCreateColumnsFromModel
1276      * @see     #createDefaultColumnsFromModel
1277      */
1278     public boolean getAutoCreateColumnsFromModel() {
1279         return autoCreateColumnsFromModel;
1280     }
1281 
1282     /**
1283      * Creates default columns for the table from
1284      * the data model using the {@code getColumnCount} method
1285      * defined in the {@code TableModel} interface.
1286      * <p>
1287      * Clears any existing columns before creating the
1288      * new columns based on information from the model.
1289      *
1290      * @see     #getAutoCreateColumnsFromModel
1291      */
1292     public void createDefaultColumnsFromModel() {
1293         TableModel m = getModel();
1294         if (m != null) {
1295             // Remove any current columns
1296             TableColumnModel cm = getColumnModel();
1297             while (cm.getColumnCount() > 0) {
1298                 cm.removeColumn(cm.getColumn(0));
1299             }
1300 
1301             // Create new columns from the data model info
1302             for (int i = 0; i < m.getColumnCount(); i++) {
1303                 TableColumn newColumn = new TableColumn(i);
1304                 addColumn(newColumn);
1305             }
1306         }
1307     }
1308 
1309     /**
1310      * Sets a default cell renderer to be used if no renderer has been set in
1311      * a {@code TableColumn}. If renderer is {@code null},
1312      * removes the default renderer for this column class.
1313      *
1314      * @param  columnClass     set the default cell renderer for this columnClass
1315      * @param  renderer        default cell renderer to be used for this
1316      *                         columnClass
1317      * @see     #getDefaultRenderer
1318      * @see     #setDefaultEditor
1319      */
1320     public void setDefaultRenderer(Class<?> columnClass, TableCellRenderer renderer) {
1321         if (renderer != null) {
1322             defaultRenderersByColumnClass.put(columnClass, renderer);
1323         }
1324         else {
1325             defaultRenderersByColumnClass.remove(columnClass);
1326         }
1327     }
1328 
1329     /**
1330      * Returns the cell renderer to be used when no renderer has been set in
1331      * a {@code TableColumn}. During the rendering of cells the renderer is fetched from
1332      * a {@code Hashtable} of entries according to the class of the cells in the column. If
1333      * there is no entry for this {@code columnClass} the method returns
1334      * the entry for the most specific superclass. The {@code JTable} installs entries
1335      * for {@code Object}, {@code Number}, and {@code Boolean}, all of which can be modified
1336      * or replaced.
1337      *
1338      * @param   columnClass   return the default cell renderer
1339      *                        for this columnClass
1340      * @return  the renderer for this columnClass
1341      * @see     #setDefaultRenderer
1342      * @see     #getColumnClass
1343      */
1344     public TableCellRenderer getDefaultRenderer(Class<?> columnClass) {
1345         if (columnClass == null) {
1346             return null;
1347         }
1348         else {
1349             Object renderer = defaultRenderersByColumnClass.get(columnClass);
1350             if (renderer != null) {
1351                 return (TableCellRenderer)renderer;
1352             }
1353             else {
1354                 Class<?> c = columnClass.getSuperclass();
1355                 if (c == null && columnClass != Object.class) {
1356                     c = Object.class;
1357                 }
1358                 return getDefaultRenderer(c);
1359             }
1360         }
1361     }
1362 
1363     /**
1364      * Sets a default cell editor to be used if no editor has been set in
1365      * a {@code TableColumn}. If no editing is required in a table, or a
1366      * particular column in a table, uses the {@code isCellEditable}
1367      * method in the {@code TableModel} interface to ensure that this
1368      * {@code JTable} will not start an editor in these columns.
1369      * If editor is {@code null}, removes the default editor for this
1370      * column class.
1371      *
1372      * @param  columnClass  set the default cell editor for this columnClass
1373      * @param  editor   default cell editor to be used for this columnClass
1374      * @see     TableModel#isCellEditable
1375      * @see     #getDefaultEditor
1376      * @see     #setDefaultRenderer
1377      */
1378     public void setDefaultEditor(Class<?> columnClass, TableCellEditor editor) {
1379         if (editor != null) {
1380             defaultEditorsByColumnClass.put(columnClass, editor);
1381         }
1382         else {
1383             defaultEditorsByColumnClass.remove(columnClass);
1384         }
1385     }
1386 
1387     /**
1388      * Returns the editor to be used when no editor has been set in
1389      * a {@code TableColumn}. During the editing of cells the editor is fetched from
1390      * a {@code Hashtable} of entries according to the class of the cells in the column. If
1391      * there is no entry for this {@code columnClass} the method returns
1392      * the entry for the most specific superclass. The {@code JTable} installs entries
1393      * for {@code Object}, {@code Number}, and {@code Boolean}, all of which can be modified
1394      * or replaced.
1395      *
1396      * @param   columnClass  return the default cell editor for this columnClass
1397      * @return the default cell editor to be used for this columnClass
1398      * @see     #setDefaultEditor
1399      * @see     #getColumnClass
1400      */
1401     public TableCellEditor getDefaultEditor(Class<?> columnClass) {
1402         if (columnClass == null) {
1403             return null;
1404         }
1405         else {
1406             Object editor = defaultEditorsByColumnClass.get(columnClass);
1407             if (editor != null) {
1408                 return (TableCellEditor)editor;
1409             }
1410             else {
1411                 return getDefaultEditor(columnClass.getSuperclass());
1412             }
1413         }


1417      * Turns on or off automatic drag handling. In order to enable automatic
1418      * drag handling, this property should be set to {@code true}, and the
1419      * table's {@code TransferHandler} needs to be {@code non-null}.
1420      * The default value of the {@code dragEnabled} property is {@code false}.
1421      * <p>
1422      * The job of honoring this property, and recognizing a user drag gesture,
1423      * lies with the look and feel implementation, and in particular, the table's
1424      * {@code TableUI}. When automatic drag handling is enabled, most look and
1425      * feels (including those that subclass {@code BasicLookAndFeel}) begin a
1426      * drag and drop operation whenever the user presses the mouse button over
1427      * an item (in single selection mode) or a selection (in other selection
1428      * modes) and then moves the mouse a few pixels. Setting this property to
1429      * {@code true} can therefore have a subtle effect on how selections behave.
1430      * <p>
1431      * If a look and feel is used that ignores this property, you can still
1432      * begin a drag and drop operation by calling {@code exportAsDrag} on the
1433      * table's {@code TransferHandler}.
1434      *
1435      * @param b whether or not to enable automatic drag handling
1436      * @exception HeadlessException if
1437      *            {@code b} is {@code true} and
1438      *            {@code GraphicsEnvironment.isHeadless()}
1439      *            returns {@code true}
1440      * @see java.awt.GraphicsEnvironment#isHeadless
1441      * @see #getDragEnabled
1442      * @see #setTransferHandler
1443      * @see TransferHandler
1444      * @since 1.4
1445      *
1446      * @beaninfo
1447      *  description: determines whether automatic drag handling is enabled
1448      *        bound: false
1449      */
1450     public void setDragEnabled(boolean b) {
1451         checkDragEnabled(b);
1452         dragEnabled = b;
1453     }
1454 
1455     private void checkDragEnabled(boolean b) {
1456         if (b && GraphicsEnvironment.isHeadless()) {
1457             throw new HeadlessException();
1458         }
1459     }
1460 
1461     /**
1462      * Returns whether or not automatic drag handling is enabled.
1463      *
1464      * @return the value of the {@code dragEnabled} property
1465      * @see #setDragEnabled
1466      * @since 1.4
1467      */
1468     public boolean getDragEnabled() {
1469         return dragEnabled;
1470     }
1471 
1472     /**
1473      * Sets the drop mode for this component. For backward compatibility,
1474      * the default for this property is {@code DropMode.USE_SELECTION}.
1475      * Usage of one of the other modes is recommended, however, for an
1476      * improved user experience. {@code DropMode.ON}, for instance,
1477      * offers similar behavior of showing items as selected, but does so without
1478      * affecting the actual selection in the table.
1479      * <p>
1480      * {@code JTable} supports the following drop modes:
1481      * <ul>
1482      *    <li>{@code DropMode.USE_SELECTION}</li>
1483      *    <li>{@code DropMode.ON}</li>
1484      *    <li>{@code DropMode.INSERT}</li>
1485      *    <li>{@code DropMode.INSERT_ROWS}</li>
1486      *    <li>{@code DropMode.INSERT_COLS}</li>
1487      *    <li>{@code DropMode.ON_OR_INSERT}</li>
1488      *    <li>{@code DropMode.ON_OR_INSERT_ROWS}</li>
1489      *    <li>{@code DropMode.ON_OR_INSERT_COLS}</li>
1490      * </ul>
1491      * <p>
1492      * The drop mode is only meaningful if this component has a
1493      * {@code TransferHandler} that accepts drops.
1494      *
1495      * @param dropMode the drop mode to use
1496      * @throws IllegalArgumentException if the drop mode is unsupported
1497      *         or {@code null}
1498      * @see #getDropMode
1499      * @see #getDropLocation
1500      * @see #setTransferHandler
1501      * @see TransferHandler
1502      * @since 1.6
1503      */
1504     public final void setDropMode(DropMode dropMode) {
1505         checkDropMode(dropMode);
1506         this.dropMode = dropMode;
1507     }
1508 
1509     private static void checkDropMode(DropMode dropMode) {
1510         if (dropMode != null) {
1511             switch (dropMode) {
1512                 case USE_SELECTION:
1513                 case ON:
1514                 case INSERT:
1515                 case INSERT_ROWS:
1516                 case INSERT_COLS:
1517                 case ON_OR_INSERT:


1522         }
1523         throw new IllegalArgumentException(dropMode
1524                 + ": Unsupported drop mode for table");
1525     }
1526     /**
1527      * Returns the drop mode for this component.
1528      *
1529      * @return the drop mode for this component
1530      * @see #setDropMode
1531      * @since 1.6
1532      */
1533     public final DropMode getDropMode() {
1534         return dropMode;
1535     }
1536 
1537     /**
1538      * Calculates a drop location in this component, representing where a
1539      * drop at the given point should insert data.
1540      *
1541      * @param p the point to calculate a drop location for
1542      * @return the drop location, or {@code null}
1543      */
1544     DropLocation dropLocationForPoint(Point p) {
1545         DropLocation location = null;
1546 
1547         int row = rowAtPoint(p);
1548         int col = columnAtPoint(p);
1549         boolean outside = Boolean.TRUE == getClientProperty("Table.isFileList")
1550                           && SwingUtilities2.pointOutsidePrefSize(this, row, col, p);
1551 
1552         Rectangle rect = getCellRect(row, col, true);
1553         Section xSection, ySection;
1554         boolean between = false;
1555         boolean ltr = getComponentOrientation().isLeftToRight();
1556 
1557         switch(dropMode) {
1558             case USE_SELECTION:
1559             case ON:
1560                 if (row == -1 || col == -1 || outside) {
1561                     location = new DropLocation(p, -1, -1, false, false);
1562                 } else {


1718     }
1719 
1720     /**
1721      * Called to set or clear the drop location during a DnD operation.
1722      * In some cases, the component may need to use it's internal selection
1723      * temporarily to indicate the drop location. To help facilitate this,
1724      * this method returns and accepts as a parameter a state object.
1725      * This state object can be used to store, and later restore, the selection
1726      * state. Whatever this method returns will be passed back to it in
1727      * future calls, as the state parameter. If it wants the DnD system to
1728      * continue storing the same state, it must pass it back every time.
1729      * Here's how this is used:
1730      * <p>
1731      * Let's say that on the first call to this method the component decides
1732      * to save some state (because it is about to use the selection to show
1733      * a drop index). It can return a state object to the caller encapsulating
1734      * any saved selection state. On a second call, let's say the drop location
1735      * is being changed to something else. The component doesn't need to
1736      * restore anything yet, so it simply passes back the same state object
1737      * to have the DnD system continue storing it. Finally, let's say this
1738      * method is messaged with {@code null}. This means DnD
1739      * is finished with this component for now, meaning it should restore
1740      * state. At this point, it can use the state parameter to restore
1741      * said state, and of course return {@code null} since there's
1742      * no longer anything to store.
1743      *
1744      * @param location the drop location (as calculated by
1745      *        {@code dropLocationForPoint}) or {@code null}
1746      *        if there's no longer a valid drop location
1747      * @param state the state object saved earlier for this component,
1748      *        or {@code null}
1749      * @param forDrop whether or not the method is being called because an
1750      *        actual drop occurred
1751      * @return any saved state for this component, or {@code null} if none
1752      */
1753     Object setDropLocation(TransferHandler.DropLocation location,
1754                            Object state,
1755                            boolean forDrop) {
1756 
1757         Object retVal = null;
1758         DropLocation tableLocation = (DropLocation)location;
1759 
1760         if (dropMode == DropMode.USE_SELECTION) {
1761             if (tableLocation == null) {
1762                 if (!forDrop && state != null) {
1763                     clearSelection();
1764 
1765                     int[] rows = ((int[][])state)[0];
1766                     int[] cols = ((int[][])state)[1];
1767                     int[] anchleads = ((int[][])state)[2];
1768 
1769                     for (int row : rows) {
1770                         addRowSelectionInterval(row, row);
1771                     }


1806                     setColumnSelectionInterval(tableLocation.getColumn(),
1807                                                tableLocation.getColumn());
1808                 }
1809             }
1810         }
1811 
1812         DropLocation old = dropLocation;
1813         dropLocation = tableLocation;
1814         firePropertyChange("dropLocation", old, dropLocation);
1815 
1816         return retVal;
1817     }
1818 
1819     /**
1820      * Returns the location that this component should visually indicate
1821      * as the drop location during a DnD operation over the component,
1822      * or {@code null} if no location is to currently be shown.
1823      * <p>
1824      * This method is not meant for querying the drop location
1825      * from a {@code TransferHandler}, as the drop location is only
1826      * set after the {@code TransferHandler}'s {@code canImport}
1827      * has returned and has allowed for the location to be shown.
1828      * <p>
1829      * When this property changes, a property change event with
1830      * name "dropLocation" is fired by the component.
1831      *
1832      * @return the drop location
1833      * @see #setDropMode
1834      * @see TransferHandler#canImport(TransferHandler.TransferSupport)
1835      * @since 1.6
1836      */
1837     public final DropLocation getDropLocation() {
1838         return dropLocation;
1839     }
1840 
1841     /**
1842      * Specifies whether a {@code RowSorter} should be created for the
1843      * table whenever its model changes.
1844      * <p>
1845      * When {@code setAutoCreateRowSorter(true)} is invoked, a {@code
1846      * TableRowSorter} is immediately created and installed on the


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


1952     }
1953 
1954     /**
1955      * Returns the object responsible for sorting.
1956      *
1957      * @return the object responsible for sorting
1958      * @since 1.6
1959      */
1960     public RowSorter<? extends TableModel> getRowSorter() {
1961         return (sortManager != null) ? sortManager.sorter : null;
1962     }
1963 
1964 //
1965 // Selection methods
1966 //
1967     /**
1968      * Sets the table's selection mode to allow only single selections, a single
1969      * contiguous interval, or multiple intervals.
1970      * <P>
1971      * <b>Note:</b>
1972      * {@code JTable} provides all the methods for handling
1973      * column and row selection.  When setting states,
1974      * such as {@code setSelectionMode}, it not only
1975      * updates the mode for the row selection model but also sets similar
1976      * values in the selection model of the {@code columnModel}.
1977      * If you want to have the row and column selection models operating
1978      * in different modes, set them both directly.
1979      * <p>
1980      * Both the row and column selection models for {@code JTable}
1981      * default to using a {@code DefaultListSelectionModel}
1982      * so that {@code JTable} works the same way as the
1983      * {@code JList}. See the {@code setSelectionMode} method
1984      * in {@code JList} for details about the modes.
1985      *
1986      * @param selectionMode the mode used by the row and column selection models
1987      * @see JList#setSelectionMode
1988      * @beaninfo
1989      * description: The selection mode used by the row and column selection models.
1990      *        enum: SINGLE_SELECTION            ListSelectionModel.SINGLE_SELECTION
1991      *              SINGLE_INTERVAL_SELECTION   ListSelectionModel.SINGLE_INTERVAL_SELECTION
1992      *              MULTIPLE_INTERVAL_SELECTION ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
1993      */
1994     public void setSelectionMode(int selectionMode) {
1995         clearSelection();
1996         getSelectionModel().setSelectionMode(selectionMode);
1997         getColumnModel().getSelectionModel().setSelectionMode(selectionMode);
1998     }
1999 
2000     /**
2001      * Sets whether the rows in this model can be selected.
2002      *
2003      * @param rowSelectionAllowed   true if this model will allow row selection
2004      * @see #getRowSelectionAllowed


2042         if (old != columnSelectionAllowed) {
2043             repaint();
2044         }
2045         firePropertyChange("columnSelectionAllowed", old, columnSelectionAllowed);
2046     }
2047 
2048     /**
2049      * Returns true if columns can be selected.
2050      *
2051      * @return true if columns can be selected, otherwise false
2052      * @see #setColumnSelectionAllowed
2053      */
2054     public boolean getColumnSelectionAllowed() {
2055         return columnModel.getColumnSelectionAllowed();
2056     }
2057 
2058     /**
2059      * Sets whether this table allows both a column selection and a
2060      * row selection to exist simultaneously. When set,
2061      * the table treats the intersection of the row and column selection
2062      * models as the selected cells. Override {@code isCellSelected} to
2063      * change this default behavior. This method is equivalent to setting
2064      * both the {@code rowSelectionAllowed} property and
2065      * {@code columnSelectionAllowed} property of the
2066      * {@code columnModel} to the supplied value.
2067      *
2068      * @param  cellSelectionEnabled     true if simultaneous row and column
2069      *                                  selection is allowed
2070      * @see #getCellSelectionEnabled
2071      * @see #isCellSelected
2072      * @beaninfo
2073      *  bound: true
2074      *    attribute: visualUpdate true
2075      *  description: Select a rectangular region of cells rather than
2076      *               rows or columns.
2077      */
2078     public void setCellSelectionEnabled(boolean cellSelectionEnabled) {
2079         setRowSelectionAllowed(cellSelectionEnabled);
2080         setColumnSelectionAllowed(cellSelectionEnabled);
2081         boolean old = this.cellSelectionEnabled;
2082         this.cellSelectionEnabled = cellSelectionEnabled;
2083         firePropertyChange("cellSelectionEnabled", old, cellSelectionEnabled);
2084     }
2085 
2086     /**
2087      * Returns true if both row and column selection models are enabled.
2088      * Equivalent to
2089      * {@code getRowSelectionAllowed() && getColumnSelectionAllowed()}.
2090      *
2091      * @return true if both row and column selection models are enabled
2092      *
2093      * @see #setCellSelectionEnabled
2094      */
2095     public boolean getCellSelectionEnabled() {
2096         return getRowSelectionAllowed() && getColumnSelectionAllowed();
2097     }
2098 
2099     /**
2100      *  Selects all rows, columns, and cells in the table.
2101      */
2102     public void selectAll() {
2103         // If I'm currently editing, then I should stop editing
2104         if (isEditing()) {
2105             removeEditor();
2106         }
2107         if (getRowCount() > 0 && getColumnCount() > 0) {
2108             int oldLead;
2109             int oldAnchor;


2161     private int getAdjustedIndex(int index, boolean row) {
2162         int compare = row ? getRowCount() : getColumnCount();
2163         return index < compare ? index : -1;
2164     }
2165 
2166     private int boundRow(int row) throws IllegalArgumentException {
2167         if (row < 0 || row >= getRowCount()) {
2168             throw new IllegalArgumentException("Row index out of range");
2169         }
2170         return row;
2171     }
2172 
2173     private int boundColumn(int col) {
2174         if (col< 0 || col >= getColumnCount()) {
2175             throw new IllegalArgumentException("Column index out of range");
2176         }
2177         return col;
2178     }
2179 
2180     /**
2181      * Selects the rows from {@code index0} to {@code index1},
2182      * inclusive.
2183      *
2184      * @exception IllegalArgumentException      if {@code index0} or
2185      *                                          {@code index1} lie outside
2186      *                                          [0, {@code getRowCount()}-1]
2187      * @param   index0 one end of the interval
2188      * @param   index1 the other end of the interval
2189      */
2190     public void setRowSelectionInterval(int index0, int index1) {
2191         selectionModel.setSelectionInterval(boundRow(index0), boundRow(index1));
2192     }
2193 
2194     /**
2195      * Selects the columns from {@code index0} to {@code index1},
2196      * inclusive.
2197      *
2198      * @exception IllegalArgumentException      if {@code index0} or
2199      *                                          {@code index1} lie outside
2200      *                                          [0, {@code getColumnCount()}-1]
2201      * @param   index0 one end of the interval
2202      * @param   index1 the other end of the interval
2203      */
2204     public void setColumnSelectionInterval(int index0, int index1) {
2205         columnModel.getSelectionModel().setSelectionInterval(boundColumn(index0), boundColumn(index1));
2206     }
2207 
2208     /**
2209      * Adds the rows from {@code index0} to {@code index1}, inclusive, to
2210      * the current selection.
2211      *
2212      * @exception IllegalArgumentException      if {@code index0} or {@code index1}
2213      *                                          lie outside [0, {@code getRowCount()}-1]
2214      * @param   index0 one end of the interval
2215      * @param   index1 the other end of the interval
2216      */
2217     public void addRowSelectionInterval(int index0, int index1) {
2218         selectionModel.addSelectionInterval(boundRow(index0), boundRow(index1));
2219     }
2220 
2221     /**
2222      * Adds the columns from {@code index0} to {@code index1},
2223      * inclusive, to the current selection.
2224      *
2225      * @exception IllegalArgumentException      if {@code index0} or
2226      *                                          {@code index1} lie outside
2227      *                                          [0, {@code getColumnCount()}-1]
2228      * @param   index0 one end of the interval
2229      * @param   index1 the other end of the interval
2230      */
2231     public void addColumnSelectionInterval(int index0, int index1) {
2232         columnModel.getSelectionModel().addSelectionInterval(boundColumn(index0), boundColumn(index1));
2233     }
2234 
2235     /**
2236      * Deselects the rows from {@code index0} to {@code index1}, inclusive.
2237      *
2238      * @exception IllegalArgumentException      if {@code index0} or
2239      *                                          {@code index1} lie outside
2240      *                                          [0, {@code getRowCount()}-1]
2241      * @param   index0 one end of the interval
2242      * @param   index1 the other end of the interval
2243      */
2244     public void removeRowSelectionInterval(int index0, int index1) {
2245         selectionModel.removeSelectionInterval(boundRow(index0), boundRow(index1));
2246     }
2247 
2248     /**
2249      * Deselects the columns from {@code index0} to {@code index1}, inclusive.
2250      *
2251      * @exception IllegalArgumentException      if {@code index0} or
2252      *                                          {@code index1} lie outside
2253      *                                          [0, {@code getColumnCount()}-1]
2254      * @param   index0 one end of the interval
2255      * @param   index1 the other end of the interval
2256      */
2257     public void removeColumnSelectionInterval(int index0, int index1) {
2258         columnModel.getSelectionModel().removeSelectionInterval(boundColumn(index0), boundColumn(index1));
2259     }
2260 
2261     /**
2262      * Returns the index of the first selected row, -1 if no row is selected.
2263      * @return the index of the first selected row
2264      */
2265     public int getSelectedRow() {
2266         return selectionModel.getMinSelectionIndex();
2267     }
2268 
2269     /**
2270      * Returns the index of the first selected column,
2271      * -1 if no column is selected.
2272      * @return the index of the first selected column
2273      */


2328                 count++;
2329             }
2330         }
2331         return count;
2332     }
2333 
2334     /**
2335      * Returns the number of selected columns.
2336      *
2337      * @return the number of selected columns, 0 if no columns are selected
2338      */
2339     public int getSelectedColumnCount() {
2340         return columnModel.getSelectedColumnCount();
2341     }
2342 
2343     /**
2344      * Returns true if the specified index is in the valid range of rows,
2345      * and the row at that index is selected.
2346      *
2347      * @param row a row in the row model
2348      * @return true if {@code row} is a valid index and the row at
2349      *              that index is selected (where 0 is the first row)
2350      */
2351     public boolean isRowSelected(int row) {
2352         return selectionModel.isSelectedIndex(row);
2353     }
2354 
2355     /**
2356      * Returns true if the specified index is in the valid range of columns,
2357      * and the column at that index is selected.
2358      *
2359      * @param   column   the column in the column model
2360      * @return true if {@code column} is a valid index and the column at
2361      *              that index is selected (where 0 is the first column)
2362      */
2363     public boolean isColumnSelected(int column) {
2364         return columnModel.getSelectionModel().isSelectedIndex(column);
2365     }
2366 
2367     /**
2368      * Returns true if the specified indices are in the valid range of rows
2369      * and columns and the cell at the specified position is selected.
2370      * @param row   the row being queried
2371      * @param column  the column being queried
2372      *
2373      * @return true if {@code row} and {@code column} are valid indices
2374      *              and the cell at index {@code (row, column)} is selected,
2375      *              where the first row and first column are at index 0
2376      */
2377     public boolean isCellSelected(int row, int column) {
2378         if (!getRowSelectionAllowed() && !getColumnSelectionAllowed()) {
2379             return false;
2380         }
2381         return (!getRowSelectionAllowed() || isRowSelected(row)) &&
2382                (!getColumnSelectionAllowed() || isColumnSelected(column));
2383     }
2384 
2385     private void changeSelectionModel(ListSelectionModel sm, int index,
2386                                       boolean toggle, boolean extend, boolean selected,
2387                                       int anchor, boolean anchorSelected) {
2388         if (extend) {
2389             if (toggle) {
2390                 if (anchorSelected) {
2391                     sm.addSelectionInterval(anchor, index);
2392                 } else {
2393                     sm.removeSelectionInterval(anchor, index);
2394                     // this is a Windows-only behavior that we want for file lists


2402                 sm.setSelectionInterval(anchor, index);
2403             }
2404         }
2405         else {
2406             if (toggle) {
2407                 if (selected) {
2408                     sm.removeSelectionInterval(index, index);
2409                 }
2410                 else {
2411                     sm.addSelectionInterval(index, index);
2412                 }
2413             }
2414             else {
2415                 sm.setSelectionInterval(index, index);
2416             }
2417         }
2418     }
2419 
2420     /**
2421      * Updates the selection models of the table, depending on the state of the
2422      * two flags: {@code toggle} and {@code extend}. Most changes
2423      * to the selection that are the result of keyboard or mouse events received
2424      * by the UI are channeled through this method so that the behavior may be
2425      * overridden by a subclass. Some UIs may need more functionality than
2426      * this method provides, such as when manipulating the lead for discontiguous
2427      * selection, and may not call into this method for some selection changes.
2428      * <p>
2429      * This implementation uses the following conventions:
2430      * <ul>
2431      * <li> {@code toggle}: <em>false</em>, {@code extend}: <em>false</em>.
2432      *      Clear the previous selection and ensure the new cell is selected.
2433      * <li> {@code toggle}: <em>false</em>, {@code extend}: <em>true</em>.
2434      *      Extend the previous selection from the anchor to the specified cell,
2435      *      clearing all other selections.
2436      * <li> {@code toggle}: <em>true</em>, {@code extend}: <em>false</em>.
2437      *      If the specified cell is selected, deselect it. If it is not selected, select it.
2438      * <li> {@code toggle}: <em>true</em>, {@code extend}: <em>true</em>.
2439      *      Apply the selection state of the anchor to all cells between it and the
2440      *      specified cell.
2441      * </ul>
2442      * @param  rowIndex   affects the selection at {@code row}
2443      * @param  columnIndex  affects the selection at {@code column}
2444      * @param  toggle  see description above
2445      * @param  extend  if true, extend the current selection
2446      *
2447      * @since 1.3
2448      */
2449     public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
2450         ListSelectionModel rsm = getSelectionModel();
2451         ListSelectionModel csm = getColumnModel().getSelectionModel();
2452 
2453         int anchorRow = getAdjustedIndex(rsm.getAnchorSelectionIndex(), true);
2454         int anchorCol = getAdjustedIndex(csm.getAnchorSelectionIndex(), false);
2455 
2456         boolean anchorSelected = true;
2457 
2458         if (anchorRow == -1) {
2459             if (getRowCount() > 0) {
2460                 anchorRow = 0;
2461             }
2462             anchorSelected = false;
2463         }


2481 
2482         changeSelectionModel(csm, columnIndex, toggle, extend, selected,
2483                              anchorCol, anchorSelected);
2484         changeSelectionModel(rsm, rowIndex, toggle, extend, selected,
2485                              anchorRow, anchorSelected);
2486 
2487         // Scroll after changing the selection as blit scrolling is immediate,
2488         // so that if we cause the repaint after the scroll we end up painting
2489         // everything!
2490         if (getAutoscrolls()) {
2491             Rectangle cellRect = getCellRect(rowIndex, columnIndex, false);
2492             if (cellRect != null) {
2493                 scrollRectToVisible(cellRect);
2494             }
2495         }
2496     }
2497 
2498     /**
2499      * Returns the foreground color for selected cells.
2500      *
2501      * @return the {@code Color} object for the foreground property
2502      * @see #setSelectionForeground
2503      * @see #setSelectionBackground
2504      */
2505     public Color getSelectionForeground() {
2506         return selectionForeground;
2507     }
2508 
2509     /**
2510      * Sets the foreground color for selected cells.  Cell renderers
2511      * can use this color to render text and graphics for selected
2512      * cells.
2513      * <p>
2514      * The default value of this property is defined by the look
2515      * and feel implementation.
2516      * <p>
2517      * This is a <a href="http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html">JavaBeans</a> bound property.
2518      *
2519      * @param selectionForeground  the {@code Color} to use in the foreground
2520      *                             for selected list items
2521      * @see #getSelectionForeground
2522      * @see #setSelectionBackground
2523      * @see #setForeground
2524      * @see #setBackground
2525      * @see #setFont
2526      * @beaninfo
2527      *       bound: true
2528      * description: A default foreground color for selected cells.
2529      */
2530     public void setSelectionForeground(Color selectionForeground) {
2531         Color old = this.selectionForeground;
2532         this.selectionForeground = selectionForeground;
2533         firePropertyChange("selectionForeground", old, selectionForeground);
2534         repaint();
2535     }
2536 
2537     /**
2538      * Returns the background color for selected cells.
2539      *
2540      * @return the {@code Color} used for the background of selected list items
2541      * @see #setSelectionBackground
2542      * @see #setSelectionForeground
2543      */
2544     public Color getSelectionBackground() {
2545         return selectionBackground;
2546     }
2547 
2548     /**
2549      * Sets the background color for selected cells.  Cell renderers
2550      * can use this color to the fill selected cells.
2551      * <p>
2552      * The default value of this property is defined by the look
2553      * and feel implementation.
2554      * <p>
2555      * This is a <a href="http://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html">JavaBeans</a> bound property.
2556      *
2557      * @param selectionBackground  the {@code Color} to use for the background
2558      *                             of selected cells
2559      * @see #getSelectionBackground
2560      * @see #setSelectionForeground
2561      * @see #setForeground
2562      * @see #setBackground
2563      * @see #setFont
2564      * @beaninfo
2565      *       bound: true
2566      * description: A default background color for selected cells.
2567      */
2568     public void setSelectionBackground(Color selectionBackground) {
2569         Color old = this.selectionBackground;
2570         this.selectionBackground = selectionBackground;
2571         firePropertyChange("selectionBackground", old, selectionBackground);
2572         repaint();
2573     }
2574 
2575     /**
2576      * Returns the {@code TableColumn} object for the column in the table
2577      * whose identifier is equal to {@code identifier}, when compared using
2578      * {@code equals}.
2579      *
2580      * @return  the {@code TableColumn} object that matches the identifier
2581      * @exception IllegalArgumentException      if {@code identifier} is {@code null} or no {@code TableColumn} has this identifier
2582      *
2583      * @param   identifier                      the identifier object
2584      */
2585     public TableColumn getColumn(Object identifier) {
2586         TableColumnModel cm = getColumnModel();
2587         int columnIndex = cm.getColumnIndex(identifier);
2588         return cm.getColumn(columnIndex);
2589     }
2590 
2591 //
2592 // Informally implement the TableModel interface.
2593 //
2594 
2595     /**
2596      * Maps the index of the column in the view at
2597      * {@code viewColumnIndex} to the index of the column
2598      * in the table model.  Returns the index of the corresponding
2599      * column in the model.  If {@code viewColumnIndex}
2600      * is less than zero, returns {@code viewColumnIndex}.
2601      *
2602      * @param   viewColumnIndex     the index of the column in the view
2603      * @return  the index of the corresponding column in the model
2604      *
2605      * @see #convertColumnIndexToView
2606      */
2607     public int convertColumnIndexToModel(int viewColumnIndex) {
2608         return SwingUtilities2.convertColumnIndexToModel(
2609                 getColumnModel(), viewColumnIndex);
2610     }
2611 
2612     /**
2613      * Maps the index of the column in the table model at
2614      * {@code modelColumnIndex} to the index of the column
2615      * in the view.  Returns the index of the
2616      * corresponding column in the view; returns -1 if this column is not
2617      * being displayed.  If {@code modelColumnIndex} is less than zero,
2618      * returns {@code modelColumnIndex}.
2619      *
2620      * @param   modelColumnIndex     the index of the column in the model
2621      * @return   the index of the corresponding column in the view
2622      *
2623      * @see #convertColumnIndexToModel
2624      */
2625     public int convertColumnIndexToView(int modelColumnIndex) {
2626         return SwingUtilities2.convertColumnIndexToView(
2627                 getColumnModel(), modelColumnIndex);
2628     }
2629 
2630     /**
2631      * Maps the index of the row in terms of the
2632      * {@code TableModel} to the view.  If the contents of the
2633      * model are not sorted the model and view indices are the same.
2634      *
2635      * @param modelRowIndex the index of the row in terms of the model
2636      * @return the index of the corresponding row in the view, or -1 if
2637      *         the row isn't visible
2638      * @throws IndexOutOfBoundsException if sorting is enabled and passed an
2639      *         index outside the number of rows of the {@code TableModel}
2640      * @see javax.swing.table.TableRowSorter
2641      * @since 1.6
2642      */
2643     public int convertRowIndexToView(int modelRowIndex) {
2644         RowSorter<?> sorter = getRowSorter();
2645         if (sorter != null) {
2646             return sorter.convertRowIndexToView(modelRowIndex);
2647         }
2648         return modelRowIndex;
2649     }
2650 
2651     /**
2652      * Maps the index of the row in terms of the view to the
2653      * underlying {@code TableModel}.  If the contents of the
2654      * model are not sorted the model and view indices are the same.
2655      *
2656      * @param viewRowIndex the index of the row in the view
2657      * @return the index of the corresponding row in the model
2658      * @throws IndexOutOfBoundsException if sorting is enabled and passed an
2659      *         index outside the range of the {@code JTable} as
2660      *         determined by the method {@code getRowCount}
2661      * @see javax.swing.table.TableRowSorter
2662      * @see #getRowCount
2663      * @since 1.6
2664      */
2665     public int convertRowIndexToModel(int viewRowIndex) {
2666         RowSorter<?> sorter = getRowSorter();
2667         if (sorter != null) {
2668             return sorter.convertRowIndexToModel(viewRowIndex);
2669         }
2670         return viewRowIndex;
2671     }
2672 
2673     /**
2674      * Returns the number of rows that can be shown in the
2675      * {@code JTable}, given unlimited space.  If a
2676      * {@code RowSorter} with a filter has been specified, the
2677      * number of rows returned may differ from that of the underlying
2678      * {@code TableModel}.
2679      *
2680      * @return the number of rows shown in the {@code JTable}
2681      * @see #getColumnCount
2682      */
2683     public int getRowCount() {
2684         RowSorter<?> sorter = getRowSorter();
2685         if (sorter != null) {
2686             return sorter.getViewRowCount();
2687         }
2688         return getModel().getRowCount();
2689     }
2690 
2691     /**
2692      * Returns the number of columns in the column model. Note that this may
2693      * be different from the number of columns in the table model.
2694      *
2695      * @return  the number of columns in the table
2696      * @see #getRowCount
2697      * @see #removeColumn
2698      */
2699     public int getColumnCount() {
2700         return getColumnModel().getColumnCount();
2701     }
2702 
2703     /**
2704      * Returns the name of the column appearing in the view at
2705      * column position {@code column}.
2706      *
2707      * @param  column    the column in the view being queried
2708      * @return the name of the column at position {@code column}
2709                         in the view where the first column is column 0
2710      */
2711     public String getColumnName(int column) {
2712         return getModel().getColumnName(convertColumnIndexToModel(column));
2713     }
2714 
2715     /**
2716      * Returns the type of the column appearing in the view at
2717      * column position {@code column}.
2718      *
2719      * @param   column   the column in the view being queried
2720      * @return the type of the column at position {@code column}
2721      *          in the view where the first column is column 0
2722      */
2723     public Class<?> getColumnClass(int column) {
2724         return getModel().getColumnClass(convertColumnIndexToModel(column));
2725     }
2726 
2727     /**
2728      * Returns the cell value at {@code row} and {@code column}.
2729      * <p>
2730      * <b>Note</b>: The column is specified in the table view's display
2731      *              order, and not in the {@code TableModel}'s column
2732      *              order.  This is an important distinction because as the
2733      *              user rearranges the columns in the table,
2734      *              the column at a given index in the view will change.
2735      *              Meanwhile the user's actions never affect the model's
2736      *              column ordering.
2737      *
2738      * @param   row             the row whose value is to be queried
2739      * @param   column          the column whose value is to be queried
2740      * @return  the Object at the specified cell
2741      */
2742     public Object getValueAt(int row, int column) {
2743         return getModel().getValueAt(convertRowIndexToModel(row),
2744                                      convertColumnIndexToModel(column));
2745     }
2746 
2747     /**
2748      * Sets the value for the cell in the table model at {@code row}
2749      * and {@code column}.
2750      * <p>
2751      * <b>Note</b>: The column is specified in the table view's display
2752      *              order, and not in the {@code TableModel}'s column
2753      *              order.  This is an important distinction because as the
2754      *              user rearranges the columns in the table,
2755      *              the column at a given index in the view will change.
2756      *              Meanwhile the user's actions never affect the model's
2757      *              column ordering.
2758      *
2759      * {@code aValue} is the new value.
2760      *
2761      * @param   aValue          the new value
2762      * @param   row             the row of the cell to be changed
2763      * @param   column          the column of the cell to be changed
2764      * @see #getValueAt
2765      */
2766     public void setValueAt(Object aValue, int row, int column) {
2767         getModel().setValueAt(aValue, convertRowIndexToModel(row),
2768                               convertColumnIndexToModel(column));
2769     }
2770 
2771     /**
2772      * Returns true if the cell at {@code row} and {@code column}
2773      * is editable.  Otherwise, invoking {@code setValueAt} on the cell
2774      * will have no effect.
2775      * <p>
2776      * <b>Note</b>: The column is specified in the table view's display
2777      *              order, and not in the {@code TableModel}'s column
2778      *              order.  This is an important distinction because as the
2779      *              user rearranges the columns in the table,
2780      *              the column at a given index in the view will change.
2781      *              Meanwhile the user's actions never affect the model's
2782      *              column ordering.
2783      *
2784      *
2785      * @param   row      the row whose value is to be queried
2786      * @param   column   the column whose value is to be queried
2787      * @return  true if the cell is editable
2788      * @see #setValueAt
2789      */
2790     public boolean isCellEditable(int row, int column) {
2791         return getModel().isCellEditable(convertRowIndexToModel(row),
2792                                          convertColumnIndexToModel(column));
2793     }
2794 //
2795 // Adding and removing columns in the view
2796 //
2797 
2798     /**
2799      *  Appends {@code aColumn} to the end of the array of columns held by
2800      *  this {@code JTable}'s column model.
2801      *  If the column name of {@code aColumn} is {@code null},
2802      *  sets the column name of {@code aColumn} to the name
2803      *  returned by {@code getModel().getColumnName()}.
2804      *  <p>
2805      *  To add a column to this {@code JTable} to display the
2806      *  {@code modelColumn}'th column of data in the model with a
2807      *  given {@code width}, {@code cellRenderer},
2808      *  and {@code cellEditor} you can use:
2809      *  <pre>
2810      *
2811      *      addColumn(new TableColumn(modelColumn, width, cellRenderer, cellEditor));
2812      *
2813      *  </pre>
2814      *  [Any of the {@code TableColumn} constructors can be used
2815      *  instead of this one.]
2816      *  The model column number is stored inside the {@code TableColumn}
2817      *  and is used during rendering and editing to locate the appropriates
2818      *  data values in the model. The model column number does not change
2819      *  when columns are reordered in the view.
2820      *
2821      *  @param  aColumn         the {@code TableColumn} to be added
2822      *  @see    #removeColumn
2823      */
2824     public void addColumn(TableColumn aColumn) {
2825         if (aColumn.getHeaderValue() == null) {
2826             int modelColumn = aColumn.getModelIndex();
2827             String columnName = getModel().getColumnName(modelColumn);
2828             aColumn.setHeaderValue(columnName);
2829         }
2830         getColumnModel().addColumn(aColumn);
2831     }
2832 
2833     /**
2834      *  Removes {@code aColumn} from this {@code JTable}'s
2835      *  array of columns.  Note: this method does not remove the column
2836      *  of data from the model; it just removes the {@code TableColumn}
2837      *  that was responsible for displaying it.
2838      *
2839      *  @param  aColumn         the {@code TableColumn} to be removed
2840      *  @see    #addColumn
2841      */
2842     public void removeColumn(TableColumn aColumn) {
2843         getColumnModel().removeColumn(aColumn);
2844     }
2845 
2846     /**
2847      * Moves the column {@code column} to the position currently
2848      * occupied by the column {@code targetColumn} in the view.
2849      * The old column at {@code targetColumn} is
2850      * shifted left or right to make room.
2851      *
2852      * @param   column                  the index of column to be moved
2853      * @param   targetColumn            the new index of the column
2854      */
2855     public void moveColumn(int column, int targetColumn) {
2856         getColumnModel().moveColumn(column, targetColumn);
2857     }
2858 
2859 //
2860 // Cover methods for various models and helper methods
2861 //
2862 
2863     /**
2864      * Returns the index of the column that {@code point} lies in,
2865      * or -1 if the result is not in the range
2866      * [0, {@code getColumnCount()}-1].
2867      *
2868      * @param   point   the location of interest
2869      * @return  the index of the column that {@code point} lies in,
2870      *          or -1 if the result is not in the range
2871      *          [0, {@code getColumnCount()}-1]
2872      * @see     #rowAtPoint
2873      */
2874     public int columnAtPoint(Point point) {
2875         int x = point.x;
2876         if( !getComponentOrientation().isLeftToRight() ) {
2877             x = getWidth() - x - 1;
2878         }
2879         return getColumnModel().getColumnIndexAtX(x);
2880     }
2881 
2882     /**
2883      * Returns the index of the row that {@code point} lies in,
2884      * or -1 if the result is not in the range
2885      * [0, {@code getRowCount()}-1].
2886      *
2887      * @param   point   the location of interest
2888      * @return  the index of the row that {@code point} lies in,
2889      *          or -1 if the result is not in the range
2890      *          [0, {@code getRowCount()}-1]
2891      * @see     #columnAtPoint
2892      */
2893     public int rowAtPoint(Point point) {
2894         int y = point.y;
2895         int result = (rowModel == null) ?  y/getRowHeight() : rowModel.getIndex(y);
2896         if (result < 0) {
2897             return -1;
2898         }
2899         else if (result >= getRowCount()) {
2900             return -1;
2901         }
2902         else {
2903             return result;
2904         }
2905     }
2906 
2907     /**
2908      * Returns a rectangle for the cell that lies at the intersection of
2909      * {@code row} and {@code column}.
2910      * If {@code includeSpacing} is true then the value returned
2911      * has the full height and width of the row and column
2912      * specified. If it is false, the returned rectangle is inset by the
2913      * intercell spacing to return the true bounds of the rendering or
2914      * editing component as it will be set during rendering.
2915      * <p>
2916      * If the column index is valid but the row index is less
2917      * than zero the method returns a rectangle with the
2918      * {@code y} and {@code height} values set appropriately
2919      * and the {@code x} and {@code width} values both set
2920      * to zero. In general, when either the row or column indices indicate a
2921      * cell outside the appropriate range, the method returns a rectangle
2922      * depicting the closest edge of the closest cell that is within
2923      * the table's range. When both row and column indices are out
2924      * of range the returned rectangle covers the closest
2925      * point of the closest cell.
2926      * <p>
2927      * In all cases, calculations that use this method to calculate
2928      * results along one axis will not fail because of anomalies in
2929      * calculations along the other axis. When the cell is not valid
2930      * the {@code includeSpacing} parameter is ignored.
2931      *
2932      * @param   row                   the row index where the desired cell
2933      *                                is located
2934      * @param   column                the column index where the desired cell
2935      *                                is located in the display; this is not
2936      *                                necessarily the same as the column index
2937      *                                in the data model for the table; the
2938      *                                {@link #convertColumnIndexToView(int)}
2939      *                                method may be used to convert a data
2940      *                                model column index to a display
2941      *                                column index
2942      * @param   includeSpacing        if false, return the true cell bounds -
2943      *                                computed by subtracting the intercell
2944      *                                spacing from the height and widths of
2945      *                                the column and row models
2946      *
2947      * @return  the rectangle containing the cell at location
2948      *          {@code row},{@code column}
2949      * @see #getIntercellSpacing
2950      */
2951     public Rectangle getCellRect(int row, int column, boolean includeSpacing) {
2952         Rectangle r = new Rectangle();
2953         boolean valid = true;
2954         if (row < 0) {
2955             // y = height = 0;
2956             valid = false;
2957         }
2958         else if (row >= getRowCount()) {
2959             r.y = getHeight();
2960             valid = false;
2961         }
2962         else {
2963             r.height = getRowHeight(row);
2964             r.y = (rowModel == null) ? row * r.height : rowModel.getPosition(row);
2965         }
2966 
2967         if (column < 0) {
2968             if( !getComponentOrientation().isLeftToRight() ) {


3001             r.setBounds(r.x + cm/2, r.y + rm/2, r.width - cm, r.height - rm);
3002         }
3003         return r;
3004     }
3005 
3006     private int viewIndexForColumn(TableColumn aColumn) {
3007         TableColumnModel cm = getColumnModel();
3008         for (int column = 0; column < cm.getColumnCount(); column++) {
3009             if (cm.getColumn(column) == aColumn) {
3010                 return column;
3011             }
3012         }
3013         return -1;
3014     }
3015 
3016     /**
3017      * Causes this table to lay out its rows and columns.  Overridden so
3018      * that columns can be resized to accommodate a change in the size of
3019      * a containing parent.
3020      * Resizes one or more of the columns in the table
3021      * so that the total width of all of this {@code JTable}'s
3022      * columns is equal to the width of the table.
3023      * <p>
3024      * Before the layout begins the method gets the
3025      * {@code resizingColumn} of the {@code tableHeader}.
3026      * When the method is called as a result of the resizing of an enclosing window,
3027      * the {@code resizingColumn} is {@code null}. This means that resizing
3028      * has taken place "outside" the {@code JTable} and the change -
3029      * or "delta" - should be distributed to all of the columns regardless
3030      * of this {@code JTable}'s automatic resize mode.
3031      * <p>
3032      * If the {@code resizingColumn} is not {@code null}, it is one of
3033      * the columns in the table that has changed size rather than
3034      * the table itself. In this case the auto-resize modes govern
3035      * the way the extra (or deficit) space is distributed
3036      * amongst the available columns.
3037      * <p>
3038      * The modes are:
3039      * <ul>
3040      * <li>  AUTO_RESIZE_OFF: Don't automatically adjust the column's
3041      * widths at all. Use a horizontal scrollbar to accommodate the
3042      * columns when their sum exceeds the width of the
3043      * {@code Viewport}.  If the {@code JTable} is not
3044      * enclosed in a {@code JScrollPane} this may
3045      * leave parts of the table invisible.
3046      * <li>  AUTO_RESIZE_NEXT_COLUMN: Use just the column after the
3047      * resizing column. This results in the "boundary" or divider
3048      * between adjacent cells being independently adjustable.
3049      * <li>  AUTO_RESIZE_SUBSEQUENT_COLUMNS: Use all columns after the
3050      * one being adjusted to absorb the changes.  This is the
3051      * default behavior.
3052      * <li>  AUTO_RESIZE_LAST_COLUMN: Automatically adjust the
3053      * size of the last column only. If the bounds of the last column
3054      * prevent the desired size from being allocated, set the
3055      * width of the last column to the appropriate limit and make
3056      * no further adjustments.
3057      * <li>  AUTO_RESIZE_ALL_COLUMNS: Spread the delta amongst all the columns
3058      * in the {@code JTable}, including the one that is being
3059      * adjusted.
3060      * </ul>
3061      * <p>
3062      * <b>Note:</b> When a {@code JTable} makes adjustments
3063      *   to the widths of the columns it respects their minimum and
3064      *   maximum values absolutely.  It is therefore possible that,
3065      *   even after this method is called, the total width of the columns
3066      *   is still not equal to the width of the table. When this happens
3067      *   the {@code JTable} does not put itself
3068      *   in AUTO_RESIZE_OFF mode to bring up a scroll bar, or break other
3069      *   commitments of its current auto-resize mode -- instead it
3070      *   allows its bounds to be set larger (or smaller) than the total of the
3071      *   column minimum or maximum, meaning, either that there
3072      *   will not be enough room to display all of the columns, or that the
3073      *   columns will not fill the {@code JTable}'s bounds.
3074      *   These respectively, result in the clipping of some columns
3075      *   or an area being painted in the {@code JTable}'s
3076      *   background color during painting.
3077      * <p>
3078      *   The mechanism for distributing the delta amongst the available
3079      *   columns is provided in a private method in the {@code JTable}
3080      *   class:
3081      * <pre>
3082      *   adjustSizes(long targetSize, final Resizable3 r, boolean inverse)
3083      * </pre>
3084      *   an explanation of which is provided in the following section.
3085      *   {@code Resizable3} is a private
3086      *   interface that allows any data structure containing a collection
3087      *   of elements with a size, preferred size, maximum size and minimum size
3088      *   to have its elements manipulated by the algorithm.
3089      *
3090      * <H3> Distributing the delta </H3>
3091      *
3092      * <H4> Overview </H4>
3093      * <P>
3094      * Call "DELTA" the difference between the target size and the
3095      * sum of the preferred sizes of the elements in r. The individual
3096      * sizes are calculated by taking the original preferred
3097      * sizes and adding a share of the DELTA - that share being based on
3098      * how far each preferred size is from its limiting bound (minimum or
3099      * maximum).
3100      *
3101      * <H4>Definition</H4>
3102      * <P>
3103      * Call the individual constraints min[i], max[i], and pref[i].
3104      * <p>
3105      * Call their respective sums: MIN, MAX, and PREF.


3121      * If (DELTA &gt; 0) we are in expand mode where:
3122      *
3123      * <PRE>
3124      *                        DELTA
3125      *          delta[i] = ------------ * (max[i] - pref[i])
3126      *                      (MAX - PREF)
3127      * </PRE>
3128      * <P>
3129      * The overall effect is that the total size moves that same percentage,
3130      * k, towards the total minimum or maximum and that percentage guarantees
3131      * accommodation of the required space, DELTA.
3132      *
3133      * <H4>Details</H4>
3134      * <P>
3135      * Naive evaluation of the formulae presented here would be subject to
3136      * the aggregated rounding errors caused by doing this operation in finite
3137      * precision (using ints). To deal with this, the multiplying factor above,
3138      * is constantly recalculated and this takes account of the rounding
3139      * errors in the previous iterations. The result is an algorithm that
3140      * produces a set of integers whose values exactly sum to the supplied
3141      * {@code targetSize}, and does so by spreading the rounding
3142      * errors evenly over the given elements.
3143      *
3144      * <H4>When the MAX and MIN bounds are hit</H4>
3145      * <P>
3146      * When {@code targetSize} is outside the [MIN, MAX] range,
3147      * the algorithm sets all sizes to their appropriate limiting value
3148      * (maximum or minimum).
3149      *
3150      */
3151     public void doLayout() {
3152         TableColumn resizingColumn = getResizingColumn();
3153         if (resizingColumn == null) {
3154             setWidthsFromPreferredWidths(false);
3155         }
3156         else {
3157             // JTable behaves like a layout manger - but one in which the
3158             // user can come along and dictate how big one of the children
3159             // (columns) is supposed to be.
3160 
3161             // A column has been resized and JTable may need to distribute
3162             // any overall delta to other columns, according to the resize mode.
3163             int columnIndex = viewIndexForColumn(resizingColumn);
3164             int delta = getWidth() - getColumnModel().getTotalColumnWidth();
3165             accommodateDelta(columnIndex, delta);
3166             delta = getWidth() - getColumnModel().getTotalColumnWidth();


3184             // Thereafter, during window resizing etc. it has to work off
3185             // the preferred sizes as usual - the idea being that, whatever
3186             // the user does, everything stays in synch and things don't jump
3187             // around.
3188             setWidthsFromPreferredWidths(true);
3189         }
3190 
3191         super.doLayout();
3192     }
3193 
3194     private TableColumn getResizingColumn() {
3195         return (tableHeader == null) ? null
3196                                      : tableHeader.getResizingColumn();
3197     }
3198 
3199     /**
3200      * Sizes the table columns to fit the available space.
3201      *
3202      * @param lastColumnOnly determines whether to resize last column only
3203      * @deprecated As of Swing version 1.0.3,
3204      * replaced by {@code doLayout()}.
3205      * @see #doLayout
3206      */
3207     @Deprecated
3208     public void sizeColumnsToFit(boolean lastColumnOnly) {
3209         int oldAutoResizeMode = autoResizeMode;
3210         setAutoResizeMode(lastColumnOnly ? AUTO_RESIZE_LAST_COLUMN
3211                                          : AUTO_RESIZE_ALL_COLUMNS);
3212         sizeColumnsToFit(-1);
3213         setAutoResizeMode(oldAutoResizeMode);
3214     }
3215 
3216     /**
3217      * Obsolete as of Java 2 platform v1.4.  Please use the
3218      * {@code doLayout()} method instead.
3219      * @param resizingColumn    the column whose resizing made this adjustment
3220      *                          necessary or -1 if there is no such column
3221      * @see  #doLayout
3222      */
3223     public void sizeColumnsToFit(int resizingColumn) {
3224         if (resizingColumn == -1) {
3225             setWidthsFromPreferredWidths(false);
3226         }
3227         else {
3228             if (autoResizeMode == AUTO_RESIZE_OFF) {
3229                 TableColumn aColumn = getColumnModel().getColumn(resizingColumn);
3230                 aColumn.setPreferredWidth(aColumn.getWidth());
3231             }
3232             else {
3233                 int delta = getWidth() - getColumnModel().getTotalColumnWidth();
3234                 accommodateDelta(resizingColumn, delta);
3235                 setWidthsFromPreferredWidths(true);
3236             }
3237         }
3238     }


3374             // In this case, lowerBound == upperBound, for all subsequent terms.
3375             int newSize;
3376             if (totalLowerBound == totalUpperBound) {
3377                 newSize = lowerBound;
3378             }
3379             else {
3380                 double f = (double)(target - totalLowerBound)/(totalUpperBound - totalLowerBound);
3381                 newSize = (int)Math.round(lowerBound+f*(upperBound - lowerBound));
3382                 // We'd need to round manually in an all integer version.
3383                 // size[i] = (int)(((totalUpperBound - target) * lowerBound +
3384                 //     (target - totalLowerBound) * upperBound)/(totalUpperBound-totalLowerBound));
3385             }
3386             r.setSizeAt(newSize, i);
3387             target -= newSize;
3388             totalLowerBound -= lowerBound;
3389             totalUpperBound -= upperBound;
3390         }
3391     }
3392 
3393     /**
3394      * Overrides {@code JComponent}'s {@code getToolTipText}
3395      * method in order to allow the renderer's tips to be used
3396      * if it has text set.
3397      * <p>
3398      * <b>Note:</b> For {@code JTable} to properly display
3399      * tooltips of its renderers
3400      * {@code JTable} must be a registered component with the
3401      * {@code ToolTipManager}.
3402      * This is done automatically in {@code initializeLocalVars},
3403      * but if at a later point {@code JTable} is told
3404      * {@code setToolTipText(null)} it will unregister the table
3405      * component, and no tips from renderers will display anymore.
3406      *
3407      * @see JComponent#getToolTipText
3408      */
3409     public String getToolTipText(MouseEvent event) {
3410         String tip = null;
3411         Point p = event.getPoint();
3412 
3413         // Locate the renderer under the event location
3414         int hitColumnIndex = columnAtPoint(p);
3415         int hitRowIndex = rowAtPoint(p);
3416 
3417         if ((hitColumnIndex != -1) && (hitRowIndex != -1)) {
3418             TableCellRenderer renderer = getCellRenderer(hitRowIndex, hitColumnIndex);
3419             Component component = prepareRenderer(renderer, hitRowIndex, hitColumnIndex);
3420 
3421             // Now have to see if the component is a JComponent before
3422             // getting the tip
3423             if (component instanceof JComponent) {
3424                 // Convert the event to the renderer's coordinate system


3466     public void setSurrendersFocusOnKeystroke(boolean surrendersFocusOnKeystroke) {
3467         this.surrendersFocusOnKeystroke = surrendersFocusOnKeystroke;
3468     }
3469 
3470     /**
3471      * Returns true if the editor should get the focus
3472      * when keystrokes cause the editor to be activated
3473      *
3474      * @return  true if the editor should get the focus
3475      *          when keystrokes cause the editor to be
3476      *          activated
3477      *
3478      * @see #setSurrendersFocusOnKeystroke
3479      * @since 1.4
3480      */
3481     public boolean getSurrendersFocusOnKeystroke() {
3482         return surrendersFocusOnKeystroke;
3483     }
3484 
3485     /**
3486      * Programmatically starts editing the cell at {@code row} and
3487      * {@code column}, if those indices are in the valid range, and
3488      * the cell at those indices is editable.
3489      * Note that this is a convenience method for
3490      * {@code editCellAt(int, int, null)}.
3491      *
3492      * @param   row                             the row to be edited
3493      * @param   column                          the column to be edited
3494      * @return  false if for any reason the cell cannot be edited,
3495      *                or if the indices are invalid
3496      */
3497     public boolean editCellAt(int row, int column) {
3498         return editCellAt(row, column, null);
3499     }
3500 
3501     /**
3502      * Programmatically starts editing the cell at {@code row} and
3503      * {@code column}, if those indices are in the valid range, and
3504      * the cell at those indices is editable.
3505      * To prevent the {@code JTable} from
3506      * editing a particular table, column or cell value, return false from
3507      * the {@code isCellEditable} method in the {@code TableModel}
3508      * interface.
3509      *
3510      * @param   row     the row to be edited
3511      * @param   column  the column to be edited
3512      * @param   e       event to pass into {@code shouldSelectCell};
3513      *                  note that as of Java 2 platform v1.2, the call to
3514      *                  {@code shouldSelectCell} is no longer made
3515      * @return  false if for any reason the cell cannot be edited,
3516      *                or if the indices are invalid
3517      */
3518     public boolean editCellAt(int row, int column, EventObject e){
3519         if (cellEditor != null && !cellEditor.stopCellEditing()) {
3520             return false;
3521         }
3522 
3523         if (row < 0 || row >= getRowCount() ||
3524             column < 0 || column >= getColumnCount()) {
3525             return false;
3526         }
3527 
3528         if (!isCellEditable(row, column))
3529             return false;
3530 
3531         if (editorRemover == null) {
3532             KeyboardFocusManager fm =
3533                 KeyboardFocusManager.getCurrentKeyboardFocusManager();
3534             editorRemover = new CellEditorRemover(fm);


3592 
3593     /**
3594      * Returns the index of the row that contains the cell currently
3595      * being edited.  If nothing is being edited, returns -1.
3596      *
3597      * @return  the index of the row that contains the cell currently
3598      *          being edited; returns -1 if nothing being edited
3599      * @see #editingColumn
3600      */
3601     public int getEditingRow() {
3602         return editingRow;
3603     }
3604 
3605 //
3606 // Managing TableUI
3607 //
3608 
3609     /**
3610      * Returns the L&amp;F object that renders this component.
3611      *
3612      * @return the {@code TableUI} object that renders this component
3613      */
3614     public TableUI getUI() {
3615         return (TableUI)ui;
3616     }
3617 
3618     /**
3619      * Sets the L&amp;F object that renders this component and repaints.
3620      *
3621      * @param ui  the TableUI L&amp;F object
3622      * @see UIDefaults#getUI
3623      * @beaninfo
3624      *        bound: true
3625      *       hidden: true
3626      *    attribute: visualUpdate true
3627      *  description: The UI object that implements the Component's LookAndFeel.
3628      */
3629     public void setUI(TableUI ui) {
3630         if (this.ui != ui) {
3631             super.setUI(ui);
3632             repaint();
3633         }
3634     }
3635 
3636     /**
3637      * Notification from the {@code UIManager} that the L&amp;F has changed.
3638      * Replaces the current UI object with the latest version from the
3639      * {@code UIManager}.
3640      *
3641      * @see JComponent#updateUI
3642      */
3643     public void updateUI() {
3644         // Update the UIs of the cell renderers, cell editors and header renderers.
3645         TableColumnModel cm = getColumnModel();
3646         for(int column = 0; column < cm.getColumnCount(); column++) {
3647             TableColumn aColumn = cm.getColumn(column);
3648             SwingUtilities.updateRendererOrEditorUI(aColumn.getCellRenderer());
3649             SwingUtilities.updateRendererOrEditorUI(aColumn.getCellEditor());
3650             SwingUtilities.updateRendererOrEditorUI(aColumn.getHeaderRenderer());
3651         }
3652 
3653         // Update the UIs of all the default renderers.
3654         Enumeration<?> defaultRenderers = defaultRenderersByColumnClass.elements();
3655         while (defaultRenderers.hasMoreElements()) {
3656             SwingUtilities.updateRendererOrEditorUI(defaultRenderers.nextElement());
3657         }
3658 
3659         // Update the UIs of all the default editors.


3812         }
3813     }
3814 
3815     /**
3816      * Returns the {@code ListSelectionModel} that is used to maintain row
3817      * selection state.
3818      *
3819      * @return the object that provides row selection state, {@code null} if row
3820      *         selection is not allowed
3821      * @see #setSelectionModel
3822      */
3823     public ListSelectionModel getSelectionModel() {
3824         return selectionModel;
3825     }
3826 
3827 //
3828 // RowSorterListener
3829 //
3830 
3831     /**
3832      * {@code RowSorterListener} notification that the
3833      * {@code RowSorter} has changed in some way.
3834      *
3835      * @param e the {@code RowSorterEvent} describing the change
3836      * @throws NullPointerException if {@code e} is {@code null}
3837      * @since 1.6
3838      */
3839     public void sorterChanged(RowSorterEvent e) {
3840         if (e.getType() == RowSorterEvent.Type.SORT_ORDER_CHANGED) {
3841             JTableHeader header = getTableHeader();
3842             if (header != null) {
3843                 header.repaint();
3844             }
3845         }
3846         else if (e.getType() == RowSorterEvent.Type.SORTED) {
3847             sorterChanged = true;
3848             if (!ignoreSortChange) {
3849                 sortedTableChanged(e, null);
3850             }
3851         }
3852     }
3853 
3854 
3855     /**
3856      * SortManager provides support for managing the selection and variable


4108         int length;
4109 
4110         // True if the event indicates all the contents have changed
4111         boolean allRowsChanged;
4112 
4113         ModelChange(TableModelEvent e) {
4114             startModelIndex = Math.max(0, e.getFirstRow());
4115             endModelIndex = e.getLastRow();
4116             modelRowCount = getModel().getRowCount();
4117             if (endModelIndex < 0) {
4118                 endModelIndex = Math.max(0, modelRowCount - 1);
4119             }
4120             length = endModelIndex - startModelIndex + 1;
4121             type = e.getType();
4122             event = e;
4123             allRowsChanged = (e.getLastRow() == Integer.MAX_VALUE);
4124         }
4125     }
4126 
4127     /**
4128      * Invoked when {@code sorterChanged} is invoked, or
4129      * when {@code tableChanged} is invoked and sorting is enabled.
4130      */
4131     private void sortedTableChanged(RowSorterEvent sortedEvent,
4132                                     TableModelEvent e) {
4133         int editingModelIndex = -1;
4134         ModelChange change = (e != null) ? new ModelChange(e) : null;
4135 
4136         if ((change == null || !change.allRowsChanged) &&
4137                 this.editingRow != -1) {
4138             editingModelIndex = convertRowIndexToModel(sortedEvent,
4139                                                        this.editingRow);
4140         }
4141 
4142         sortManager.prepareForChange(sortedEvent, change);
4143 
4144         if (e != null) {
4145             if (change.type == TableModelEvent.UPDATE) {
4146                 repaintSortedRows(change);
4147             }
4148             notifySorter(change);
4149             if (change.type != TableModelEvent.UPDATE) {


4365     private int convertRowIndexToModel(RowSorterEvent e, int viewIndex) {
4366         if (e != null) {
4367             if (e.getPreviousRowCount() == 0) {
4368                 return viewIndex;
4369             }
4370             // range checking handled by RowSorterEvent
4371             return e.convertPreviousRowIndexToModel(viewIndex);
4372         }
4373         // Make sure the viewIndex is valid
4374         if (viewIndex < 0 || viewIndex >= getRowCount()) {
4375             return -1;
4376         }
4377         return convertRowIndexToModel(viewIndex);
4378     }
4379 
4380 //
4381 // Implementing TableModelListener interface
4382 //
4383 
4384     /**
4385      * Invoked when this table's {@code TableModel} generates
4386      * a {@code TableModelEvent}.
4387      * The {@code TableModelEvent} should be constructed in the
4388      * coordinate system of the model; the appropriate mapping to the
4389      * view coordinate system is performed by this {@code JTable}
4390      * when it receives the event.
4391      * <p>
4392      * Application code will not use these methods explicitly, they
4393      * are used internally by {@code JTable}.
4394      * <p>
4395      * Note that as of 1.3, this method clears the selection, if any.
4396      */
4397     public void tableChanged(TableModelEvent e) {
4398         if (e == null || e.getFirstRow() == TableModelEvent.HEADER_ROW) {
4399             // The whole thing changed
4400             clearSelectionAndLeadAnchor();
4401 
4402             rowModel = null;
4403 
4404             if (sortManager != null) {
4405                 try {
4406                     ignoreSortChange = true;
4407                     sortManager.sorter.modelStructureChanged();
4408                 } finally {
4409                     ignoreSortChange = false;
4410                 }
4411                 sortManager.allChanged();
4412             }
4413 


4624      * @see TableColumnModelListener
4625      */
4626     public void columnMarginChanged(ChangeEvent e) {
4627         if (isEditing() && !getCellEditor().stopCellEditing()) {
4628             getCellEditor().cancelCellEditing();
4629         }
4630         TableColumn resizingColumn = getResizingColumn();
4631         // Need to do this here, before the parent's
4632         // layout manager calls getPreferredSize().
4633         if (resizingColumn != null && autoResizeMode == AUTO_RESIZE_OFF) {
4634             resizingColumn.setPreferredWidth(resizingColumn.getWidth());
4635         }
4636         resizeAndRepaint();
4637     }
4638 
4639     private int limit(int i, int a, int b) {
4640         return Math.min(b, Math.max(i, a));
4641     }
4642 
4643     /**
4644      * Invoked when the selection model of the {@code TableColumnModel}
4645      * is changed.
4646      * <p>
4647      * Application code will not use these methods explicitly, they
4648      * are used internally by JTable.
4649      *
4650      * @param  e  the event received
4651      * @see TableColumnModelListener
4652      */
4653     public void columnSelectionChanged(ListSelectionEvent e) {
4654         boolean isAdjusting = e.getValueIsAdjusting();
4655         if (columnSelectionAdjusting && !isAdjusting) {
4656             // The assumption is that when the model is no longer adjusting
4657             // we will have already gotten all the changes, and therefore
4658             // don't need to do an additional paint.
4659             columnSelectionAdjusting = false;
4660             return;
4661         }
4662         columnSelectionAdjusting = isAdjusting;
4663         // The getCellRect() call will fail unless there is at least one row.
4664         if (getRowCount() <= 0 || getColumnCount() <= 0) {


4764      * Invoked when editing is canceled. The editor object is discarded
4765      * and the cell is rendered once again.
4766      * <p>
4767      * Application code will not use these methods explicitly, they
4768      * are used internally by JTable.
4769      *
4770      * @param  e  the event received
4771      * @see CellEditorListener
4772      */
4773     public void editingCanceled(ChangeEvent e) {
4774         removeEditor();
4775     }
4776 
4777 //
4778 // Implementing the Scrollable interface
4779 //
4780 
4781     /**
4782      * Sets the preferred size of the viewport for this table.
4783      *
4784      * @param size  a {@code Dimension} object specifying the {@code preferredSize} of a
4785      *              {@code JViewport} whose view is this table
4786      * @see Scrollable#getPreferredScrollableViewportSize
4787      * @beaninfo
4788      * description: The preferred size of the viewport.
4789      */
4790     public void setPreferredScrollableViewportSize(Dimension size) {
4791         preferredViewportSize = size;
4792     }
4793 
4794     /**
4795      * Returns the preferred size of the viewport for this table.
4796      *
4797      * @return a {@code Dimension} object containing the {@code preferredSize} of the {@code JViewport}
4798      *         which displays this table
4799      * @see Scrollable#getPreferredScrollableViewportSize
4800      */
4801     public Dimension getPreferredScrollableViewportSize() {
4802         return preferredViewportSize;
4803     }
4804 
4805     /**
4806      * Returns the scroll increment (in pixels) that completely exposes one new
4807      * row or column (depending on the orientation).
4808      * <p>
4809      * This method is called each time the user requests a unit scroll.
4810      *
4811      * @param visibleRect the view area visible within the viewport
4812      * @param orientation either {@code SwingConstants.VERTICAL}
4813      *                  or {@code SwingConstants.HORIZONTAL}
4814      * @param direction less than zero to scroll up/left,
4815      *                  greater than zero for down/right
4816      * @return the "unit" increment for scrolling in the specified direction
4817      * @see Scrollable#getScrollableUnitIncrement
4818      */
4819     public int getScrollableUnitIncrement(Rectangle visibleRect,
4820                                           int orientation,
4821                                           int direction) {
4822         int leadingRow;
4823         int leadingCol;
4824         Rectangle leadingCellRect;
4825 
4826         int leadingVisibleEdge;
4827         int leadingCellEdge;
4828         int leadingCellSize;
4829 
4830         leadingRow = getLeadingRow(visibleRect);
4831         leadingCol = getLeadingCol(visibleRect);
4832         if (orientation == SwingConstants.VERTICAL && leadingRow < 0) {
4833             // Couldn't find leading row - return some default value


4888             else { // Case #2: hide leading cell
4889                 return leadingCellSize;
4890             }
4891         }
4892         else { // Leading cell is partially hidden
4893             // Compute visible, hidden portions
4894             int hiddenAmt = Math.abs(leadingVisibleEdge - leadingCellEdge);
4895             int visibleAmt = leadingCellSize - hiddenAmt;
4896 
4897             if (direction > 0) {
4898                 // Case #3: hide showing portion of leading cell
4899                 return visibleAmt;
4900             }
4901             else { // Case #4: reveal hidden portion of leading cell
4902                 return hiddenAmt;
4903             }
4904         }
4905     }
4906 
4907     /**
4908      * Returns {@code visibleRect.height} or
4909      * {@code visibleRect.width},
4910      * depending on this table's orientation.  Note that as of Swing 1.1.1
4911      * (Java 2 v 1.2.2) the value
4912      * returned will ensure that the viewport is cleanly aligned on
4913      * a row boundary.
4914      *
4915      * @return {@code visibleRect.height} or
4916      *                                  {@code visibleRect.width}
4917      *                                  per the orientation
4918      * @see Scrollable#getScrollableBlockIncrement
4919      */
4920     public int getScrollableBlockIncrement(Rectangle visibleRect,
4921             int orientation, int direction) {
4922 
4923         if (getRowCount() == 0) {
4924             // Short-circuit empty table model
4925             if (SwingConstants.VERTICAL == orientation) {
4926                 int rh = getRowHeight();
4927                 return (rh > 0) ? Math.max(rh, (visibleRect.height / rh) * rh) :
4928                                   visibleRect.height;
4929             }
4930             else {
4931                 return visibleRect.width;
4932             }
4933         }
4934         // Shortcut for vertical scrolling of a table w/ uniform row height
4935         if (null == rowModel && SwingConstants.VERTICAL == orientation) {
4936             int row = rowAtPoint(visibleRect.getLocation());


5196     }
5197 
5198     /*
5199      * Returns the trailing edge ("end") of the given Rectangle.
5200      * For VERTICAL, this is the bottom, for left-to-right, the right side, and
5201      * for right-to-left, the left side.
5202      */
5203     private int trailingEdge(Rectangle rect, int orientation) {
5204         if (orientation == SwingConstants.VERTICAL) {
5205             return rect.y + rect.height;
5206         }
5207         else if (getComponentOrientation().isLeftToRight()) {
5208             return rect.x + rect.width;
5209         }
5210         else { // Horizontal, right-to-left
5211             return rect.x;
5212         }
5213     }
5214 
5215     /**
5216      * Returns false if {@code autoResizeMode} is set to
5217      * {@code AUTO_RESIZE_OFF}, which indicates that the
5218      * width of the viewport does not determine the width
5219      * of the table.  Otherwise returns true.
5220      *
5221      * @return false if {@code autoResizeMode} is set
5222      *   to {@code AUTO_RESIZE_OFF}, otherwise returns true
5223      * @see Scrollable#getScrollableTracksViewportWidth
5224      */
5225     public boolean getScrollableTracksViewportWidth() {
5226         return !(autoResizeMode == AUTO_RESIZE_OFF);
5227     }
5228 
5229     /**
5230      * Returns {@code false} to indicate that the height of the viewport does
5231      * not determine the height of the table, unless
5232      * {@code getFillsViewportHeight} is {@code true} and the preferred height
5233      * of the table is smaller than the viewport's height.
5234      *
5235      * @return {@code false} unless {@code getFillsViewportHeight} is
5236      *         {@code true} and the table needs to be stretched to fill
5237      *         the viewport
5238      * @see Scrollable#getScrollableTracksViewportHeight
5239      * @see #setFillsViewportHeight
5240      * @see #getFillsViewportHeight
5241      */
5242     public boolean getScrollableTracksViewportHeight() {


5572         setAutoResizeMode(AUTO_RESIZE_SUBSEQUENT_COLUMNS);
5573         setRowHeight(16);
5574         isRowHeightSet = false;
5575         setRowMargin(1);
5576         setRowSelectionAllowed(true);
5577         setCellEditor(null);
5578         setEditingColumn(-1);
5579         setEditingRow(-1);
5580         setSurrendersFocusOnKeystroke(false);
5581         setPreferredScrollableViewportSize(new Dimension(450, 400));
5582 
5583         // I'm registered to do tool tips so we can draw tips for the renderers
5584         ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
5585         toolTipManager.registerComponent(this);
5586 
5587         setAutoscrolls(true);
5588     }
5589 
5590     /**
5591      * Returns the default table model object, which is
5592      * a {@code DefaultTableModel}.  A subclass can override this
5593      * method to return a different table model object.
5594      *
5595      * @return the default table model object
5596      * @see javax.swing.table.DefaultTableModel
5597      */
5598     protected TableModel createDefaultDataModel() {
5599         return new DefaultTableModel();
5600     }
5601 
5602     /**
5603      * Returns the default column model object, which is
5604      * a {@code DefaultTableColumnModel}.  A subclass can override this
5605      * method to return a different column model object.
5606      *
5607      * @return the default column model object
5608      * @see javax.swing.table.DefaultTableColumnModel
5609      */
5610     protected TableColumnModel createDefaultColumnModel() {
5611         return new DefaultTableColumnModel();
5612     }
5613 
5614     /**
5615      * Returns the default selection model object, which is
5616      * a {@code DefaultListSelectionModel}.  A subclass can override this
5617      * method to return a different selection model object.
5618      *
5619      * @return the default selection model object
5620      * @see javax.swing.DefaultListSelectionModel
5621      */
5622     protected ListSelectionModel createDefaultSelectionModel() {
5623         return new DefaultListSelectionModel();
5624     }
5625 
5626     /**
5627      * Returns the default table header object, which is
5628      * a {@code JTableHeader}.  A subclass can override this
5629      * method to return a different table header object.
5630      *
5631      * @return the default table header object
5632      * @see javax.swing.table.JTableHeader
5633      */
5634     protected JTableHeader createDefaultTableHeader() {
5635         return new JTableHeader(columnModel);
5636     }
5637 
5638     /**
5639      * Equivalent to {@code revalidate} followed by {@code repaint}.
5640      */
5641     protected void resizeAndRepaint() {
5642         revalidate();
5643         repaint();
5644     }
5645 
5646     /**
5647      * Returns the active cell editor, which is {@code null} if the table
5648      * is not currently editing.
5649      *
5650      * @return the {@code TableCellEditor} that does the editing,
5651      *         or {@code null} if the table is not currently editing.
5652      * @see #cellEditor
5653      * @see #getCellEditor(int, int)
5654      */
5655     public TableCellEditor getCellEditor() {
5656         return cellEditor;
5657     }
5658 
5659     /**
5660      * Sets the active cell editor.
5661      *
5662      * @param anEditor the active cell editor
5663      * @see #cellEditor
5664      * @beaninfo
5665      *  bound: true
5666      *  description: The table's active cell editor.
5667      */
5668     public void setCellEditor(TableCellEditor anEditor) {
5669         TableCellEditor oldEditor = cellEditor;
5670         cellEditor = anEditor;
5671         firePropertyChange("tableCellEditor", oldEditor, anEditor);
5672     }
5673 
5674     /**
5675      * Sets the {@code editingColumn} variable.
5676      * @param aColumn  the column of the cell to be edited
5677      *
5678      * @see #editingColumn
5679      */
5680     public void setEditingColumn(int aColumn) {
5681         editingColumn = aColumn;
5682     }
5683 
5684     /**
5685      * Sets the {@code editingRow} variable.
5686      * @param aRow  the row of the cell to be edited
5687      *
5688      * @see #editingRow
5689      */
5690     public void setEditingRow(int aRow) {
5691         editingRow = aRow;
5692     }
5693 
5694     /**
5695      * Returns an appropriate renderer for the cell specified by this row and
5696      * column. If the {@code TableColumn} for this column has a non-null
5697      * renderer, returns that.  If not, finds the class of the data in
5698      * this column (using {@code getColumnClass})
5699      * and returns the default renderer for this type of data.
5700      * <p>
5701      * <b>Note:</b>
5702      * Throughout the table package, the internal implementations always
5703      * use this method to provide renderers so that this default behavior
5704      * can be safely overridden by a subclass.
5705      *
5706      * @param row       the row of the cell to render, where 0 is the first row
5707      * @param column    the column of the cell to render,
5708      *                  where 0 is the first column
5709      * @return the assigned renderer; if {@code null}
5710      *                  returns the default renderer
5711      *                  for this type of object
5712      * @see javax.swing.table.DefaultTableCellRenderer
5713      * @see javax.swing.table.TableColumn#setCellRenderer
5714      * @see #setDefaultRenderer
5715      */
5716     public TableCellRenderer getCellRenderer(int row, int column) {
5717         TableColumn tableColumn = getColumnModel().getColumn(column);
5718         TableCellRenderer renderer = tableColumn.getCellRenderer();
5719         if (renderer == null) {
5720             renderer = getDefaultRenderer(getColumnClass(column));
5721         }
5722         return renderer;
5723     }
5724 
5725     /**
5726      * Prepares the renderer by querying the data model for the
5727      * value and selection state
5728      * of the cell at {@code row}, {@code column}.
5729      * Returns the component (may be a {@code Component}
5730      * or a {@code JComponent}) under the event location.
5731      * <p>
5732      * During a printing operation, this method will configure the
5733      * renderer without indicating selection or focus, to prevent
5734      * them from appearing in the printed output. To do other
5735      * customizations based on whether or not the table is being
5736      * printed, you can check the value of
5737      * {@link javax.swing.JComponent#isPaintingForPrint()}, either here
5738      * or within custom renderers.
5739      * <p>
5740      * <b>Note:</b>
5741      * Throughout the table package, the internal implementations always
5742      * use this method to prepare renderers so that this default behavior
5743      * can be safely overridden by a subclass.
5744      *
5745      * @param renderer  the {@code TableCellRenderer} to prepare
5746      * @param row       the row of the cell to render, where 0 is the first row
5747      * @param column    the column of the cell to render,
5748      *                  where 0 is the first column
5749      * @return          the {@code Component} under the event location
5750      */
5751     public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
5752         Object value = getValueAt(row, column);
5753 
5754         boolean isSelected = false;
5755         boolean hasFocus = false;
5756 
5757         // Only indicate the selection and focused cell if not printing
5758         if (!isPaintingForPrint()) {
5759             isSelected = isCellSelected(row, column);
5760 
5761             boolean rowIsLead =
5762                 (selectionModel.getLeadSelectionIndex() == row);
5763             boolean colIsLead =
5764                 (columnModel.getSelectionModel().getLeadSelectionIndex() == column);
5765 
5766             hasFocus = (rowIsLead && colIsLead) && isFocusOwner();
5767         }
5768 
5769         return renderer.getTableCellRendererComponent(this, value,
5770                                                       isSelected, hasFocus,
5771                                                       row, column);
5772     }
5773 
5774     /**
5775      * Returns an appropriate editor for the cell specified by
5776      * {@code row} and {@code column}. If the
5777      * {@code TableColumn} for this column has a non-null editor,
5778      * returns that.  If not, finds the class of the data in this
5779      * column (using {@code getColumnClass})
5780      * and returns the default editor for this type of data.
5781      * <p>
5782      * <b>Note:</b>
5783      * Throughout the table package, the internal implementations always
5784      * use this method to provide editors so that this default behavior
5785      * can be safely overridden by a subclass.
5786      *
5787      * @param row       the row of the cell to edit, where 0 is the first row
5788      * @param column    the column of the cell to edit,
5789      *                  where 0 is the first column
5790      * @return          the editor for this cell;
5791      *                  if {@code null} return the default editor for
5792      *                  this type of cell
5793      * @see DefaultCellEditor
5794      */
5795     public TableCellEditor getCellEditor(int row, int column) {
5796         TableColumn tableColumn = getColumnModel().getColumn(column);
5797         TableCellEditor editor = tableColumn.getCellEditor();
5798         if (editor == null) {
5799             editor = getDefaultEditor(getColumnClass(column));
5800         }
5801         return editor;
5802     }
5803 
5804 
5805     /**
5806      * Prepares the editor by querying the data model for the value and
5807      * selection state of the cell at {@code row}, {@code column}.
5808      * <p>
5809      * <b>Note:</b>
5810      * Throughout the table package, the internal implementations always
5811      * use this method to prepare editors so that this default behavior
5812      * can be safely overridden by a subclass.
5813      *
5814      * @param editor  the {@code TableCellEditor} to set up
5815      * @param row     the row of the cell to edit,
5816      *                where 0 is the first row
5817      * @param column  the column of the cell to edit,
5818      *                where 0 is the first column
5819      * @return the {@code Component} being edited
5820      */
5821     @SuppressWarnings("deprecation")
5822     public Component prepareEditor(TableCellEditor editor, int row, int column) {
5823         Object value = getValueAt(row, column);
5824         boolean isSelected = isCellSelected(row, column);
5825         Component comp = editor.getTableCellEditorComponent(this, value, isSelected,
5826                                                   row, column);
5827         if (comp instanceof JComponent) {
5828             JComponent jComp = (JComponent)comp;
5829             if (jComp.getNextFocusableComponent() == null) {
5830                 jComp.setNextFocusableComponent(this);
5831             }
5832         }
5833         return comp;
5834     }
5835 
5836     /**
5837      * Discards the editor object and frees the real estate it used for
5838      * cell rendering.
5839      */


5972          }
5973     }
5974 
5975     /* Called from the JComponent's EnableSerializationFocusListener to
5976      * do any Swing-specific pre-serialization configuration.
5977      */
5978     void compWriteObjectNotify() {
5979         super.compWriteObjectNotify();
5980         // If ToolTipText != null, then the tooltip has already been
5981         // unregistered by JComponent.compWriteObjectNotify()
5982         if (getToolTipText() == null) {
5983             ToolTipManager.sharedInstance().unregisterComponent(this);
5984         }
5985     }
5986 
5987     /**
5988      * Returns a string representation of this table. This method
5989      * is intended to be used only for debugging purposes, and the
5990      * content and format of the returned string may vary between
5991      * implementations. The returned string may be empty but may not
5992      * be {@code null}.
5993      *
5994      * @return  a string representation of this table
5995      */
5996     protected String paramString() {
5997         String gridColorString = (gridColor != null ?
5998                                   gridColor.toString() : "");
5999         String showHorizontalLinesString = (showHorizontalLines ?
6000                                             "true" : "false");
6001         String showVerticalLinesString = (showVerticalLines ?
6002                                           "true" : "false");
6003         String autoResizeModeString;
6004         if (autoResizeMode == AUTO_RESIZE_OFF) {
6005             autoResizeModeString = "AUTO_RESIZE_OFF";
6006         } else if (autoResizeMode == AUTO_RESIZE_NEXT_COLUMN) {
6007             autoResizeModeString = "AUTO_RESIZE_NEXT_COLUMN";
6008         } else if (autoResizeMode == AUTO_RESIZE_SUBSEQUENT_COLUMNS) {
6009             autoResizeModeString = "AUTO_RESIZE_SUBSEQUENT_COLUMNS";
6010         } else if (autoResizeMode == AUTO_RESIZE_LAST_COLUMN) {
6011             autoResizeModeString = "AUTO_RESIZE_LAST_COLUMN";
6012         } else if (autoResizeMode == AUTO_RESIZE_ALL_COLUMNS)  {


6069                 } else if ((c instanceof Window) ||
6070                            (c instanceof Applet && c.getParent() == null)) {
6071                     if (c == SwingUtilities.getRoot(JTable.this)) {
6072                         if (!getCellEditor().stopCellEditing()) {
6073                             getCellEditor().cancelCellEditing();
6074                         }
6075                     }
6076                     break;
6077                 }
6078                 c = c.getParent();
6079             }
6080         }
6081     }
6082 
6083 /////////////////
6084 // Printing Support
6085 /////////////////
6086 
6087     /**
6088      * A convenience method that displays a printing dialog, and then prints
6089      * this {@code JTable} in mode {@code PrintMode.FIT_WIDTH},
6090      * with no header or footer text. A modal progress dialog, with an abort
6091      * option, will be shown for the duration of printing.
6092      * <p>
6093      * Note: In headless mode, no dialogs are shown and printing
6094      * occurs on the default printer.
6095      *
6096      * @return true, unless printing is cancelled by the user
6097      * @throws SecurityException if this thread is not allowed to
6098      *                           initiate a print job request
6099      * @throws PrinterException if an error in the print system causes the job
6100      *                          to be aborted
6101      * @see #print(JTable.PrintMode, MessageFormat, MessageFormat,
6102      *             boolean, PrintRequestAttributeSet, boolean, PrintService)
6103      * @see #getPrintable
6104      *
6105      * @since 1.5
6106      */
6107     public boolean print() throws PrinterException {
6108 
6109         return print(PrintMode.FIT_WIDTH);
6110     }
6111 
6112     /**
6113      * A convenience method that displays a printing dialog, and then prints
6114      * this {@code JTable} in the given printing mode,
6115      * with no header or footer text. A modal progress dialog, with an abort
6116      * option, will be shown for the duration of printing.
6117      * <p>
6118      * Note: In headless mode, no dialogs are shown and printing
6119      * occurs on the default printer.
6120      *
6121      * @param  printMode        the printing mode that the printable should use
6122      * @return true, unless printing is cancelled by the user
6123      * @throws SecurityException if this thread is not allowed to
6124      *                           initiate a print job request
6125      * @throws PrinterException if an error in the print system causes the job
6126      *                          to be aborted
6127      * @see #print(JTable.PrintMode, MessageFormat, MessageFormat,
6128      *             boolean, PrintRequestAttributeSet, boolean, PrintService)
6129      * @see #getPrintable
6130      *
6131      * @since 1.5
6132      */
6133     public boolean print(PrintMode printMode) throws PrinterException {
6134 
6135         return print(printMode, null, null);
6136     }
6137 
6138     /**
6139      * A convenience method that displays a printing dialog, and then prints
6140      * this {@code JTable} in the given printing mode,
6141      * with the specified header and footer text. A modal progress dialog,
6142      * with an abort option, will be shown for the duration of printing.
6143      * <p>
6144      * Note: In headless mode, no dialogs are shown and printing
6145      * occurs on the default printer.
6146      *
6147      * @param  printMode        the printing mode that the printable should use
6148      * @param  headerFormat     a {@code MessageFormat} specifying the text
6149      *                          to be used in printing a header,
6150      *                          or null for none
6151      * @param  footerFormat     a {@code MessageFormat} specifying the text
6152      *                          to be used in printing a footer,
6153      *                          or null for none
6154      * @return true, unless printing is cancelled by the user
6155      * @throws SecurityException if this thread is not allowed to
6156      *                           initiate a print job request
6157      * @throws PrinterException if an error in the print system causes the job
6158      *                          to be aborted
6159      * @see #print(JTable.PrintMode, MessageFormat, MessageFormat,
6160      *             boolean, PrintRequestAttributeSet, boolean, PrintService)
6161      * @see #getPrintable
6162      *
6163      * @since 1.5
6164      */
6165     public boolean print(PrintMode printMode,
6166                          MessageFormat headerFormat,
6167                          MessageFormat footerFormat) throws PrinterException {
6168 
6169         boolean showDialogs = !GraphicsEnvironment.isHeadless();
6170         return print(printMode, headerFormat, footerFormat,
6171                      showDialogs, null, showDialogs);
6172     }
6173 
6174     /**
6175      * Prints this table, as specified by the fully featured
6176      * {@link #print(JTable.PrintMode, MessageFormat, MessageFormat,
6177      * boolean, PrintRequestAttributeSet, boolean, PrintService) print}
6178      * method, with the default printer specified as the print service.
6179      *
6180      * @param  printMode        the printing mode that the printable should use
6181      * @param  headerFormat     a {@code MessageFormat} specifying the text
6182      *                          to be used in printing a header,
6183      *                          or {@code null} for none
6184      * @param  footerFormat     a {@code MessageFormat} specifying the text
6185      *                          to be used in printing a footer,
6186      *                          or {@code null} for none
6187      * @param  showPrintDialog  whether or not to display a print dialog
6188      * @param  attr             a {@code PrintRequestAttributeSet}
6189      *                          specifying any printing attributes,
6190      *                          or {@code null} for none
6191      * @param  interactive      whether or not to print in an interactive mode
6192      * @return true, unless printing is cancelled by the user
6193      * @throws HeadlessException if the method is asked to show a printing
6194      *                           dialog or run interactively, and
6195      *                           {@code GraphicsEnvironment.isHeadless}
6196      *                           returns {@code true}
6197      * @throws SecurityException if this thread is not allowed to
6198      *                           initiate a print job request
6199      * @throws PrinterException if an error in the print system causes the job
6200      *                          to be aborted
6201      * @see #print(JTable.PrintMode, MessageFormat, MessageFormat,
6202      *             boolean, PrintRequestAttributeSet, boolean, PrintService)
6203      * @see #getPrintable
6204      *
6205      * @since 1.5
6206      */
6207     public boolean print(PrintMode printMode,
6208                          MessageFormat headerFormat,
6209                          MessageFormat footerFormat,
6210                          boolean showPrintDialog,
6211                          PrintRequestAttributeSet attr,
6212                          boolean interactive) throws PrinterException,
6213                                                      HeadlessException {
6214 
6215         return print(printMode,
6216                      headerFormat,
6217                      footerFormat,
6218                      showPrintDialog,
6219                      attr,
6220                      interactive,
6221                      null);
6222     }
6223 
6224     /**
6225      * Prints this {@code JTable}. Takes steps that the majority of
6226      * developers would take in order to print a {@code JTable}.
6227      * In short, it prepares the table, calls {@code getPrintable} to
6228      * fetch an appropriate {@code Printable}, and then sends it to the
6229      * printer.
6230      * <p>
6231      * A {@code boolean} parameter allows you to specify whether or not
6232      * a printing dialog is displayed to the user. When it is, the user may
6233      * use the dialog to change the destination printer or printing attributes,
6234      * or even to cancel the print. Another two parameters allow for a
6235      * {@code PrintService} and printing attributes to be specified.
6236      * These parameters can be used either to provide initial values for the
6237      * print dialog, or to specify values when the dialog is not shown.
6238      * <p>
6239      * A second {@code boolean} parameter allows you to specify whether
6240      * or not to perform printing in an interactive mode. If {@code true},
6241      * a modal progress dialog, with an abort option, is displayed for the
6242      * duration of printing . This dialog also prevents any user action which
6243      * may affect the table. However, it can not prevent the table from being
6244      * modified by code (for example, another thread that posts updates using
6245      * {@code SwingUtilities.invokeLater}). It is therefore the
6246      * responsibility of the developer to ensure that no other code modifies
6247      * the table in any way during printing (invalid modifications include
6248      * changes in: size, renderers, or underlying data). Printing behavior is
6249      * undefined when the table is changed during printing.
6250      * <p>
6251      * If {@code false} is specified for this parameter, no dialog will
6252      * be displayed and printing will begin immediately on the event-dispatch
6253      * thread. This blocks any other events, including repaints, from being
6254      * processed until printing is complete. Although this effectively prevents
6255      * the table from being changed, it doesn't provide a good user experience.
6256      * For this reason, specifying {@code false} is only recommended when
6257      * printing from an application with no visible GUI.
6258      * <p>
6259      * Note: Attempting to show the printing dialog or run interactively, while
6260      * in headless mode, will result in a {@code HeadlessException}.
6261      * <p>
6262      * Before fetching the printable, this method will gracefully terminate
6263      * editing, if necessary, to prevent an editor from showing in the printed
6264      * result. Additionally, {@code JTable} will prepare its renderers
6265      * during printing such that selection and focus are not indicated.
6266      * As far as customizing further how the table looks in the printout,
6267      * developers can provide custom renderers or paint code that conditionalize
6268      * on the value of {@link javax.swing.JComponent#isPaintingForPrint()}.
6269      * <p>
6270      * See {@link #getPrintable} for more description on how the table is
6271      * printed.
6272      *
6273      * @param  printMode        the printing mode that the printable should use
6274      * @param  headerFormat     a {@code MessageFormat} specifying the text
6275      *                          to be used in printing a header,
6276      *                          or {@code null} for none
6277      * @param  footerFormat     a {@code MessageFormat} specifying the text
6278      *                          to be used in printing a footer,
6279      *                          or {@code null} for none
6280      * @param  showPrintDialog  whether or not to display a print dialog
6281      * @param  attr             a {@code PrintRequestAttributeSet}
6282      *                          specifying any printing attributes,
6283      *                          or {@code null} for none
6284      * @param  interactive      whether or not to print in an interactive mode
6285      * @param  service          the destination {@code PrintService},
6286      *                          or {@code null} to use the default printer
6287      * @return true, unless printing is cancelled by the user
6288      * @throws HeadlessException if the method is asked to show a printing
6289      *                           dialog or run interactively, and
6290      *                           {@code GraphicsEnvironment.isHeadless}
6291      *                           returns {@code true}
6292      * @throws  SecurityException if a security manager exists and its
6293      *          {@link java.lang.SecurityManager#checkPrintJobAccess}
6294      *          method disallows this thread from creating a print job request
6295      * @throws PrinterException if an error in the print system causes the job
6296      *                          to be aborted
6297      * @see #getPrintable
6298      * @see java.awt.GraphicsEnvironment#isHeadless
6299      *
6300      * @since 1.6
6301      */
6302     public boolean print(PrintMode printMode,
6303                          MessageFormat headerFormat,
6304                          MessageFormat footerFormat,
6305                          boolean showPrintDialog,
6306                          PrintRequestAttributeSet attr,
6307                          boolean interactive,
6308                          PrintService service) throws PrinterException,
6309                                                       HeadlessException {
6310 
6311         // complain early if an invalid parameter is specified for headless mode


6419             // a subclass of PrinterException meaning the job was aborted,
6420             // in this case, by the user
6421             if (pe instanceof PrinterAbortException) {
6422                 return false;
6423             } else if (pe instanceof PrinterException) {
6424                 throw (PrinterException)pe;
6425             } else if (pe instanceof RuntimeException) {
6426                 throw (RuntimeException)pe;
6427             } else if (pe instanceof Error) {
6428                 throw (Error)pe;
6429             }
6430 
6431             // can not happen
6432             throw new AssertionError(pe);
6433         }
6434 
6435         return true;
6436     }
6437 
6438     /**
6439      * Return a {@code Printable} for use in printing this JTable.
6440      * <p>
6441      * This method is meant for those wishing to customize the default
6442      * {@code Printable} implementation used by {@code JTable}'s
6443      * {@code print} methods. Developers wanting simply to print the table
6444      * should use one of those methods directly.
6445      * <p>
6446      * The {@code Printable} can be requested in one of two printing modes.
6447      * In both modes, it spreads table rows naturally in sequence across
6448      * multiple pages, fitting as many rows as possible per page.
6449      * {@code PrintMode.NORMAL} specifies that the table be
6450      * printed at its current size. In this mode, there may be a need to spread
6451      * columns across pages in a similar manner to that of the rows. When the
6452      * need arises, columns are distributed in an order consistent with the
6453      * table's {@code ComponentOrientation}.
6454      * {@code PrintMode.FIT_WIDTH} specifies that the output be
6455      * scaled smaller, if necessary, to fit the table's entire width
6456      * (and thereby all columns) on each page. Width and height are scaled
6457      * equally, maintaining the aspect ratio of the output.
6458      * <p>
6459      * The {@code Printable} heads the portion of table on each page
6460      * with the appropriate section from the table's {@code JTableHeader},
6461      * if it has one.
6462      * <p>
6463      * Header and footer text can be added to the output by providing
6464      * {@code MessageFormat} arguments. The printing code requests
6465      * Strings from the formats, providing a single item which may be included
6466      * in the formatted string: an {@code Integer} representing the current
6467      * page number.
6468      * <p>
6469      * You are encouraged to read the documentation for
6470      * {@code MessageFormat} as some characters, such as single-quote,
6471      * are special and need to be escaped.
6472      * <p>
6473      * Here's an example of creating a {@code MessageFormat} that can be
6474      * used to print "Duke's Table: Page - " and the current page number:
6475      *
6476      * <pre>
6477      *     // notice the escaping of the single quote
6478      *     // notice how the page number is included with "{0}"
6479      *     MessageFormat format = new MessageFormat("Duke''s Table: Page - {0}");
6480      * </pre>
6481      * <p>
6482      * The {@code Printable} constrains what it draws to the printable
6483      * area of each page that it prints. Under certain circumstances, it may
6484      * find it impossible to fit all of a page's content into that area. In
6485      * these cases the output may be clipped, but the implementation
6486      * makes an effort to do something reasonable. Here are a few situations
6487      * where this is known to occur, and how they may be handled by this
6488      * particular implementation:
6489      * <ul>
6490      *   <li>In any mode, when the header or footer text is too wide to fit
6491      *       completely in the printable area -- print as much of the text as
6492      *       possible starting from the beginning, as determined by the table's
6493      *       {@code ComponentOrientation}.
6494      *   <li>In any mode, when a row is too tall to fit in the
6495      *       printable area -- print the upper-most portion of the row
6496      *       and paint no lower border on the table.
6497      *   <li>In {@code PrintMode.NORMAL} when a column
6498      *       is too wide to fit in the printable area -- print the center
6499      *       portion of the column and leave the left and right borders
6500      *       off the table.
6501      * </ul>
6502      * <p>
6503      * It is entirely valid for this {@code Printable} to be wrapped
6504      * inside another in order to create complex reports and documents. You may
6505      * even request that different pages be rendered into different sized
6506      * printable areas. The implementation must be prepared to handle this
6507      * (possibly by doing its layout calculations on the fly). However,
6508      * providing different heights to each page will likely not work well
6509      * with {@code PrintMode.NORMAL} when it has to spread columns
6510      * across pages.
6511      * <p>
6512      * As far as customizing how the table looks in the printed result,
6513      * {@code JTable} itself will take care of hiding the selection
6514      * and focus during printing. For additional customizations, your
6515      * renderers or painting code can customize the look based on the value
6516      * of {@link javax.swing.JComponent#isPaintingForPrint()}
6517      * <p>
6518      * Also, <i>before</i> calling this method you may wish to <i>first</i>
6519      * modify the state of the table, such as to cancel cell editing or
6520      * have the user size the table appropriately. However, you must not
6521      * modify the state of the table <i>after</i> this {@code Printable}
6522      * has been fetched (invalid modifications include changes in size or
6523      * underlying data). The behavior of the returned {@code Printable}
6524      * is undefined once the table has been changed.
6525      *
6526      * @param  printMode     the printing mode that the printable should use
6527      * @param  headerFormat  a {@code MessageFormat} specifying the text to
6528      *                       be used in printing a header, or null for none
6529      * @param  footerFormat  a {@code MessageFormat} specifying the text to
6530      *                       be used in printing a footer, or null for none
6531      * @return a {@code Printable} for printing this JTable
6532      * @see #print(JTable.PrintMode, MessageFormat, MessageFormat,
6533      *             boolean, PrintRequestAttributeSet, boolean)
6534      * @see Printable
6535      * @see PrinterJob
6536      *
6537      * @since 1.5
6538      */
6539     public Printable getPrintable(PrintMode printMode,
6540                                   MessageFormat headerFormat,
6541                                   MessageFormat footerFormat) {
6542 
6543         return new TablePrintable(this, printMode, headerFormat, footerFormat);
6544     }
6545 
6546 
6547     /**
6548      * A {@code Printable} implementation that wraps another
6549      * {@code Printable}, making it safe for printing on another thread.
6550      */
6551     private class ThreadSafePrintable implements Printable {
6552 
6553         /** The delegate {@code Printable}. */
6554         private Printable printDelegate;
6555 
6556         /**
6557          * To communicate any return value when delegating.
6558          */
6559         private int retVal;
6560 
6561         /**
6562          * To communicate any {@code Throwable} when delegating.
6563          */
6564         private Throwable retThrowable;
6565 
6566         /**
6567          * Construct a {@code ThreadSafePrintable} around the given
6568          * delegate.
6569          *
6570          * @param printDelegate the {@code Printable} to delegate to
6571          */
6572         public ThreadSafePrintable(Printable printDelegate) {
6573             this.printDelegate = printDelegate;
6574         }
6575 
6576         /**
6577          * Prints the specified page into the given {@link Graphics}
6578          * context, in the specified format.
6579          * <p>
6580          * Regardless of what thread this method is called on, all calls into
6581          * the delegate will be done on the event-dispatch thread.
6582          *
6583          * @param   graphics    the context into which the page is drawn
6584          * @param   pageFormat  the size and orientation of the page being drawn
6585          * @param   pageIndex   the zero based index of the page to be drawn
6586          * @return  PAGE_EXISTS if the page is rendered successfully, or
6587          *          NO_SUCH_PAGE if a non-existent page index is specified
6588          * @throws  PrinterException if an error causes printing to be aborted
6589          */
6590         public int print(final Graphics graphics,


6652      * For tables, the AccessibleContext takes the form of an
6653      * AccessibleJTable.
6654      * A new AccessibleJTable instance is created if necessary.
6655      *
6656      * @return an AccessibleJTable that serves as the
6657      *         AccessibleContext of this JTable
6658      */
6659     public AccessibleContext getAccessibleContext() {
6660         if (accessibleContext == null) {
6661             accessibleContext = new AccessibleJTable();
6662         }
6663         return accessibleContext;
6664     }
6665 
6666     //
6667     // *** should also implement AccessibleSelection?
6668     // *** and what's up with keyboard navigation/manipulation?
6669     //
6670     /**
6671      * This class implements accessibility support for the
6672      * {@code JTable} class.  It provides an implementation of the
6673      * Java Accessibility API appropriate to table user-interface elements.
6674      * <p>
6675      * <strong>Warning:</strong>
6676      * Serialized objects of this class will not be compatible with
6677      * future Swing releases. The current serialization support is
6678      * appropriate for short term storage or RMI between applications running
6679      * the same version of Swing.  As of 1.4, support for long term storage
6680      * of all JavaBeans&trade;
6681      * has been added to the {@code java.beans} package.
6682      * Please see {@link java.beans.XMLEncoder}.
6683      */
6684     @SuppressWarnings("serial") // Same-version serialization only
6685     protected class AccessibleJTable extends AccessibleJComponent
6686     implements AccessibleSelection, ListSelectionListener, TableModelListener,
6687     TableColumnModelListener, CellEditorListener, PropertyChangeListener,
6688     AccessibleExtendedTable {
6689 
6690         int previousFocusedRow;
6691         int previousFocusedCol;
6692 
6693         /**
6694          * AccessibleJTable constructor
6695          *
6696          * @since 1.5
6697          */
6698         protected AccessibleJTable() {
6699             super();
6700             JTable.this.addPropertyChangeListener(this);
6701             JTable.this.getSelectionModel().addListSelectionListener(this);


7102          * AccessibleSelection interface on behalf of itself.
7103          *
7104          * @return this object
7105          */
7106         public AccessibleSelection getAccessibleSelection() {
7107             return this;
7108         }
7109 
7110         /**
7111          * Gets the role of this object.
7112          *
7113          * @return an instance of AccessibleRole describing the role of the
7114          * object
7115          * @see AccessibleRole
7116          */
7117         public AccessibleRole getAccessibleRole() {
7118             return AccessibleRole.TABLE;
7119         }
7120 
7121         /**
7122          * Returns the {@code Accessible} child, if one exists,
7123          * contained at the local coordinate {@code Point}.
7124          *
7125          * @param p the point defining the top-left corner of the
7126          *    {@code Accessible}, given in the coordinate space
7127          *    of the object's parent
7128          * @return the {@code Accessible}, if it exists,
7129          *    at the specified location; else {@code null}
7130          */
7131         public Accessible getAccessibleAt(Point p) {
7132             int column = columnAtPoint(p);
7133             int row = rowAtPoint(p);
7134 
7135             if ((column != -1) && (row != -1)) {
7136                 TableColumn aColumn = getColumnModel().getColumn(column);
7137                 TableCellRenderer renderer = aColumn.getCellRenderer();
7138                 if (renderer == null) {
7139                     Class<?> columnClass = getColumnClass(column);
7140                     renderer = getDefaultRenderer(columnClass);
7141                 }
7142                 Component component = renderer.getTableCellRendererComponent(
7143                                   JTable.this, null, false, false,
7144                                   row, column);
7145                 return new AccessibleJTableCell(JTable.this, row, column,
7146                       getAccessibleIndexAt(row, column));
7147             }
7148             return null;
7149         }
7150 
7151         /**
7152          * Returns the number of accessible children in the object.  If all
7153          * of the children of this object implement {@code Accessible},
7154          * then this method should return the number of children of this object.
7155          *
7156          * @return the number of accessible children in the object
7157          */
7158         public int getAccessibleChildrenCount() {
7159             return (JTable.this.getColumnCount() * JTable.this.getRowCount());
7160         }
7161 
7162         /**
7163          * Returns the nth {@code Accessible} child of the object.
7164          *
7165          * @param i zero-based index of child
7166          * @return the nth Accessible child of the object
7167          */
7168         public Accessible getAccessibleChild(int i) {
7169             if (i < 0 || i >= getAccessibleChildrenCount()) {
7170                 return null;
7171             } else {
7172                 // children increase across, and then down, for tables
7173                 // (arbitrary decision)
7174                 int column = getAccessibleColumnAtIndex(i);
7175                 int row = getAccessibleRowAtIndex(i);
7176 
7177                 TableColumn aColumn = getColumnModel().getColumn(column);
7178                 TableCellRenderer renderer = aColumn.getCellRenderer();
7179                 if (renderer == null) {
7180                     Class<?> columnClass = getColumnClass(column);
7181                     renderer = getDefaultRenderer(columnClass);
7182                 }
7183                 Component component = renderer.getTableCellRendererComponent(
7184                                   JTable.this, null, false, false,
7185                                   row, column);
7186                 return new AccessibleJTableCell(JTable.this, row, column,
7187                       getAccessibleIndexAt(row, column));
7188             }
7189         }
7190 
7191     // AccessibleSelection support
7192 
7193         /**
7194          * Returns the number of {@code Accessible} children
7195          * currently selected.
7196          * If no children are selected, the return value will be 0.
7197          *
7198          * @return the number of items currently selected
7199          */
7200         public int getAccessibleSelectionCount() {
7201             int rowsSel = JTable.this.getSelectedRowCount();
7202             int colsSel = JTable.this.getSelectedColumnCount();
7203 
7204             if (JTable.this.cellSelectionEnabled) { // a contiguous block
7205                 return rowsSel * colsSel;
7206 
7207             } else {
7208                 // a column swath and a row swath, with a shared block
7209                 if (JTable.this.getRowSelectionAllowed() &&
7210                     JTable.this.getColumnSelectionAllowed()) {
7211                     return rowsSel * JTable.this.getColumnCount() +
7212                            colsSel * JTable.this.getRowCount() -
7213                            rowsSel * colsSel;
7214 
7215                 // just one or more rows in selection
7216                 } else if (JTable.this.getRowSelectionAllowed()) {
7217                     return rowsSel * JTable.this.getColumnCount();
7218 
7219                 // just one or more rows in selection
7220                 } else if (JTable.this.getColumnSelectionAllowed()) {
7221                     return colsSel * JTable.this.getRowCount();
7222 
7223                 } else {
7224                     return 0;    // JTable doesn't allow selections
7225                 }
7226             }
7227         }
7228 
7229         /**
7230          * Returns an {@code Accessible} representing the
7231          * specified selected child in the object.  If there
7232          * isn't a selection, or there are fewer children selected
7233          * than the integer passed in, the return
7234          * value will be {@code null}.
7235          * <p>Note that the index represents the i-th selected child, which
7236          * is different from the i-th child.
7237          *
7238          * @param i the zero-based index of selected children
7239          * @return the i-th selected child
7240          * @see #getAccessibleSelectionCount
7241          */
7242         public Accessible getAccessibleSelection(int i) {
7243             if (i < 0 || i > getAccessibleSelectionCount()) {
7244                 return null;
7245             }
7246 
7247             int rowsSel = JTable.this.getSelectedRowCount();
7248             int colsSel = JTable.this.getSelectedColumnCount();
7249             int rowIndicies[] = getSelectedRows();
7250             int colIndicies[] = getSelectedColumns();
7251             int ttlCols = JTable.this.getColumnCount();
7252             int ttlRows = JTable.this.getRowCount();
7253             int r;
7254             int c;


7344                 // one or more rows selected
7345                 } else if (JTable.this.getRowSelectionAllowed()) {
7346                     c = i % ttlCols;
7347                     r = rowIndicies[i / ttlCols];
7348                     return getAccessibleChild((r * ttlCols) + c);
7349 
7350                 // one or more columns selected
7351                 } else if (JTable.this.getColumnSelectionAllowed()) {
7352                     c = colIndicies[i % colsSel];
7353                     r = i / colsSel;
7354                     return getAccessibleChild((r * ttlCols) + c);
7355                 }
7356             }
7357             return null;
7358         }
7359 
7360         /**
7361          * Determines if the current child of this object is selected.
7362          *
7363          * @param i the zero-based index of the child in this
7364          *    {@code Accessible} object
7365          * @return true if the current child of this object is selected
7366          * @see AccessibleContext#getAccessibleChild
7367          */
7368         public boolean isAccessibleChildSelected(int i) {
7369             int column = getAccessibleColumnAtIndex(i);
7370             int row = getAccessibleRowAtIndex(i);
7371             return JTable.this.isCellSelected(row, column);
7372         }
7373 
7374         /**
7375          * Adds the specified {@code Accessible} child of the
7376          * object to the object's selection.  If the object supports
7377          * multiple selections, the specified child is added to
7378          * any existing selection, otherwise
7379          * it replaces any existing selection in the object.  If the
7380          * specified child is already selected, this method has no effect.
7381          * <p>
7382          * This method only works on {@code JTable}s which have
7383          * individual cell selection enabled.
7384          *
7385          * @param i the zero-based index of the child
7386          * @see AccessibleContext#getAccessibleChild
7387          */
7388         public void addAccessibleSelection(int i) {
7389             // TIGER - 4495286
7390             int column = getAccessibleColumnAtIndex(i);
7391             int row = getAccessibleRowAtIndex(i);
7392             JTable.this.changeSelection(row, column, true, false);
7393         }
7394 
7395         /**
7396          * Removes the specified child of the object from the object's
7397          * selection.  If the specified item isn't currently selected, this
7398          * method has no effect.
7399          * <p>
7400          * This method only works on {@code JTables} which have
7401          * individual cell selection enabled.
7402          *
7403          * @param i the zero-based index of the child
7404          * @see AccessibleContext#getAccessibleChild
7405          */
7406         public void removeAccessibleSelection(int i) {
7407             if (JTable.this.cellSelectionEnabled) {
7408                 int column = getAccessibleColumnAtIndex(i);
7409                 int row = getAccessibleRowAtIndex(i);
7410                 JTable.this.removeRowSelectionInterval(row, row);
7411                 JTable.this.removeColumnSelectionInterval(column, column);
7412             }
7413         }
7414 
7415         /**
7416          * Clears the selection in the object, so that no children in the
7417          * object are selected.
7418          */
7419         public void clearAccessibleSelection() {
7420             JTable.this.clearSelection();
7421         }
7422 
7423         /**
7424          * Causes every child of the object to be selected, but only
7425          * if the {@code JTable} supports multiple selections,
7426          * and if individual cell selection is enabled.
7427          */
7428         public void selectAllAccessibleSelection() {
7429             if (JTable.this.cellSelectionEnabled) {
7430                 JTable.this.selectAll();
7431             }
7432         }
7433 
7434         // begin AccessibleExtendedTable implementation -------------
7435 
7436         /**
7437          * Returns the row number of an index in the table.
7438          *
7439          * @param index the zero-based index in the table
7440          * @return the zero-based row of the table if one exists;
7441          * otherwise -1.
7442          * @since 1.4
7443          */
7444         public int getAccessibleRow(int index) {
7445             return getAccessibleRowAtIndex(index);


7463          * @param r zero-based row of the table
7464          * @param c zero-based column of the table
7465          * @return the zero-based index in the table if one exists;
7466          * otherwise -1.
7467          * @since 1.4
7468          */
7469         public int getAccessibleIndex(int r, int c) {
7470             return getAccessibleIndexAt(r, c);
7471         }
7472 
7473         // end of AccessibleExtendedTable implementation ------------
7474 
7475         // start of AccessibleTable implementation ------------------
7476 
7477         private Accessible caption;
7478         private Accessible summary;
7479         private Accessible [] rowDescription;
7480         private Accessible [] columnDescription;
7481 
7482         /**
7483          * Gets the {@code AccessibleTable} associated with this
7484          * object.  In the implementation of the Java Accessibility
7485          * API for this class, return this object, which is responsible
7486          * for implementing the {@code AccessibleTables} interface
7487          * on behalf of itself.
7488          *
7489          * @return this object
7490          * @since 1.3
7491          */
7492         public AccessibleTable getAccessibleTable() {
7493             return this;
7494         }
7495 
7496         /**
7497          * Returns the caption for the table.
7498          *
7499          * @return the caption for the table
7500          * @since 1.3
7501          */
7502         public Accessible getAccessibleCaption() {
7503             return this.caption;
7504         }
7505 
7506         /**


7541 
7542         /*
7543          * Returns the total number of rows in this table.
7544          *
7545          * @return the total number of rows in this table
7546          */
7547         public int getAccessibleRowCount() {
7548             return JTable.this.getRowCount();
7549         }
7550 
7551         /*
7552          * Returns the total number of columns in the table.
7553          *
7554          * @return the total number of columns in the table
7555          */
7556         public int getAccessibleColumnCount() {
7557             return JTable.this.getColumnCount();
7558         }
7559 
7560         /*
7561          * Returns the {@code Accessible} at a specified row
7562          * and column in the table.
7563          *
7564          * @param r zero-based row of the table
7565          * @param c zero-based column of the table
7566          * @return the {@code Accessible} at the specified row and column
7567          * in the table
7568          */
7569         public Accessible getAccessibleAt(int r, int c) {
7570             return getAccessibleChild((r * getAccessibleColumnCount()) + c);
7571         }
7572 
7573         /**
7574          * Returns the number of rows occupied by the {@code Accessible}
7575          * at a specified row and column in the table.
7576          *
7577          * @return the number of rows occupied by the {@code Accessible}
7578          *     at a specified row and column in the table
7579          * @since 1.3
7580          */
7581         public int getAccessibleRowExtentAt(int r, int c) {
7582             return 1;
7583         }
7584 
7585         /**
7586          * Returns the number of columns occupied by the
7587          * {@code Accessible} at a given (row, column).
7588          *
7589          * @return the number of columns occupied by the {@code Accessible}
7590          *     at a specified row and column in the table
7591          * @since 1.3
7592          */
7593         public int getAccessibleColumnExtentAt(int r, int c) {
7594             return 1;
7595         }
7596 
7597         /**
7598          * Returns the row headers as an {@code AccessibleTable}.
7599          *
7600          * @return an {@code AccessibleTable} representing the row
7601          * headers
7602          * @since 1.3
7603          */
7604         public AccessibleTable getAccessibleRowHeader() {
7605             // row headers are not supported
7606             return null;
7607         }
7608 
7609         /**
7610          * Sets the row headers as an {@code AccessibleTable}.
7611          *
7612          * @param a an {@code AccessibleTable} representing the row
7613          *  headers
7614          * @since 1.3
7615          */
7616         public void setAccessibleRowHeader(AccessibleTable a) {
7617             // row headers are not supported
7618         }
7619 
7620         /**
7621          * Returns the column headers as an {@code AccessibleTable}.
7622          *
7623          *  @return an {@code AccessibleTable} representing the column
7624          *          headers, or {@code null} if the table header is
7625          *          {@code null}
7626          * @since 1.3
7627          */
7628         public AccessibleTable getAccessibleColumnHeader() {
7629             JTableHeader header = JTable.this.getTableHeader();
7630             return header == null ? null : new AccessibleTableHeader(header);
7631         }
7632 
7633         /*
7634          * Private class representing a table column header
7635          */
7636         private class AccessibleTableHeader implements AccessibleTable {
7637             private JTableHeader header;
7638             private TableColumnModel headerModel;
7639 
7640             AccessibleTableHeader(JTableHeader header) {
7641                 this.header = header;
7642                 this.headerModel = header.getColumnModel();
7643             }
7644 
7645             /**


7840              * Returns the selected rows in a table.
7841              *
7842              * @return an array of selected rows where each element is a
7843              * zero-based row of the table
7844              * @since 1.3
7845              */
7846             public int [] getSelectedAccessibleRows() { return new int[0]; }
7847 
7848             /**
7849              * Returns the selected columns in a table.
7850              *
7851              * @return an array of selected columns where each element is a
7852              * zero-based column of the table
7853              * @since 1.3
7854              */
7855             public int [] getSelectedAccessibleColumns() { return new int[0]; }
7856         }
7857 
7858 
7859         /**
7860          * Sets the column headers as an {@code AccessibleTable}.
7861          *
7862          * @param a an {@code AccessibleTable} representing the
7863          * column headers
7864          * @since 1.3
7865          */
7866         public void setAccessibleColumnHeader(AccessibleTable a) {
7867             // XXX not implemented
7868         }
7869 
7870         /**
7871          * Returns the description of the specified row in the table.
7872          *
7873          * @param r zero-based row of the table
7874          * @return the description of the row
7875          * @since 1.3
7876          */
7877         public Accessible getAccessibleRowDescription(int r) {
7878             if (r < 0 || r >= getAccessibleRowCount()) {
7879                 throw new IllegalArgumentException(Integer.toString(r));
7880             }
7881             if (rowDescription == null) {
7882                 return null;


8043          */
8044         public int getAccessibleIndexAt(int r, int c) {
8045             return ((r * getAccessibleColumnCount()) + c);
8046         }
8047 
8048         // end of AccessibleTable implementation --------------------
8049 
8050         /**
8051          * The class provides an implementation of the Java Accessibility
8052          * API appropriate to table cells.
8053          */
8054         protected class AccessibleJTableCell extends AccessibleContext
8055             implements Accessible, AccessibleComponent {
8056 
8057             private JTable parent;
8058             private int row;
8059             private int column;
8060             private int index;
8061 
8062             /**
8063              *  Constructs an {@code AccessibleJTableHeaderEntry}.
8064              *
8065              * @param t a {@code JTable}
8066              * @param r an {@code int} specifying a row
8067              * @param c an {@code int} specifying a column
8068              * @param i an {@code int} specifying the index to this cell
8069              * @since 1.4
8070              */
8071             public AccessibleJTableCell(JTable t, int r, int c, int i) {
8072                 parent = t;
8073                 row = r;
8074                 column = c;
8075                 index = i;
8076                 this.setAccessibleParent(parent);
8077             }
8078 
8079             /**
8080              * Gets the {@code AccessibleContext} associated with this
8081              * component. In the implementation of the Java Accessibility
8082              * API for this class, return this object, which is its own
8083              * {@code AccessibleContext}.
8084              *
8085              * @return this object
8086              */
8087             public AccessibleContext getAccessibleContext() {
8088                 return this;
8089             }
8090 
8091             /**
8092              * Gets the AccessibleContext for the table cell renderer.
8093              *
8094              * @return the {@code AccessibleContext} for the table
8095              * cell renderer if one exists;
8096              * otherwise, returns {@code null}.
8097              * @since 1.6
8098              */
8099             protected AccessibleContext getCurrentAccessibleContext() {
8100                 TableColumn aColumn = getColumnModel().getColumn(column);
8101                 TableCellRenderer renderer = aColumn.getCellRenderer();
8102                 if (renderer == null) {
8103                     Class<?> columnClass = getColumnClass(column);
8104                     renderer = getDefaultRenderer(columnClass);
8105                 }
8106                 Component component = renderer.getTableCellRendererComponent(
8107                                   JTable.this, getValueAt(row, column),
8108                                   false, false, row, column);
8109                 if (component instanceof Accessible) {
8110                     return component.getAccessibleContext();
8111                 } else {
8112                     return null;
8113                 }
8114             }
8115 
8116             /**
8117              * Gets the table cell renderer component.
8118              *
8119              * @return the table cell renderer component if one exists;
8120              * otherwise, returns {@code null}.
8121              * @since 1.6
8122              */
8123             protected Component getCurrentComponent() {
8124                 TableColumn aColumn = getColumnModel().getColumn(column);
8125                 TableCellRenderer renderer = aColumn.getCellRenderer();
8126                 if (renderer == null) {
8127                     Class<?> columnClass = getColumnClass(column);
8128                     renderer = getDefaultRenderer(columnClass);
8129                 }
8130                 return renderer.getTableCellRendererComponent(
8131                                   JTable.this, null, false, false,
8132                                   row, column);
8133             }
8134 
8135         // AccessibleContext methods
8136 
8137             /**
8138              * Gets the accessible name of this object.
8139              *
8140              * @return the localized name of the object; {@code null}
8141              *     if this object does not have a name
8142              */
8143             public String getAccessibleName() {
8144                 AccessibleContext ac = getCurrentAccessibleContext();
8145                 if (ac != null) {
8146                     String name = ac.getAccessibleName();
8147                     if ((name != null) && (name != "")) {
8148                         // return the cell renderer's AccessibleName
8149                         return name;
8150                     }
8151                 }
8152                 if ((accessibleName != null) && (accessibleName != "")) {
8153                     return accessibleName;
8154                 } else {
8155                     // fall back to the client property
8156                     return (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
8157                 }
8158             }
8159 
8160             /**
8161              * Sets the localized accessible name of this object.
8162              *
8163              * @param s the new localized name of the object
8164              */
8165             public void setAccessibleName(String s) {
8166                 AccessibleContext ac = getCurrentAccessibleContext();
8167                 if (ac != null) {
8168                     ac.setAccessibleName(s);
8169                 } else {
8170                     super.setAccessibleName(s);
8171                 }
8172             }
8173 
8174             //
8175             // *** should check toolTip text for desc. (needs MouseEvent)
8176             //
8177             /**
8178              * Gets the accessible description of this object.
8179              *
8180              * @return the localized description of the object;
8181              *     {@code null} if this object does not have
8182              *     a description
8183              */
8184             public String getAccessibleDescription() {
8185                 AccessibleContext ac = getCurrentAccessibleContext();
8186                 if (ac != null) {
8187                     return ac.getAccessibleDescription();
8188                 } else {
8189                     return super.getAccessibleDescription();
8190                 }
8191             }
8192 
8193             /**
8194              * Sets the accessible description of this object.
8195              *
8196              * @param s the new localized description of the object
8197              */
8198             public void setAccessibleDescription(String s) {
8199                 AccessibleContext ac = getCurrentAccessibleContext();
8200                 if (ac != null) {
8201                     ac.setAccessibleDescription(s);
8202                 } else {
8203                     super.setAccessibleDescription(s);
8204                 }
8205             }
8206 
8207             /**
8208              * Gets the role of this object.
8209              *
8210              * @return an instance of {@code AccessibleRole}
8211              *      describing the role of the object
8212              * @see AccessibleRole
8213              */
8214             public AccessibleRole getAccessibleRole() {
8215                 AccessibleContext ac = getCurrentAccessibleContext();
8216                 if (ac != null) {
8217                     return ac.getAccessibleRole();
8218                 } else {
8219                     return AccessibleRole.UNKNOWN;
8220                 }
8221             }
8222 
8223             /**
8224              * Gets the state set of this object.
8225              *
8226              * @return an instance of {@code AccessibleStateSet}
8227              *     containing the current state set of the object
8228              * @see AccessibleState
8229              */
8230             public AccessibleStateSet getAccessibleStateSet() {
8231                 AccessibleContext ac = getCurrentAccessibleContext();
8232                 AccessibleStateSet as = null;
8233 
8234                 if (ac != null) {
8235                     as = ac.getAccessibleStateSet();
8236                 }
8237                 if (as == null) {
8238                     as = new AccessibleStateSet();
8239                 }
8240                 Rectangle rjt = JTable.this.getVisibleRect();
8241                 Rectangle rcell = JTable.this.getCellRect(row, column, false);
8242                 if (rjt.intersects(rcell)) {
8243                     as.add(AccessibleState.SHOWING);
8244                 } else {
8245                     if (as.contains(AccessibleState.SHOWING)) {
8246                          as.remove(AccessibleState.SHOWING);
8247                     }
8248                 }
8249                 if (parent.isCellSelected(row, column)) {
8250                     as.add(AccessibleState.SELECTED);
8251                 } else if (as.contains(AccessibleState.SELECTED)) {
8252                     as.remove(AccessibleState.SELECTED);
8253                 }
8254                 if ((row == getSelectedRow()) && (column == getSelectedColumn())) {
8255                     as.add(AccessibleState.ACTIVE);
8256                 }
8257                 as.add(AccessibleState.TRANSIENT);
8258                 return as;
8259             }
8260 
8261             /**
8262              * Gets the {@code Accessible} parent of this object.
8263              *
8264              * @return the Accessible parent of this object;
8265              *     {@code null} if this object does not
8266              *     have an {@code Accessible} parent
8267              */
8268             public Accessible getAccessibleParent() {
8269                 return parent;
8270             }
8271 
8272             /**
8273              * Gets the index of this object in its accessible parent.
8274              *
8275              * @return the index of this object in its parent; -1 if this
8276              *     object does not have an accessible parent
8277              * @see #getAccessibleParent
8278              */
8279             public int getAccessibleIndexInParent() {
8280                 return index;
8281             }
8282 
8283             /**
8284              * Returns the number of accessible children in the object.
8285              *
8286              * @return the number of accessible children in the object
8287              */
8288             public int getAccessibleChildrenCount() {
8289                 AccessibleContext ac = getCurrentAccessibleContext();
8290                 if (ac != null) {
8291                     return ac.getAccessibleChildrenCount();
8292                 } else {
8293                     return 0;
8294                 }
8295             }
8296 
8297             /**
8298              * Returns the specified {@code Accessible} child of the
8299              * object.
8300              *
8301              * @param i zero-based index of child
8302              * @return the {@code Accessible} child of the object
8303              */
8304             public Accessible getAccessibleChild(int i) {
8305                 AccessibleContext ac = getCurrentAccessibleContext();
8306                 if (ac != null) {
8307                     Accessible accessibleChild = ac.getAccessibleChild(i);
8308                     ac.setAccessibleParent(this);
8309                     return accessibleChild;
8310                 } else {
8311                     return null;
8312                 }
8313             }
8314 
8315             /**
8316              * Gets the locale of the component. If the component
8317              * does not have a locale, then the locale of its parent
8318              * is returned.
8319              *
8320              * @return this component's locale; if this component does
8321              *    not have a locale, the locale of its parent is returned
8322              * @exception IllegalComponentStateException if the
8323              *    {@code Component} does not have its own locale
8324              *    and has not yet been added to a containment hierarchy
8325              *    such that the locale can be determined from the
8326              *    containing parent
8327              * @see #setLocale
8328              */
8329             public Locale getLocale() {
8330                 AccessibleContext ac = getCurrentAccessibleContext();
8331                 if (ac != null) {
8332                     return ac.getLocale();
8333                 } else {
8334                     return null;
8335                 }
8336             }
8337 
8338             /**
8339              * Adds a {@code PropertyChangeListener} to the listener list.
8340              * The listener is registered for all properties.
8341              *
8342              * @param l  the {@code PropertyChangeListener}
8343              *     to be added
8344              */
8345             public void addPropertyChangeListener(PropertyChangeListener l) {
8346                 AccessibleContext ac = getCurrentAccessibleContext();
8347                 if (ac != null) {
8348                     ac.addPropertyChangeListener(l);
8349                 } else {
8350                     super.addPropertyChangeListener(l);
8351                 }
8352             }
8353 
8354             /**
8355              * Removes a {@code PropertyChangeListener} from the
8356              * listener list. This removes a {@code PropertyChangeListener}
8357              * that was registered for all properties.
8358              *
8359              * @param l  the {@code PropertyChangeListener}
8360              *    to be removed
8361              */
8362             public void removePropertyChangeListener(PropertyChangeListener l) {
8363                 AccessibleContext ac = getCurrentAccessibleContext();
8364                 if (ac != null) {
8365                     ac.removePropertyChangeListener(l);
8366                 } else {
8367                     super.removePropertyChangeListener(l);
8368                 }
8369             }
8370 
8371             /**
8372              * Gets the {@code AccessibleAction} associated with this
8373              * object if one exists.  Otherwise returns {@code null}.
8374              *
8375              * @return the {@code AccessibleAction}, or {@code null}
8376              */
8377             public AccessibleAction getAccessibleAction() {
8378                 return getCurrentAccessibleContext().getAccessibleAction();
8379             }
8380 
8381             /**
8382              * Gets the {@code AccessibleComponent} associated with
8383              * this object if one exists.  Otherwise returns {@code null}.
8384              *
8385              * @return the {@code AccessibleComponent}, or
8386              *    {@code null}
8387              */
8388             public AccessibleComponent getAccessibleComponent() {
8389                 return this; // to override getBounds()
8390             }
8391 
8392             /**
8393              * Gets the {@code AccessibleSelection} associated with
8394              * this object if one exists.  Otherwise returns {@code null}.
8395              *
8396              * @return the {@code AccessibleSelection}, or
8397              *    {@code null}
8398              */
8399             public AccessibleSelection getAccessibleSelection() {
8400                 return getCurrentAccessibleContext().getAccessibleSelection();
8401             }
8402 
8403             /**
8404              * Gets the {@code AccessibleText} associated with this
8405              * object if one exists.  Otherwise returns {@code null}.
8406              *
8407              * @return the {@code AccessibleText}, or {@code null}
8408              */
8409             public AccessibleText getAccessibleText() {
8410                 return getCurrentAccessibleContext().getAccessibleText();
8411             }
8412 
8413             /**
8414              * Gets the {@code AccessibleValue} associated with
8415              * this object if one exists.  Otherwise returns {@code null}.
8416              *
8417              * @return the {@code AccessibleValue}, or {@code null}
8418              */
8419             public AccessibleValue getAccessibleValue() {
8420                 return getCurrentAccessibleContext().getAccessibleValue();
8421             }
8422 
8423 
8424         // AccessibleComponent methods
8425 
8426             /**
8427              * Gets the background color of this object.
8428              *
8429              * @return the background color, if supported, of the object;
8430              *     otherwise, {@code null}
8431              */
8432             public Color getBackground() {
8433                 AccessibleContext ac = getCurrentAccessibleContext();
8434                 if (ac instanceof AccessibleComponent) {
8435                     return ((AccessibleComponent) ac).getBackground();
8436                 } else {
8437                     Component c = getCurrentComponent();
8438                     if (c != null) {
8439                         return c.getBackground();
8440                     } else {
8441                         return null;
8442                     }
8443                 }
8444             }
8445 
8446             /**
8447              * Sets the background color of this object.
8448              *
8449              * @param c the new {@code Color} for the background
8450              */
8451             public void setBackground(Color c) {
8452                 AccessibleContext ac = getCurrentAccessibleContext();
8453                 if (ac instanceof AccessibleComponent) {
8454                     ((AccessibleComponent) ac).setBackground(c);
8455                 } else {
8456                     Component cp = getCurrentComponent();
8457                     if (cp != null) {
8458                         cp.setBackground(c);
8459                     }
8460                 }
8461             }
8462 
8463             /**
8464              * Gets the foreground color of this object.
8465              *
8466              * @return the foreground color, if supported, of the object;
8467              *     otherwise, {@code null}
8468              */
8469             public Color getForeground() {
8470                 AccessibleContext ac = getCurrentAccessibleContext();
8471                 if (ac instanceof AccessibleComponent) {
8472                     return ((AccessibleComponent) ac).getForeground();
8473                 } else {
8474                     Component c = getCurrentComponent();
8475                     if (c != null) {
8476                         return c.getForeground();
8477                     } else {
8478                         return null;
8479                     }
8480                 }
8481             }
8482 
8483             /**
8484              * Sets the foreground color of this object.
8485              *
8486              * @param c the new {@code Color} for the foreground
8487              */
8488             public void setForeground(Color c) {
8489                 AccessibleContext ac = getCurrentAccessibleContext();
8490                 if (ac instanceof AccessibleComponent) {
8491                     ((AccessibleComponent) ac).setForeground(c);
8492                 } else {
8493                     Component cp = getCurrentComponent();
8494                     if (cp != null) {
8495                         cp.setForeground(c);
8496                     }
8497                 }
8498             }
8499 
8500             /**
8501              * Gets the {@code Cursor} of this object.
8502              *
8503              * @return the {@code Cursor}, if supported,
8504              *    of the object; otherwise, {@code null}
8505              */
8506             public Cursor getCursor() {
8507                 AccessibleContext ac = getCurrentAccessibleContext();
8508                 if (ac instanceof AccessibleComponent) {
8509                     return ((AccessibleComponent) ac).getCursor();
8510                 } else {
8511                     Component c = getCurrentComponent();
8512                     if (c != null) {
8513                         return c.getCursor();
8514                     } else {
8515                         Accessible ap = getAccessibleParent();
8516                         if (ap instanceof AccessibleComponent) {
8517                             return ((AccessibleComponent) ap).getCursor();
8518                         } else {
8519                             return null;
8520                         }
8521                     }
8522                 }
8523             }
8524 
8525             /**
8526              * Sets the {@code Cursor} of this object.
8527              *
8528              * @param c the new {@code Cursor} for the object
8529              */
8530             public void setCursor(Cursor c) {
8531                 AccessibleContext ac = getCurrentAccessibleContext();
8532                 if (ac instanceof AccessibleComponent) {
8533                     ((AccessibleComponent) ac).setCursor(c);
8534                 } else {
8535                     Component cp = getCurrentComponent();
8536                     if (cp != null) {
8537                         cp.setCursor(c);
8538                     }
8539                 }
8540             }
8541 
8542             /**
8543              * Gets the {@code Font} of this object.
8544              *
8545              * @return the {@code Font},if supported,
8546              *   for the object; otherwise, {@code null}
8547              */
8548             public Font getFont() {
8549                 AccessibleContext ac = getCurrentAccessibleContext();
8550                 if (ac instanceof AccessibleComponent) {
8551                     return ((AccessibleComponent) ac).getFont();
8552                 } else {
8553                     Component c = getCurrentComponent();
8554                     if (c != null) {
8555                         return c.getFont();
8556                     } else {
8557                         return null;
8558                     }
8559                 }
8560             }
8561 
8562             /**
8563              * Sets the {@code Font} of this object.
8564              *
8565              * @param f the new {@code Font} for the object
8566              */
8567             public void setFont(Font f) {
8568                 AccessibleContext ac = getCurrentAccessibleContext();
8569                 if (ac instanceof AccessibleComponent) {
8570                     ((AccessibleComponent) ac).setFont(f);
8571                 } else {
8572                     Component c = getCurrentComponent();
8573                     if (c != null) {
8574                         c.setFont(f);
8575                     }
8576                 }
8577             }
8578 
8579             /**
8580              * Gets the {@code FontMetrics} of this object.
8581              *
8582              * @param f the {@code Font}
8583              * @return the {@code FontMetrics} object, if supported;
8584              *    otherwise {@code null}
8585              * @see #getFont
8586              */
8587             public FontMetrics getFontMetrics(Font f) {
8588                 AccessibleContext ac = getCurrentAccessibleContext();
8589                 if (ac instanceof AccessibleComponent) {
8590                     return ((AccessibleComponent) ac).getFontMetrics(f);
8591                 } else {
8592                     Component c = getCurrentComponent();
8593                     if (c != null) {
8594                         return c.getFontMetrics(f);
8595                     } else {
8596                         return null;
8597                     }
8598                 }
8599             }
8600 
8601             /**
8602              * Determines if the object is enabled.
8603              *
8604              * @return true if object is enabled; otherwise, false


8622              *
8623              * @param b if true, enables this object; otherwise, disables it
8624              */
8625             public void setEnabled(boolean b) {
8626                 AccessibleContext ac = getCurrentAccessibleContext();
8627                 if (ac instanceof AccessibleComponent) {
8628                     ((AccessibleComponent) ac).setEnabled(b);
8629                 } else {
8630                     Component c = getCurrentComponent();
8631                     if (c != null) {
8632                         c.setEnabled(b);
8633                     }
8634                 }
8635             }
8636 
8637             /**
8638              * Determines if this object is visible.  Note: this means that the
8639              * object intends to be visible; however, it may not in fact be
8640              * showing on the screen because one of the objects that this object
8641              * is contained by is not visible.  To determine if an object is
8642              * showing on the screen, use {@code isShowing}.
8643              *
8644              * @return true if object is visible; otherwise, false
8645              */
8646             public boolean isVisible() {
8647                 AccessibleContext ac = getCurrentAccessibleContext();
8648                 if (ac instanceof AccessibleComponent) {
8649                     return ((AccessibleComponent) ac).isVisible();
8650                 } else {
8651                     Component c = getCurrentComponent();
8652                     if (c != null) {
8653                         return c.isVisible();
8654                     } else {
8655                         return false;
8656                     }
8657                 }
8658             }
8659 
8660             /**
8661              * Sets the visible state of the object.
8662              *


8693                         // returns false when the cell on the screen
8694                         // if no parent
8695                         return isVisible();
8696                     }
8697                 } else {
8698                     Component c = getCurrentComponent();
8699                     if (c != null) {
8700                         return c.isShowing();
8701                     } else {
8702                         return false;
8703                     }
8704                 }
8705             }
8706 
8707             /**
8708              * Checks whether the specified point is within this
8709              * object's bounds, where the point's x and y coordinates
8710              * are defined to be relative to the coordinate system of
8711              * the object.
8712              *
8713              * @param p the {@code Point} relative to the
8714              *    coordinate system of the object
8715              * @return true if object contains {@code Point};
8716              *    otherwise false
8717              */
8718             public boolean contains(Point p) {
8719                 AccessibleContext ac = getCurrentAccessibleContext();
8720                 if (ac instanceof AccessibleComponent) {
8721                     Rectangle r = ((AccessibleComponent) ac).getBounds();
8722                     return r.contains(p);
8723                 } else {
8724                     Component c = getCurrentComponent();
8725                     if (c != null) {
8726                         Rectangle r = c.getBounds();
8727                         return r.contains(p);
8728                     } else {
8729                         return getBounds().contains(p);
8730                     }
8731                 }
8732             }
8733 
8734             /**
8735              * Returns the location of the object on the screen.
8736              *
8737              * @return location of object on screen -- can be
8738              *    {@code null} if this object is not on the screen
8739              */
8740             public Point getLocationOnScreen() {
8741                 if (parent != null && parent.isShowing()) {
8742                     Point parentLocation = parent.getLocationOnScreen();
8743                     Point componentLocation = getLocation();
8744                     componentLocation.translate(parentLocation.x, parentLocation.y);
8745                     return componentLocation;
8746                 } else {
8747                     return null;
8748                 }
8749             }
8750 
8751             /**
8752              * Gets the location of the object relative to the parent
8753              * in the form of a point specifying the object's
8754              * top-left corner in the screen's coordinate space.
8755              *
8756              * @return an instance of {@code Point} representing
8757              *    the top-left corner of the object's bounds in the
8758              *    coordinate space of the screen; {@code null} if
8759              *    this object or its parent are not on the screen
8760              */
8761             public Point getLocation() {
8762                 if (parent != null) {
8763                     Rectangle r = parent.getCellRect(row, column, false);
8764                     if (r != null) {
8765                         return r.getLocation();
8766                     }
8767                 }
8768                 return null;
8769             }
8770 
8771             /**
8772              * Sets the location of the object relative to the parent.
8773              */
8774             public void setLocation(Point p) {
8775 //              if ((parent != null)  && (parent.contains(p))) {
8776 //                  ensureIndexIsVisible(indexInParent);
8777 //              }
8778             }


8878                     }
8879                 }
8880             }
8881 
8882         } // inner class AccessibleJTableCell
8883 
8884         // Begin AccessibleJTableHeader ========== // TIGER - 4715503
8885 
8886         /**
8887          * This class implements accessibility for JTable header cells.
8888          */
8889         private class AccessibleJTableHeaderCell extends AccessibleContext
8890             implements Accessible, AccessibleComponent {
8891 
8892             private int row;
8893             private int column;
8894             private JTableHeader parent;
8895             private Component rendererComponent;
8896 
8897             /**
8898              * Constructs an {@code AccessibleJTableHeaderEntry} instance.
8899              *
8900              * @param row header cell row index
8901              * @param column header cell column index
8902              * @param parent header cell parent
8903              * @param rendererComponent component that renders the header cell
8904              */
8905             public AccessibleJTableHeaderCell(int row, int column,
8906                                               JTableHeader parent,
8907                                               Component rendererComponent) {
8908                 this.row = row;
8909                 this.column = column;
8910                 this.parent = parent;
8911                 this.rendererComponent = rendererComponent;
8912                 this.setAccessibleParent(parent);
8913             }
8914 
8915             /**
8916              * Gets the {@code AccessibleContext} associated with this
8917              * component. In the implementation of the Java Accessibility
8918              * API for this class, return this object, which is its own
8919              * {@code AccessibleContext}.
8920              *
8921              * @return this object
8922              */
8923             public AccessibleContext getAccessibleContext() {
8924                 return this;
8925             }
8926 
8927             /*
8928              * Returns the AccessibleContext for the header cell
8929              * renderer.
8930              */
8931             private AccessibleContext getCurrentAccessibleContext() {
8932                 return rendererComponent.getAccessibleContext();
8933             }
8934 
8935             /*
8936              * Returns the component that renders the header cell.
8937              */
8938             private Component getCurrentComponent() {
8939                 return rendererComponent;
8940             }
8941 
8942             // AccessibleContext methods ==========
8943 
8944             /**
8945              * Gets the accessible name of this object.
8946              *
8947              * @return the localized name of the object; {@code null}
8948              *     if this object does not have a name
8949              */
8950             public String getAccessibleName() {
8951                 AccessibleContext ac = getCurrentAccessibleContext();
8952                 if (ac != null) {
8953                     String name = ac.getAccessibleName();
8954                     if ((name != null) && (name != "")) {
8955                         return ac.getAccessibleName();
8956                     }
8957                 }
8958                 if ((accessibleName != null) && (accessibleName != "")) {
8959                     return accessibleName;
8960                 } else {
8961                     return null;
8962                 }
8963             }
8964 
8965             /**
8966              * Sets the localized accessible name of this object.
8967              *
8968              * @param s the new localized name of the object
8969              */
8970             public void setAccessibleName(String s) {
8971                 AccessibleContext ac = getCurrentAccessibleContext();
8972                 if (ac != null) {
8973                     ac.setAccessibleName(s);
8974                 } else {
8975                     super.setAccessibleName(s);
8976                 }
8977             }
8978 
8979             /**
8980              * Gets the accessible description of this object.
8981              *
8982              * @return the localized description of the object;
8983              *     {@code null} if this object does not have
8984              *     a description
8985              */
8986             public String getAccessibleDescription() {
8987                 AccessibleContext ac = getCurrentAccessibleContext();
8988                 if (ac != null) {
8989                     return ac.getAccessibleDescription();
8990                 } else {
8991                     return super.getAccessibleDescription();
8992                 }
8993             }
8994 
8995             /**
8996              * Sets the accessible description of this object.
8997              *
8998              * @param s the new localized description of the object
8999              */
9000             public void setAccessibleDescription(String s) {
9001                 AccessibleContext ac = getCurrentAccessibleContext();
9002                 if (ac != null) {
9003                     ac.setAccessibleDescription(s);
9004                 } else {
9005                     super.setAccessibleDescription(s);
9006                 }
9007             }
9008 
9009             /**
9010              * Gets the role of this object.
9011              *
9012              * @return an instance of {@code AccessibleRole}
9013              *      describing the role of the object
9014              * @see AccessibleRole
9015              */
9016             public AccessibleRole getAccessibleRole() {
9017                 AccessibleContext ac = getCurrentAccessibleContext();
9018                 if (ac != null) {
9019                     return ac.getAccessibleRole();
9020                 } else {
9021                     return AccessibleRole.UNKNOWN;
9022                 }
9023             }
9024 
9025             /**
9026              * Gets the state set of this object.
9027              *
9028              * @return an instance of {@code AccessibleStateSet}
9029              *     containing the current state set of the object
9030              * @see AccessibleState
9031              */
9032             public AccessibleStateSet getAccessibleStateSet() {
9033                 AccessibleContext ac = getCurrentAccessibleContext();
9034                 AccessibleStateSet as = null;
9035 
9036                 if (ac != null) {
9037                     as = ac.getAccessibleStateSet();
9038                 }
9039                 if (as == null) {
9040                     as = new AccessibleStateSet();
9041                 }
9042                 Rectangle rjt = JTable.this.getVisibleRect();
9043                 Rectangle rcell = JTable.this.getCellRect(row, column, false);
9044                 if (rjt.intersects(rcell)) {
9045                     as.add(AccessibleState.SHOWING);
9046                 } else {
9047                     if (as.contains(AccessibleState.SHOWING)) {
9048                          as.remove(AccessibleState.SHOWING);
9049                     }
9050                 }
9051                 if (JTable.this.isCellSelected(row, column)) {
9052                     as.add(AccessibleState.SELECTED);
9053                 } else if (as.contains(AccessibleState.SELECTED)) {
9054                     as.remove(AccessibleState.SELECTED);
9055                 }
9056                 if ((row == getSelectedRow()) && (column == getSelectedColumn())) {
9057                     as.add(AccessibleState.ACTIVE);
9058                 }
9059                 as.add(AccessibleState.TRANSIENT);
9060                 return as;
9061             }
9062 
9063             /**
9064              * Gets the {@code Accessible} parent of this object.
9065              *
9066              * @return the Accessible parent of this object;
9067              *     {@code null} if this object does not
9068              *     have an {@code Accessible} parent
9069              */
9070             public Accessible getAccessibleParent() {
9071                 return parent;
9072             }
9073 
9074             /**
9075              * Gets the index of this object in its accessible parent.
9076              *
9077              * @return the index of this object in its parent; -1 if this
9078              *     object does not have an accessible parent
9079              * @see #getAccessibleParent
9080              */
9081             public int getAccessibleIndexInParent() {
9082                 return column;
9083             }
9084 
9085             /**
9086              * Returns the number of accessible children in the object.
9087              *
9088              * @return the number of accessible children in the object
9089              */
9090             public int getAccessibleChildrenCount() {
9091                 AccessibleContext ac = getCurrentAccessibleContext();
9092                 if (ac != null) {
9093                     return ac.getAccessibleChildrenCount();
9094                 } else {
9095                     return 0;
9096                 }
9097             }
9098 
9099             /**
9100              * Returns the specified {@code Accessible} child of the
9101              * object.
9102              *
9103              * @param i zero-based index of child
9104              * @return the {@code Accessible} child of the object
9105              */
9106             public Accessible getAccessibleChild(int i) {
9107                 AccessibleContext ac = getCurrentAccessibleContext();
9108                 if (ac != null) {
9109                     Accessible accessibleChild = ac.getAccessibleChild(i);
9110                     ac.setAccessibleParent(this);
9111                     return accessibleChild;
9112                 } else {
9113                     return null;
9114                 }
9115             }
9116 
9117             /**
9118              * Gets the locale of the component. If the component
9119              * does not have a locale, then the locale of its parent
9120              * is returned.
9121              *
9122              * @return this component's locale; if this component does
9123              *    not have a locale, the locale of its parent is returned
9124              * @exception IllegalComponentStateException if the
9125              *    {@code Component} does not have its own locale
9126              *    and has not yet been added to a containment hierarchy
9127              *    such that the locale can be determined from the
9128              *    containing parent
9129              * @see #setLocale
9130              */
9131             public Locale getLocale() {
9132                 AccessibleContext ac = getCurrentAccessibleContext();
9133                 if (ac != null) {
9134                     return ac.getLocale();
9135                 } else {
9136                     return null;
9137                 }
9138             }
9139 
9140             /**
9141              * Adds a {@code PropertyChangeListener} to the listener list.
9142              * The listener is registered for all properties.
9143              *
9144              * @param l  the {@code PropertyChangeListener}
9145              *     to be added
9146              */
9147             public void addPropertyChangeListener(PropertyChangeListener l) {
9148                 AccessibleContext ac = getCurrentAccessibleContext();
9149                 if (ac != null) {
9150                     ac.addPropertyChangeListener(l);
9151                 } else {
9152                     super.addPropertyChangeListener(l);
9153                 }
9154             }
9155 
9156             /**
9157              * Removes a {@code PropertyChangeListener} from the
9158              * listener list. This removes a {@code PropertyChangeListener}
9159              * that was registered for all properties.
9160              *
9161              * @param l  the {@code PropertyChangeListener}
9162              *    to be removed
9163              */
9164             public void removePropertyChangeListener(PropertyChangeListener l) {
9165                 AccessibleContext ac = getCurrentAccessibleContext();
9166                 if (ac != null) {
9167                     ac.removePropertyChangeListener(l);
9168                 } else {
9169                     super.removePropertyChangeListener(l);
9170                 }
9171             }
9172 
9173             /**
9174              * Gets the {@code AccessibleAction} associated with this
9175              * object if one exists.  Otherwise returns {@code null}.
9176              *
9177              * @return the {@code AccessibleAction}, or {@code null}
9178              */
9179             public AccessibleAction getAccessibleAction() {
9180                 return getCurrentAccessibleContext().getAccessibleAction();
9181             }
9182 
9183             /**
9184              * Gets the {@code AccessibleComponent} associated with
9185              * this object if one exists.  Otherwise returns {@code null}.
9186              *
9187              * @return the {@code AccessibleComponent}, or
9188              *    {@code null}
9189              */
9190             public AccessibleComponent getAccessibleComponent() {
9191                 return this; // to override getBounds()
9192             }
9193 
9194             /**
9195              * Gets the {@code AccessibleSelection} associated with
9196              * this object if one exists.  Otherwise returns {@code null}.
9197              *
9198              * @return the {@code AccessibleSelection}, or
9199              *    {@code null}
9200              */
9201             public AccessibleSelection getAccessibleSelection() {
9202                 return getCurrentAccessibleContext().getAccessibleSelection();
9203             }
9204 
9205             /**
9206              * Gets the {@code AccessibleText} associated with this
9207              * object if one exists.  Otherwise returns {@code null}.
9208              *
9209              * @return the {@code AccessibleText}, or {@code null}
9210              */
9211             public AccessibleText getAccessibleText() {
9212                 return getCurrentAccessibleContext().getAccessibleText();
9213             }
9214 
9215             /**
9216              * Gets the {@code AccessibleValue} associated with
9217              * this object if one exists.  Otherwise returns {@code null}.
9218              *
9219              * @return the {@code AccessibleValue}, or {@code null}
9220              */
9221             public AccessibleValue getAccessibleValue() {
9222                 return getCurrentAccessibleContext().getAccessibleValue();
9223             }
9224 
9225 
9226             // AccessibleComponent methods ==========
9227 
9228             /**
9229              * Gets the background color of this object.
9230              *
9231              * @return the background color, if supported, of the object;
9232              *     otherwise, {@code null}
9233              */
9234             public Color getBackground() {
9235                 AccessibleContext ac = getCurrentAccessibleContext();
9236                 if (ac instanceof AccessibleComponent) {
9237                     return ((AccessibleComponent) ac).getBackground();
9238                 } else {
9239                     Component c = getCurrentComponent();
9240                     if (c != null) {
9241                         return c.getBackground();
9242                     } else {
9243                         return null;
9244                     }
9245                 }
9246             }
9247 
9248             /**
9249              * Sets the background color of this object.
9250              *
9251              * @param c the new {@code Color} for the background
9252              */
9253             public void setBackground(Color c) {
9254                 AccessibleContext ac = getCurrentAccessibleContext();
9255                 if (ac instanceof AccessibleComponent) {
9256                     ((AccessibleComponent) ac).setBackground(c);
9257                 } else {
9258                     Component cp = getCurrentComponent();
9259                     if (cp != null) {
9260                         cp.setBackground(c);
9261                     }
9262                 }
9263             }
9264 
9265             /**
9266              * Gets the foreground color of this object.
9267              *
9268              * @return the foreground color, if supported, of the object;
9269              *     otherwise, {@code null}
9270              */
9271             public Color getForeground() {
9272                 AccessibleContext ac = getCurrentAccessibleContext();
9273                 if (ac instanceof AccessibleComponent) {
9274                     return ((AccessibleComponent) ac).getForeground();
9275                 } else {
9276                     Component c = getCurrentComponent();
9277                     if (c != null) {
9278                         return c.getForeground();
9279                     } else {
9280                         return null;
9281                     }
9282                 }
9283             }
9284 
9285             /**
9286              * Sets the foreground color of this object.
9287              *
9288              * @param c the new {@code Color} for the foreground
9289              */
9290             public void setForeground(Color c) {
9291                 AccessibleContext ac = getCurrentAccessibleContext();
9292                 if (ac instanceof AccessibleComponent) {
9293                     ((AccessibleComponent) ac).setForeground(c);
9294                 } else {
9295                     Component cp = getCurrentComponent();
9296                     if (cp != null) {
9297                         cp.setForeground(c);
9298                     }
9299                 }
9300             }
9301 
9302             /**
9303              * Gets the {@code Cursor} of this object.
9304              *
9305              * @return the {@code Cursor}, if supported,
9306              *    of the object; otherwise, {@code null}
9307              */
9308             public Cursor getCursor() {
9309                 AccessibleContext ac = getCurrentAccessibleContext();
9310                 if (ac instanceof AccessibleComponent) {
9311                     return ((AccessibleComponent) ac).getCursor();
9312                 } else {
9313                     Component c = getCurrentComponent();
9314                     if (c != null) {
9315                         return c.getCursor();
9316                     } else {
9317                         Accessible ap = getAccessibleParent();
9318                         if (ap instanceof AccessibleComponent) {
9319                             return ((AccessibleComponent) ap).getCursor();
9320                         } else {
9321                             return null;
9322                         }
9323                     }
9324                 }
9325             }
9326 
9327             /**
9328              * Sets the {@code Cursor} of this object.
9329              *
9330              * @param c the new {@code Cursor} for the object
9331              */
9332             public void setCursor(Cursor c) {
9333                 AccessibleContext ac = getCurrentAccessibleContext();
9334                 if (ac instanceof AccessibleComponent) {
9335                     ((AccessibleComponent) ac).setCursor(c);
9336                 } else {
9337                     Component cp = getCurrentComponent();
9338                     if (cp != null) {
9339                         cp.setCursor(c);
9340                     }
9341                 }
9342             }
9343 
9344             /**
9345              * Gets the {@code Font} of this object.
9346              *
9347              * @return the {@code Font},if supported,
9348              *   for the object; otherwise, {@code null}
9349              */
9350             public Font getFont() {
9351                 AccessibleContext ac = getCurrentAccessibleContext();
9352                 if (ac instanceof AccessibleComponent) {
9353                     return ((AccessibleComponent) ac).getFont();
9354                 } else {
9355                     Component c = getCurrentComponent();
9356                     if (c != null) {
9357                         return c.getFont();
9358                     } else {
9359                         return null;
9360                     }
9361                 }
9362             }
9363 
9364             /**
9365              * Sets the {@code Font} of this object.
9366              *
9367              * @param f the new {@code Font} for the object
9368              */
9369             public void setFont(Font f) {
9370                 AccessibleContext ac = getCurrentAccessibleContext();
9371                 if (ac instanceof AccessibleComponent) {
9372                     ((AccessibleComponent) ac).setFont(f);
9373                 } else {
9374                     Component c = getCurrentComponent();
9375                     if (c != null) {
9376                         c.setFont(f);
9377                     }
9378                 }
9379             }
9380 
9381             /**
9382              * Gets the {@code FontMetrics} of this object.
9383              *
9384              * @param f the {@code Font}
9385              * @return the {@code FontMetrics} object, if supported;
9386              *    otherwise {@code null}
9387              * @see #getFont
9388              */
9389             public FontMetrics getFontMetrics(Font f) {
9390                 AccessibleContext ac = getCurrentAccessibleContext();
9391                 if (ac instanceof AccessibleComponent) {
9392                     return ((AccessibleComponent) ac).getFontMetrics(f);
9393                 } else {
9394                     Component c = getCurrentComponent();
9395                     if (c != null) {
9396                         return c.getFontMetrics(f);
9397                     } else {
9398                         return null;
9399                     }
9400                 }
9401             }
9402 
9403             /**
9404              * Determines if the object is enabled.
9405              *
9406              * @return true if object is enabled; otherwise, false


9424              *
9425              * @param b if true, enables this object; otherwise, disables it
9426              */
9427             public void setEnabled(boolean b) {
9428                 AccessibleContext ac = getCurrentAccessibleContext();
9429                 if (ac instanceof AccessibleComponent) {
9430                     ((AccessibleComponent) ac).setEnabled(b);
9431                 } else {
9432                     Component c = getCurrentComponent();
9433                     if (c != null) {
9434                         c.setEnabled(b);
9435                     }
9436                 }
9437             }
9438 
9439             /**
9440              * Determines if this object is visible.  Note: this means that the
9441              * object intends to be visible; however, it may not in fact be
9442              * showing on the screen because one of the objects that this object
9443              * is contained by is not visible.  To determine if an object is
9444              * showing on the screen, use {@code isShowing}.
9445              *
9446              * @return true if object is visible; otherwise, false
9447              */
9448             public boolean isVisible() {
9449                 AccessibleContext ac = getCurrentAccessibleContext();
9450                 if (ac instanceof AccessibleComponent) {
9451                     return ((AccessibleComponent) ac).isVisible();
9452                 } else {
9453                     Component c = getCurrentComponent();
9454                     if (c != null) {
9455                         return c.isVisible();
9456                     } else {
9457                         return false;
9458                     }
9459                 }
9460             }
9461 
9462             /**
9463              * Sets the visible state of the object.
9464              *


9495                         // returns false when the cell on the screen
9496                         // if no parent
9497                         return isVisible();
9498                     }
9499                 } else {
9500                     Component c = getCurrentComponent();
9501                     if (c != null) {
9502                         return c.isShowing();
9503                     } else {
9504                         return false;
9505                     }
9506                 }
9507             }
9508 
9509             /**
9510              * Checks whether the specified point is within this
9511              * object's bounds, where the point's x and y coordinates
9512              * are defined to be relative to the coordinate system of
9513              * the object.
9514              *
9515              * @param p the {@code Point} relative to the
9516              *    coordinate system of the object
9517              * @return true if object contains {@code Point};
9518              *    otherwise false
9519              */
9520             public boolean contains(Point p) {
9521                 AccessibleContext ac = getCurrentAccessibleContext();
9522                 if (ac instanceof AccessibleComponent) {
9523                     Rectangle r = ((AccessibleComponent) ac).getBounds();
9524                     return r.contains(p);
9525                 } else {
9526                     Component c = getCurrentComponent();
9527                     if (c != null) {
9528                         Rectangle r = c.getBounds();
9529                         return r.contains(p);
9530                     } else {
9531                         return getBounds().contains(p);
9532                     }
9533                 }
9534             }
9535 
9536             /**
9537              * Returns the location of the object on the screen.
9538              *
9539              * @return location of object on screen -- can be
9540              *    {@code null} if this object is not on the screen
9541              */
9542             public Point getLocationOnScreen() {
9543                 if (parent != null && parent.isShowing()) {
9544                     Point parentLocation = parent.getLocationOnScreen();
9545                     Point componentLocation = getLocation();
9546                     componentLocation.translate(parentLocation.x, parentLocation.y);
9547                     return componentLocation;
9548                 } else {
9549                     return null;
9550                 }
9551             }
9552 
9553             /**
9554              * Gets the location of the object relative to the parent
9555              * in the form of a point specifying the object's
9556              * top-left corner in the screen's coordinate space.
9557              *
9558              * @return an instance of {@code Point} representing
9559              *    the top-left corner of the object's bounds in the
9560              *    coordinate space of the screen; {@code null} if
9561              *    this object or its parent are not on the screen
9562              */
9563             public Point getLocation() {
9564                 if (parent != null) {
9565                     Rectangle r = parent.getHeaderRect(column);
9566                     if (r != null) {
9567                         return r.getLocation();
9568                     }
9569                 }
9570                 return null;
9571             }
9572 
9573             /**
9574              * Sets the location of the object relative to the parent.
9575              * @param p the new position for the top-left corner
9576              * @see #getLocation
9577              */
9578             public void setLocation(Point p) {
9579             }
9580 


< prev index next >