/* JTable.java -- 
   Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing;

import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.Date;
import java.util.EventObject;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Vector;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleComponent;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleExtendedTable;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleSelection;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
import javax.accessibility.AccessibleTable;
import javax.accessibility.AccessibleTableModelChange;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.plaf.TableUI;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

/**
 * The table component, displaying information, organized in rows and columns.
 * The table can be placed in the scroll bar and have the optional header
 * that is always visible. Cell values may be editable after double clicking
 * on the cell. Cell columns may have various data types, that are 
 * displayed and edited by the different renderers and editors. It is possible
 * to set different column width. The columns are also resizeable by 
 * dragging the column boundary in the header.
 */
public class JTable
  extends JComponent
  implements TableModelListener, Scrollable, TableColumnModelListener,
             ListSelectionListener, CellEditorListener, Accessible
{
  /**
   * Provides accessibility support for <code>JTable</code>.
   *
   * @author Roman Kennke (kennke@aicas.com)
   */
  protected class AccessibleJTable
    extends AccessibleJComponent
    implements AccessibleSelection, ListSelectionListener, TableModelListener,
    TableColumnModelListener, CellEditorListener, PropertyChangeListener,
    AccessibleExtendedTable
  {

    /**
     * Provides accessibility support for table cells.
     *
     * @author Roman Kennke (kennke@aicas.com)
     */
    protected class AccessibleJTableCell
      extends AccessibleContext
      implements Accessible, AccessibleComponent
    {

      /**
       * The table of this cell.
       */
      private JTable table;

      /**
       * The row index of this cell.
       */
      private int row;

      /**
       * The column index of this cell.
       */
      private int column;

      /**
       * The index of this cell inside the AccessibleJTable parent.
       */
      private int index;

      /**
       * Creates a new <code>AccessibleJTableCell</code>.
       *
       * @param t the table
       * @param r the row
       * @param c the column
       * @param i the index of this cell inside the accessible table parent
       */
      public AccessibleJTableCell(JTable t, int r, int c, int i)
      {
        table = t;
        row = r;
        column = c;
        index = i;
      }

      /**
       * Returns the accessible row for the table cell.
       *
       * @return the accessible row for the table cell
       */
      public AccessibleRole getAccessibleRole()
      {
        // TODO: What is the role of the table cell?
        // Seems like the RI returns UNKNOWN here for 'normal' cells, might
        // be different for special renderers though (not tested yet).
        return AccessibleRole.UNKNOWN;
      }

      /**
       * Returns the accessible state set of this accessible table cell.
       *
       * @return the accessible state set of this accessible table cell
       */
      public AccessibleStateSet getAccessibleStateSet()
      {
        AccessibleStateSet state = new AccessibleStateSet();

        // Figure out the SHOWING state.
        Rectangle visibleRect = getVisibleRect();
        Rectangle cellRect = getCellRect(row, column, false);
        if (visibleRect.intersects(cellRect))
          state.add(AccessibleState.SHOWING);

        // Figure out SELECTED state.
        if (isCellSelected(row, column))
          state.add(AccessibleState.SELECTED);

        // Figure out ACTIVE state.
        if (row == getSelectedRow() && column == getSelectedColumn())
          state.add(AccessibleState.ACTIVE);

        // TRANSIENT seems to be always set in the RI.
        state.add(AccessibleState.TRANSIENT);

        // TODO: Any other state to handle here?
        return state;
      }

      /**
       * Returns the index of this cell in the parent object.
       *
       * @return the index of this cell in the parent object
       */
      public int getAccessibleIndexInParent()
      {
        return index;
      }

      /**
       * Returns the number of children of this object. Table cells cannot have
       * children, so we return <code>0</code> here.
       *
       * @return <code>0</code>
       */
      public int getAccessibleChildrenCount()
      {
        return 0;
      }

      /**
       * Returns the accessible child at index <code>i</code>. Table cells
       * don't have children, so we return <code>null</code> here.
       *
       * @return <code>null</code>
       */
      public Accessible getAccessibleChild(int i)
      {
        return null;
      }

      /**
       * Returns the locale setting for this accessible table cell.
       *
       * @return the locale setting for this accessible table cell
       */
      public Locale getLocale()
      {
        // TODO: For now, we return english here. This must be fixed as soon
        // as we have a localized Swing.
        return Locale.ENGLISH;
      }

      /**
       * Returns the accessible context of this table cell. Since accessible
       * table cells are their own accessible context, we return
       * <code>this</code>.
       *
       * @return the accessible context of this table cell
       */
      public AccessibleContext getAccessibleContext()
      {
        return this;
      }

      /**
       * Returns the background color of this cell.
       *
       * @return the background color of this cell
       */
      public Color getBackground()
      {
        return table.getBackground();
      }

      /**
       * Sets the background of the cell. Since table cells cannot have
       * individual background colors, this method does nothing. Set the
       * background directly on the table instead.
       * 
       * @param color not used
       */
      public void setBackground(Color color)
      {
        // This method does nothing. See API comments.
      }

      /**
       * Returns the foreground color of the table cell.
       *
       * @return the foreground color of the table cell
       */
      public Color getForeground()
      {
        return table.getForeground();
      }

      /**
       * Sets the foreground of the cell. Since table cells cannot have
       * individual foreground colors, this method does nothing. Set the
       * foreground directly on the table instead.
       * 
       * @param color not used
       */
      public void setForeground(Color color)
      {
        // This method does nothing. See API comments.
      }

      /**
       * Returns the cursor for this table cell.
       *
       * @return the cursor for this table cell
       */
      public Cursor getCursor()
      {
        return table.getCursor();
      }

      /**
       * Sets the cursor of the cell. Since table cells cannot have
       * individual cursors, this method does nothing. Set the
       * cursor directly on the table instead.
       * 
       * @param cursor not used
       */
      public void setCursor(Cursor cursor)
      {
        // This method does nothing. See API comments.
      }

      /**
       * Returns the font of the table cell.
       *
       * @return the font of the table cell
       */
      public Font getFont()
      {
        return table.getFont();
      }

      /**
       * Sets the font of the cell. Since table cells cannot have
       * individual fonts, this method does nothing. Set the
       * font directly on the table instead.
       * 
       * @param font not used
       */
      public void setFont(Font font)
      {
        // This method does nothing. See API comments.
      }

      /**
       * Returns the font metrics for a specified font.
       *
       * @param font the font for which we return the metrics
       *
       * @return the font metrics for a specified font
       */
      public FontMetrics getFontMetrics(Font font)
      {
        return table.getFontMetrics(font);
      }

      /**
       * Returns <code>true</code> if this table cell is enabled,
       * <code>false</code> otherwise.
       *
       * @return <code>true</code> if this table cell is enabled,
       *         <code>false</code> otherwise
       */
      public boolean isEnabled()
      {
        return table.isEnabled();
      }

      /**
       * Table cells cannot be disabled or enabled individually, so this method
       * does nothing. Set the enabled flag on the table itself.
       *
       * @param b not used here
       */
      public void setEnabled(boolean b)
      {
        // This method does nothing. See API comments.
      }

      /**
       * Returns <code>true</code> if this cell is visible, <code>false</code>
       * otherwise.
       *
       * @return <code>true</code> if this cell is visible, <code>false</code>
       *         otherwise
       */
      public boolean isVisible()
      {
        return table.isVisible();
      }

      /**
       * The visibility cannot be set on individual table cells, so this method
       * does nothing. Set the visibility on the table itself.
       *
       * @param b not used
       */
      public void setVisible(boolean b)
      {
        // This method does nothing. See API comments.
      }

      /**
       * Returns <code>true</code> if this table cell is currently showing on
       * screen.
       *
       * @return <code>true</code> if this table cell is currently showing on
       *         screen
       */
      public boolean isShowing()
      {
        return table.isShowing();
      }

      /**
       * Returns <code>true</code> if this table cell contains the location
       * at <code>point</code>, <code>false</code> otherwise.
       * <code>point</code> is interpreted as relative to the coordinate system
       * of the table cell.
       *
       * @return <code>true</code> if this table cell contains the location
       *         at <code>point</code>, <code>false</code> otherwise
       */
      public boolean contains(Point point)
      {
        Rectangle cellRect = table.getCellRect(row, column, true);
        cellRect.x = 0;
        cellRect.y = 0;
        return cellRect.contains(point);
      }

      /**
       * Returns the screen location of the table cell.
       *
       * @return the screen location of the table cell
       */
      public Point getLocationOnScreen()
      {
        Point tableLoc = table.getLocationOnScreen();
        Rectangle cellRect = table.getCellRect(row, column, true);
        tableLoc.x += cellRect.x;
        tableLoc.y += cellRect.y;
        return tableLoc;
      }

      /**
       * Returns the location of this cell relative to the table's bounds.
       *
       * @return the location of this cell relative to the table's bounds
       */
      public Point getLocation()
      {
        Rectangle cellRect = table.getCellRect(row, column, true);
        return new Point(cellRect.x, cellRect.y);
      }

      /**
       * The location of the table cells cannot be manipulated directly, so
       * this method does nothing.
       *
       * @param point not used
       */
      public void setLocation(Point point)
      {
        // This method does nothing. See API comments.
      }

      /**
       * Returns the bounds of the cell relative to its table.
       *
       * @return the bounds of the cell relative to its table
       */
      public Rectangle getBounds()
      {
        return table.getCellRect(row, column, true);
      }

      /**
       * The bounds of the table cells cannot be manipulated directly, so
       * this method does nothing.
       *
       * @param rectangle not used
       */
      public void setBounds(Rectangle rectangle)
      {
        // This method does nothing. See API comments.
      }

      /**
       * Returns the size of the table cell.
       *
       * @return the size of the table cell
       */
      public Dimension getSize()
      {
        Rectangle cellRect = table.getCellRect(row, column, true);
        return new Dimension(cellRect.width, cellRect.height);
      }

      /**
       * The size cannot be set on table cells directly, so this method does
       * nothing.
       *
       * @param dimension not used
       */
      public void setSize(Dimension dimension)
      {
        // This method does nothing. See API comments.
      }

      /**
       * Table cells have no children, so we return <code>null</code> here.
       *
       * @return <code>null</code>
       */
      public Accessible getAccessibleAt(Point point)
      {
        return null;
      }

      /**
       * Returns <code>true</code> if this table cell is focus traversable,
       * <code>false</code> otherwise.
       *
       * @return <code>true</code> if this table cell is focus traversable,
       *         <code>false</code> otherwise
       */
      public boolean isFocusTraversable()
      {
        return table.isFocusable();
      }

      /**
       * Requests that this table cell gets the keyboard focus.
       */
      public void requestFocus()
      {
        // We first set the selection models' lead selection to this cell.
        table.getColumnModel().getSelectionModel()
        .setLeadSelectionIndex(column);
        table.getSelectionModel().setLeadSelectionIndex(row);
        // Now we request that the table receives focus.
        table.requestFocus();
      }

      /**
       * Adds a focus listener to this cell. The focus listener is really
       * added to the table, so there is no way to find out when an individual
       * cell changes the focus.
       *
       * @param listener the focus listener to add
       */
      public void addFocusListener(FocusListener listener)
      {
        table.addFocusListener(listener);
      }

      /**
       * Removes a focus listener from the cell. The focus listener is really
       * removed from the table.
       *
       * @param listener the listener to remove
       */
      public void removeFocusListener(FocusListener listener)
      {
        table.removeFocusListener(listener);
      }
        
    }

    protected class AccessibleJTableModelChange
      implements AccessibleTableModelChange
    {
      protected int type;
      protected int firstRow;
      protected int lastRow;
      protected int firstColumn;
      protected int lastColumn;

      protected AccessibleJTableModelChange(int type, int firstRow,
                                            int lastRow, int firstColumn,
                                            int lastColumn)
      {
        this.type = type;
        this.firstRow = firstRow;
        this.lastRow = lastRow;
        this.firstColumn = firstColumn;
        this.lastColumn = lastColumn;
      }

      public int getType()
      {
        return type;
      }

      public int getFirstRow()
      {
        return firstRow;
      }

      public int getLastRow()
      {
        return lastRow;
      }

      public int getFirstColumn()
      {
        return firstColumn;
      }

      public int getLastColumn()
      {
        return lastColumn;
      }
    }

    /**
     * The RI returns an instance with this name in
     * {@link #getAccessibleColumnHeader()}, this makes sense, so we do the
     * same.
     */
    private class AccessibleTableHeader
      implements AccessibleTable
    {

      /**
       * The JTableHeader wrapped by this class.
       */
      private JTableHeader header;

      /**
       * Creates a new instance.
       *
       * @param h the JTableHeader to wrap
       */
      private AccessibleTableHeader(JTableHeader h)
      {
        header = h;
      }

      /**
       * Returns the caption for the table header.
       *
       * @return the caption for the table header
       */
      public Accessible getAccessibleCaption()
      {
        // The RI seems to always return null here, so do we.
        return null;
      }

      /**
       * Sets the caption for the table header.
       *
       * @param caption the caption to set
       */
      public void setAccessibleCaption(Accessible caption)
      {
        // This seems to be a no-op in the RI, so we do the same.
      }

      /**
       * Returns the caption for the table header.
       *
       * @return the caption for the table header
       */
      public Accessible getAccessibleSummary()
      {
        // The RI seems to always return null here, so do we.
        return null;
      }

      /**
       * Sets the summary for the table header.
       *
       * @param summary the caption to set
       */
      public void setAccessibleSummary(Accessible summary)
      {
        // This seems to be a no-op in the RI, so we do the same.
      }

      /**
       * Returns the number of rows, which is always 1 for the table header.
       *
       * @return the number of rows
       */
      public int getAccessibleRowCount()
      {
        return 1;
      }

      /**
       * Returns the number of columns in the table header.
       *
       * @return the number of columns in the table header
       */
      public int getAccessibleColumnCount()
      {
        return header.getColumnModel().getColumnCount();
      }

      /**
       * Returns the accessible child at the specified row and column.
       * The row number is ignored here, and we return an
       * AccessibleJTableHeaderCell here with the renderer component as
       * component.
       *
       * @param r the row number
       * @param c the column number
       *
       * @return the accessible child at the specified row and column
       */
      public Accessible getAccessibleAt(int r, int c)
      {
        TableColumn column = header.getColumnModel().getColumn(c);
        TableCellRenderer rend = column.getHeaderRenderer();
        if (rend == null)
          rend = header.getDefaultRenderer();
        Component comp =
          rend.getTableCellRendererComponent(header.getTable(),
                                             column.getHeaderValue(), false,
                                             false, -1, c);
        return new AccessibleJTableHeaderCell(header, comp, r, c);
      }

      public int getAccessibleRowExtentAt(int r, int c)
      {
        // TODO Auto-generated method stub
        return 0;
      }

      public int getAccessibleColumnExtentAt(int r, int c)
      {
        // TODO Auto-generated method stub
        return 0;
      }

      public AccessibleTable getAccessibleRowHeader()
      {
        // TODO Auto-generated method stub
        return null;
      }

      public void setAccessibleRowHeader(AccessibleTable header)
      {
        // TODO Auto-generated method stub
        
      }

      public AccessibleTable getAccessibleColumnHeader()
      {
        // TODO Auto-generated method stub
        return null;
      }

      public void setAccessibleColumnHeader(AccessibleTable header)
      {
        // TODO Auto-generated method stub
        
      }

      public Accessible getAccessibleRowDescription(int r)
      {
        // TODO Auto-generated method stub
        return null;
      }

      public void setAccessibleRowDescription(int r, Accessible description)
      {
        // TODO Auto-generated method stub
        
      }

      public Accessible getAccessibleColumnDescription(int c)
      {
        // TODO Auto-generated method stub
        return null;
      }

      public void setAccessibleColumnDescription(int c, Accessible description)
      {
        // TODO Auto-generated method stub
        
      }

      public boolean isAccessibleSelected(int r, int c)
      {
        // TODO Auto-generated method stub
        return false;
      }

      public boolean isAccessibleRowSelected(int r)
      {
        // TODO Auto-generated method stub
        return false;
      }

      public boolean isAccessibleColumnSelected(int c)
      {
        // TODO Auto-generated method stub
        return false;
      }

      public int[] getSelectedAccessibleRows()
      {
        // TODO Auto-generated method stub
        return null;
      }

      public int[] getSelectedAccessibleColumns()
      {
        // TODO Auto-generated method stub
        return null;
      }
        
    }

    /**
     * The RI returns an instance of such class for table header cells. This
     * makes sense so I added this class. This still needs to be fully
     * implemented, I just don't feel motivated enough to do so just now.
     */
    private class AccessibleJTableHeaderCell
      extends AccessibleContext
      implements Accessible, AccessibleComponent
    {

      JTableHeader header;
      
      int columnIndex;
      
      /**
       * 
       * @param h  the table header.
       * @param comp
       * @param r
       * @param c  the column index.
       */
      private AccessibleJTableHeaderCell(JTableHeader h, Component comp, int r,
                                         int c)
      {
        header = h;
        columnIndex = c;
      }

      /**
       * Returns the header renderer.
       * 
       * @return The header renderer.
       */
      Component getColumnHeaderRenderer()
      {
        TableColumn tc = header.getColumnModel().getColumn(columnIndex);
        TableCellRenderer r = tc.getHeaderRenderer();
        if (r == null)
          r = header.getDefaultRenderer();
        return r.getTableCellRendererComponent(header.getTable(), 
            tc.getHeaderValue(), false, false, -1, columnIndex);
      }
      
      /**
       * Returns the accessible role for the table header cell.
       * 
       * @return The accessible role.
       */
      public AccessibleRole getAccessibleRole()
      {
        Component renderer = getColumnHeaderRenderer();
        if (renderer instanceof Accessible)
          {
            Accessible ac = (Accessible) renderer;
            return ac.getAccessibleContext().getAccessibleRole();
          }
        return null;
      }

      public AccessibleStateSet getAccessibleStateSet()
      {
        // TODO Auto-generated method stub
        return null;
      }

      public int getAccessibleIndexInParent()
      {
        // TODO Auto-generated method stub
        return 0;
      }

      public int getAccessibleChildrenCount()
      {
        // TODO Auto-generated method stub
        return 0;
      }

      public Accessible getAccessibleChild(int i)
      {
        // TODO Auto-generated method stub
        return null;
      }

      public Locale getLocale()
      {
        // TODO Auto-generated method stub
        return null;
      }

      /**
       * Returns the accessible context.
       * 
       * @return <code>this</code>.
       */
      public AccessibleContext getAccessibleContext()
      {
        return this;
      }

      public Color getBackground()
      {
        // TODO Auto-generated method stub
        return null;
      }

      public void setBackground(Color color)
      {
        // TODO Auto-generated method stub
        
      }

      public Color getForeground()
      {
        // TODO Auto-generated method stub
        return null;
      }

      public void setForeground(Color color)
      {
        // TODO Auto-generated method stub
        
      }

      public Cursor getCursor()
      {
        // TODO Auto-generated method stub
        return null;
      }

      public void setCursor(Cursor cursor)
      {
        // TODO Auto-generated method stub
        
      }

      public Font getFont()
      {
        // TODO Auto-generated method stub
        return null;
      }

      public void setFont(Font font)
      {
        // TODO Auto-generated method stub
        
      }

      public FontMetrics getFontMetrics(Font font)
      {
        // TODO Auto-generated method stub
        return null;
      }

      public boolean isEnabled()
      {
        // TODO Auto-generated method stub
        return false;
      }

      public void setEnabled(boolean b)
      {
        // TODO Auto-generated method stub
        
      }

      public boolean isVisible()
      {
        // TODO Auto-generated method stub
        return false;
      }

      public void setVisible(boolean b)
      {
        // TODO Auto-generated method stub
        
      }

      public boolean isShowing()
      {
        // TODO Auto-generated method stub
        return false;
      }

      public boolean contains(Point point)
      {
        // TODO Auto-generated method stub
        return false;
      }

      public Point getLocationOnScreen()
      {
        // TODO Auto-generated method stub
        return null;
      }

      public Point getLocation()
      {
        // TODO Auto-generated method stub
        return null;
      }

      public void setLocation(Point point)
      {
        // TODO Auto-generated method stub
        
      }

      public Rectangle getBounds()
      {
        // TODO Auto-generated method stub
        return null;
      }

      public void setBounds(Rectangle rectangle)
      {
        // TODO Auto-generated method stub
        
      }

      public Dimension getSize()
      {
        // TODO Auto-generated method stub
        return null;
      }

      public void setSize(Dimension dimension)
      {
        // TODO Auto-generated method stub
        
      }

      public Accessible getAccessibleAt(Point point)
      {
        // TODO Auto-generated method stub
        return null;
      }

      public boolean isFocusTraversable()
      {
        // TODO Auto-generated method stub
        return false;
      }

      public void requestFocus()
      {
        // TODO Auto-generated method stub
        
      }

      public void addFocusListener(FocusListener listener)
      {
        // TODO Auto-generated method stub
        
      }

      public void removeFocusListener(FocusListener listener)
      {
        // TODO Auto-generated method stub
        
      }
      
    }

    /**
     * The last selected row. This is needed to track the selection in
     * {@link #valueChanged(ListSelectionEvent)}.
     */
    private int lastSelectedRow;

    /**
     * The last selected column. This is needed to track the selection in
     * {@link #valueChanged(ListSelectionEvent)}.
     */
    private int lastSelectedColumn;

    /**
     * The caption of the table.
     */
    private Accessible caption;

    /**
     * The summary of the table.
     */
    private Accessible summary;

    /**
     * Accessible descriptions for rows.
     */
    private Accessible[] rowDescriptions;

    /**
     * Accessible descriptions for columns.
     */
    private Accessible[] columnDescriptions;

    /**
     * Creates a new <code>AccessibleJTable</code>.
     *
     * @since JDK1.5
     */
    protected AccessibleJTable()
    {
      getModel().addTableModelListener(this);
      getSelectionModel().addListSelectionListener(this);
      getColumnModel().addColumnModelListener(this);
      lastSelectedRow = getSelectedRow();
      lastSelectedColumn = getSelectedColumn();
      TableCellEditor editor = getCellEditor();
      if (editor != null)
        editor.addCellEditorListener(this);
    }

    /**
     * Returns the accessible role for the <code>JTable</code> component.
     *
     * @return {@link AccessibleRole#TABLE}.
     */
    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.TABLE;
    }
    
    /**
     * Returns the accessible table.
     * 
     * @return <code>this</code>.
     */
    public AccessibleTable getAccessibleTable()
    {
      return this;
    }
    
    /**
     * Returns the number of selected items in this table.
     */
    public int getAccessibleSelectionCount()
    {
      return getSelectedColumnCount();
    }

    /**
     * Returns the selected accessible object with the specified index
     * <code>i</code>. This basically returns the i-th selected cell in the
     * table when going though it row-wise, and inside the rows, column-wise.
     *
     * @param i the index of the selected object to find
     *
     * @return the selected accessible object with the specified index
     *         <code>i</code>
     */
    public Accessible getAccessibleSelection(int i)
    {
      Accessible found = null;

      int[] selectedRows = getSelectedRows();
      int[] selectedColumns = getSelectedColumns();
      int numCols = getColumnCount();
      int numRows = getRowCount();

      // We have to go through every selected row and column and count until we
      // find the specified index. This is potentially inefficient, but I can't
      // think of anything better atm.
      if (getRowSelectionAllowed() && getColumnSelectionAllowed())
        {
          int current = -1;
          int newIndex = current;
          int lastSelectedRow = -1;
          // Go through the selected rows array, don't forget the selected
          // cells inside the not-selected rows' columns.
          for (int j = 0; i < selectedRows.length; i++)
            {
              // Handle unselected rows between this selected and the last
              // selected row, if any.
              int selectedRow = selectedRows[j];
              int r = -1;
              int ci = -1;
              for (r = lastSelectedRow + 1;
                   r < selectedRow && current < i; r++)
                {
                  for (ci = 0; ci < selectedColumns.length && current < i;
                       ci++)
                    {
                      current++;
                    }
                }
              if (current == i)
                {
                  // We found the cell in the above loops, now get out of here.
                  found = getAccessibleChild(r * numCols
                                             + selectedColumns[ci]);
                  break;
                }

              // If we're still here, handle the current selected row.
              if (current < i && current + numCols >= i)
                {
                  // The cell must be in that row, which one is it?
                  found = getAccessibleChild(r * numCols + (i - current));
                  break;
                }
              current += numCols;
            }
          if (found == null)
            {
              // The cell can still be in the last couple of unselected rows.
              int r = 0;
              int ci = 0;
              for (r = lastSelectedRow + 1;
                   r < numRows && current < i; r++)
                {
                  for (ci = 0; ci < selectedColumns.length && current < i;
                       ci++)
                    {
                      current++;
                    }
                }
              if (current == i)
                {
                  // We found the cell in the above loops, now get out of here.
                  found = getAccessibleChild(r * numCols
                                             + selectedColumns[ci]);
                }
            }
        }
      // One or more rows can be completely selected.
      else if (getRowSelectionAllowed())
        {
          int c = i % numCols;
          int r = selectedRows[i / numCols];
          found = getAccessibleChild(r * numCols + c);
        }
      // One or more columns can be completely selected.
      else if (getRowSelectionAllowed())
        {
          int numSelectedColumns = selectedColumns.length;
          int c = selectedColumns[i % numSelectedColumns];
          int r = i / numSelectedColumns;
          found = getAccessibleChild(r * numCols + c);
        }

      return found;
    }

    /**
     * Returns <code>true</code> if the accessible child with the index
     * <code>i</code> is selected, <code>false</code> otherwise.
     *
     * @param i the index of the accessible to check
     *
     * @return <code>true</code> if the accessible child with the index
     *         <code>i</code> is selected, <code>false</code> otherwise
     */
    public boolean isAccessibleChildSelected(int i)
    {
      int r = getAccessibleRowAtIndex(i);
      int c = getAccessibleColumnAtIndex(i);
      return isCellSelected(r, c);
    }

    /**
     * Adds the accessible child with the specified index <code>i</code> to the
     * selection.
     *
     * @param i the index of the accessible child to add to the selection
     */
    public void addAccessibleSelection(int i)
    {
      int r = getAccessibleRowAtIndex(i);
      int c = getAccessibleColumnAtIndex(i);
      changeSelection(r, c, true, false);
    }

    /**
     * Removes the accessible child with the specified index <code>i</code>
     * from the current selection. This will only work on tables that have
     * cell selection enabled (<code>rowSelectionAllowed == false &&
     * columnSelectionAllowed == false</code>).
     *
     * @param i the index of the accessible to be removed from the selection
     */
    public void removeAccessibleSelection(int i)
    {
      if (! getRowSelectionAllowed() && ! getColumnSelectionAllowed())
        {
          int r = getAccessibleRowAtIndex(i);
          int c = getAccessibleColumnAtIndex(i);
          removeRowSelectionInterval(r, r);
          removeColumnSelectionInterval(c, c);
        }
    }

    /**
     * Deselects all selected accessible children.
     */
    public void clearAccessibleSelection()
    {
      clearSelection();
    }

    /**
     * Selects all accessible children that can be selected. This will only
     * work on tables that support multiple selections and that have individual
     * cell selection enabled.
     */
    public void selectAllAccessibleSelection()
    {
      selectAll();
    }

    /**
     * Receives notification when the row selection changes and fires
     * appropriate property change events.
     *
     * @param event the list selection event
     */
    public void valueChanged(ListSelectionEvent event)
    {
      firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
                         Boolean.FALSE, Boolean.TRUE);
      int r = getSelectedRow();
      int c = getSelectedColumn();
      if (r != lastSelectedRow || c != lastSelectedColumn)
        {
          Accessible o = getAccessibleAt(lastSelectedRow,
                                         lastSelectedColumn);
          Accessible n = getAccessibleAt(r, c);
          firePropertyChange(AccessibleContext
                             .ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, o, n);
          lastSelectedRow = r;
          lastSelectedColumn = c;
        }
    }

    /**
     * Receives notification when the table model changes. Depending on the
     * type of change, this method calls {@link #tableRowsInserted} or
     * {@link #tableRowsDeleted}.
     *
     * @param event the table model event
     */
    public void tableChanged(TableModelEvent event)
    {
      switch (event.getType())
        {
        case TableModelEvent.INSERT:
          tableRowsInserted(event);
          break;
        case TableModelEvent.DELETE:
          tableRowsDeleted(event);
          break;
        }
    }

    /**
     * Receives notification when one or more rows have been inserted into the
     * table and fires appropriate property change events.
     *
     * @param event the table model event
     */
    public void tableRowsInserted(TableModelEvent event)
    {
      handleRowChange(event);
    }

    /**
     * Receives notification when one or more rows have been deleted from the
     * table.
     *
     * @param event the table model event
     */
    public void tableRowsDeleted(TableModelEvent event)
    {
      handleRowChange(event);
    }

    /**
     * Fires a PropertyChangeEvent for inserted or deleted rows.
     *
     * @param event the table model event
     */
    private void handleRowChange(TableModelEvent event)
    {
      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
                         null, null);
      int firstColumn = event.getColumn();
      int lastColumn = event.getColumn();
      if (firstColumn == TableModelEvent.ALL_COLUMNS)
        {
          firstColumn = 0;
          lastColumn = getColumnCount() - 1;
        }
      AccessibleJTableModelChange change = new AccessibleJTableModelChange
         (event.getType(), event.getFirstRow(), event.getLastRow(),
          firstColumn, lastColumn);
      firePropertyChange(AccessibleContext.ACCESSIBLE_TABLE_MODEL_CHANGED,
                         null, change);
    }

    public void columnAdded(TableColumnModelEvent event)
    {
      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
                         null, null);
      handleColumnChange(AccessibleTableModelChange.INSERT,
                         event.getFromIndex(), event.getToIndex());
    }

    public void columnRemoved(TableColumnModelEvent event)
    {
      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
                         null, null);
      handleColumnChange(AccessibleTableModelChange.DELETE,
                         event.getFromIndex(), event.getToIndex());
    }

    public void columnMoved(TableColumnModelEvent event)
    {
      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
                         null, null);
      handleColumnChange(AccessibleTableModelChange.DELETE,
                         event.getFromIndex(), event.getFromIndex());
      handleColumnChange(AccessibleTableModelChange.INSERT,
                         event.getFromIndex(), event.getToIndex());
    }

    /**
     * Fires a PropertyChangeEvent for inserted or deleted columns.
     *
     * @param type the type of change
     * @param from the start of the change
     * @param to the target of the change
     */
    private void handleColumnChange(int type, int from, int to)
    {
      AccessibleJTableModelChange change =
        new AccessibleJTableModelChange(type, 0, 0, from, to);
      firePropertyChange(AccessibleContext.ACCESSIBLE_TABLE_MODEL_CHANGED,
                         null, change);
    }

    public void columnMarginChanged(ChangeEvent event)
    {
      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
                         null, null);
    }

    public void columnSelectionChanged(ListSelectionEvent event)
    {
      // AFAICS, nothing is done here.
    }

    public void editingCanceled(ChangeEvent event)
    {
      // AFAICS, nothing is done here.
    }

    public void editingStopped(ChangeEvent event)
    {
      firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
                         null, null);
    }

    /**
     * Receives notification when any of the JTable's properties changes. This
     * is used to replace the listeners on the table's model, selection model,
     * column model and cell editor.
     *
     * @param e the property change event
     */
    public void propertyChange(PropertyChangeEvent e)
    {
      String propName = e.getPropertyName(); 
      if (propName.equals("tableModel"))
        {
          TableModel oldModel = (TableModel) e.getOldValue();
          oldModel.removeTableModelListener(this);
          TableModel newModel = (TableModel) e.getNewValue();
          newModel.addTableModelListener(this);
        }
      else if (propName.equals("columnModel"))
        {
          TableColumnModel oldModel = (TableColumnModel) e.getOldValue();
          oldModel.removeColumnModelListener(this);
          TableColumnModel newModel = (TableColumnModel) e.getNewValue();
          newModel.addColumnModelListener(this);
        }
      else if (propName.equals("selectionModel"))
        {
          ListSelectionModel oldModel = (ListSelectionModel) e.getOldValue();
          oldModel.removeListSelectionListener(this);
          ListSelectionModel newModel = (ListSelectionModel) e.getNewValue();
          newModel.addListSelectionListener(this);
        }
      else if (propName.equals("cellEditor"))
        {
          CellEditor oldEd = (CellEditor) e.getOldValue();
          oldEd.removeCellEditorListener(this);
          CellEditor newEd = (CellEditor) e.getNewValue();
          newEd.addCellEditorListener(this);
        }
    }

    /**
     * Returns the row number of an accessible child (cell) with the specified
     * index.
     *
     * @param index the index of the cell of which the row number is queried
     * 
     * @return the row number of an accessible child (cell) with the specified
     *         index 
     */
    public int getAccessibleRow(int index)
    {
      return getAccessibleRowAtIndex(index);
    }

    /**
     * Returns the column number of an accessible child (cell) with the
     * specified index.
     *
     * @param index the index of the cell of which the column number is queried
     * 
     * @return the column number of an accessible child (cell) with the
     *         specified index 
     */
    public int getAccessibleColumn(int index)
    {
      return getAccessibleColumnAtIndex(index);
    }

    /**
     * Returns the index of the accessible child at the specified row and
     * column.
     *
     * @param r the row number
     * @param c the column number
     *
     * @return the index of the accessible child at the specified row and
     *         column
     */
    public int getAccessibleIndex(int r, int c)
    {
      return getAccessibleIndexAt(r, c);
    }

    /**
     * Returns the caption of the table.
     *
     * @return the caption of the table
     *
     * @see #setAccessibleCaption(Accessible)
     */
    public Accessible getAccessibleCaption()
    {
      return caption;
    }

    /**
     * Sets the caption for the table.
     *
     * @param c the caption to set
     */
    public void setAccessibleCaption(Accessible c)
    {
      caption = c;
    }

    /**
     * Returns the summary for the table.
     *
     * @return the summary for the table
     */
    public Accessible getAccessibleSummary()
    {
      return summary;
    }

    /**
     * Sets the summary for the table.
     *
     * @param s the summary to set
     */
    public void setAccessibleSummary(Accessible s)
    {
      summary = s;
    }

    /**
     * Returns the number of rows in the table.
     *
     * @return the number of rows in the table
     */
    public int getAccessibleRowCount()
    {
      return getRowCount();
    }

    /**
     * Returns the number of columns in the table.
     *
     * @return the number of columns in the table
     */
    public int getAccessibleColumnCount()
    {
      return getColumnCount();
    }

    /**
     * Returns the accessible child at the given index.
     *
     * @param index  the child index.
     * 
     * @return The accessible child.
     */
    public Accessible getAccessibleChild(int index)
    {
      int r = getAccessibleRow(index);
      int c = getAccessibleColumn(index);
      return getAccessibleAt(r, c);  
    }
    
    /**
     * Returns the accessible child (table cell) at the specified row and
     * column.
     *
     * @param r the row number
     * @param c the column number
     *
     * @return the accessible child (table cell) at the specified row and
     *         column
     */
    public Accessible getAccessibleAt(int r, int c)
    {
      TableCellRenderer cellRenderer = getCellRenderer(r, c);
      Component renderer = cellRenderer.getTableCellRendererComponent(
          JTable.this, getValueAt(r, c), isCellSelected(r, c), false, r, c);
      if (renderer instanceof Accessible)
        return (Accessible) renderer;
      return null;
    }

    /**
     * Returns the number of rows that the specified cell occupies. The
     * standard table cells only occupy one row, so we return <code>1</code>
     * here.
     *
     * @param r the row number
     * @param c the column number
     *
     * @return the number of rows that the specified cell occupies
     */
    public int getAccessibleRowExtentAt(int r, int c)
    {
      return 1;
    }

    /**
     * Returns the number of columns that the specified cell occupies. The
     * standard table cells only occupy one column, so we return <code>1</code>
     * here.
     *
     * @param r the row number
     * @param c the column number
     *
     * @return the number of rows that the specified cell occupies
     */
    public int getAccessibleColumnExtentAt(int r, int c)
    {
      return 1;
    }

    /**
     * Returns the accessible row header.
     *
     * @return the accessible row header
     */
    public AccessibleTable getAccessibleRowHeader()
    {
      // The RI seems to always return null here, so do we.
      return null;
    }

    /**
     * Sets the accessible row header.
     *
     * @param header the header to set
     */
    public void setAccessibleRowHeader(AccessibleTable header)
    {
      // In the RI this seems to be a no-op.    
    }

    /**
     * Returns the column header.
     *
     * @return the column header, or <code>null</code> if there is no column
     *         header
     */
    public AccessibleTable getAccessibleColumnHeader()
    {
      JTableHeader h = getTableHeader();
      AccessibleTable header = null;
      if (h != null)
        header = new AccessibleTableHeader(h);
      return header;
    }

    /**
     * Sets the accessible column header. The default implementation doesn't
     * allow changing the header this way, so this is a no-op.
     *
     * @param header the accessible column header to set
     */
    public void setAccessibleColumnHeader(AccessibleTable header)
    {
      // The RI doesn't seem to do anything, so we also do nothing.
    }

    /**
     * Returns the accessible description for the row with the specified index,
     * or <code>null</code> if no description has been set.
     *
     * @param r the row for which the description is queried
     *
     * @return the accessible description for the row with the specified index,
     *         or <code>null</code> if no description has been set
     */
    public Accessible getAccessibleRowDescription(int r)
    {
      Accessible descr = null;
      if (rowDescriptions != null)
        descr = rowDescriptions[r];
      return descr;
    }

    /**
     * Sets the accessible description for the row with the specified index.
     *
     * @param r the row number for which to set the description
     * @param description the description to set
     */
    public void setAccessibleRowDescription(int r, Accessible description)
    {
      if (rowDescriptions == null)
        rowDescriptions = new Accessible[getAccessibleRowCount()];
      rowDescriptions[r] = description;
    }

    /**
     * Returns the accessible description for the column with the specified
     * index, or <code>null</code> if no description has been set.
     *
     * @param c the column for which the description is queried
     *
     * @return the accessible description for the column with the specified
     *         index, or <code>null</code> if no description has been set
     */
    public Accessible getAccessibleColumnDescription(int c)
    {
      Accessible descr = null;
      if (columnDescriptions != null)
        descr = columnDescriptions[c];
      return descr;
    }

    /**
     * Sets the accessible description for the column with the specified index.
     *
     * @param c the column number for which to set the description
     * @param description the description to set
     */
    public void setAccessibleColumnDescription(int c, Accessible description)
    {
      if (columnDescriptions == null)
        columnDescriptions = new Accessible[getAccessibleRowCount()];
      columnDescriptions[c] = description;
    }

    /**
     * Returns <code>true</code> if the accessible child at the specified
     * row and column is selected, <code>false</code> otherwise.
     *
     * @param r the row number of the child
     * @param c the column number of the child
     *
     * @return <code>true</code> if the accessible child at the specified
     *         row and column is selected, <code>false</code> otherwise
     */
    public boolean isAccessibleSelected(int r, int c)
    {
      return isCellSelected(r, c);
    }

    /**
     * Returns <code>true</code> if the row with the specified index is
     * selected, <code>false</code> otherwise.
     *
     * @param r the row number
     *
     * @return <code>true</code> if the row with the specified index is
     *        selected, <code>false</code> otherwise
     */
    public boolean isAccessibleRowSelected(int r)
    {
      return isRowSelected(r);
    }

    /**
     * Returns <code>true</code> if the column with the specified index is
     * selected, <code>false</code> otherwise.
     *
     * @param c the column number
     *
     * @return <code>true</code> if the column with the specified index is
     *        selected, <code>false</code> otherwise
     */
    public boolean isAccessibleColumnSelected(int c)
    {
      return isColumnSelected(c);
    }

    /**
     * Returns the indices of all selected rows.
     *
     * @return the indices of all selected rows
     */
    public int[] getSelectedAccessibleRows()
    {
      return getSelectedRows();
    }

    /**
     * Returns the indices of all selected columns.
     *
     * @return the indices of all selected columns
     */
    public int[] getSelectedAccessibleColumns()
    {
      return getSelectedColumns();
    }

    /**
     * Returns the accessible row at the specified index.
     *
     * @param index the index for which to query the row
     *
     * @return the row number at the specified table index
     */
    public int getAccessibleRowAtIndex(int index)
    {
      // TODO: Back this up by a Mauve test and update API docs accordingly.
      return index / getColumnCount();
    }

    /**
     * Returns the accessible column at the specified index.
     *
     * @param index the index for which to query the column
     *
     * @return the column number at the specified table index
     */
    public int getAccessibleColumnAtIndex(int index)
    {
      // TODO: Back this up by a Mauve test and update API docs accordingly.
      return index % getColumnCount();
    }

    /**
     * Returns the accessible child index at the specified column and row.
     *
     * @param row the row
     * @param column the column
     *
     * @return the index of the accessible child at the specified row and
     *         column
     */
    public int getAccessibleIndexAt(int row, int column)
    {
      // TODO: Back this up by a Mauve test and update API docs accordingly.
      return row * getColumnCount() + column;
    }
  }
  /**
   * Handles property changes from the <code>TableColumn</code>s of this
   * <code>JTable</code>.
   *
   * More specifically, this triggers a {@link #revalidate()} call if the
   * preferredWidth of one of the observed columns changes.
   */
  class TableColumnPropertyChangeHandler implements PropertyChangeListener
  {
    /**
     * Receives notification that a property of the observed TableColumns has
     * changed.
     * 
     * @param ev the property change event
     */
    public void propertyChange(PropertyChangeEvent ev)
    {
      if (ev.getPropertyName().equals("preferredWidth"))
        {
          JTableHeader header = getTableHeader();
          if (header != null)
            // Do nothing if the table is in the resizing mode.
            if (header.getResizingColumn() == null)
              {
                TableColumn col = (TableColumn) ev.getSource();
                header.setResizingColumn(col);
                doLayout();
                header.setResizingColumn(null);
              }
        }
    }
  }

  /**
   * A cell renderer for boolean values.
   */
  private class BooleanCellRenderer
    extends DefaultTableCellRenderer
  {
    /**
     * The CheckBox that is used for rendering.
     */
    private final JCheckBox checkBox;
    
    /**
     * Creates a new checkbox based boolean cell renderer. The checkbox is
     * centered by default.
     */
    BooleanCellRenderer()
    {
       checkBox = new JCheckBox();
       checkBox.setHorizontalAlignment(SwingConstants.CENTER);
    }
   
    /**
     * Get the check box.
     */
    JCheckBox getCheckBox()
    {
      return checkBox;
    }

    /**
     * Returns the component that is used for rendering the value.
     * 
     * @param table the JTable
     * @param value the value of the object
     * @param isSelected is the cell selected?
     * @param hasFocus has the cell the focus?
     * @param row the row to render
     * @param column the cell to render
     * @return this component (the default table cell renderer)
     */
    public Component getTableCellRendererComponent(JTable table, Object value,
                                                   boolean isSelected,
                                                   boolean hasFocus, int row,
                                                   int column)
    {
      if (isSelected)
        {
          checkBox.setBackground(table.getSelectionBackground());
          checkBox.setForeground(table.getSelectionForeground());
        }
      else
        {
          checkBox.setBackground(table.getBackground());
          checkBox.setForeground(table.getForeground());
        }

      if (hasFocus)
        {
          checkBox.setBorder(
            UIManager.getBorder("Table.focusCellHighlightBorder"));
          if (table.isCellEditable(row, column))
            {
              checkBox.setBackground(
                UIManager.getColor("Table.focusCellBackground"));
              checkBox.setForeground(
                UIManager.getColor("Table.focusCellForeground"));
            }
        }
      else
        checkBox.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));

      // Null is rendered as false.
      if (value == null)
        checkBox.setSelected(false);
      else
        {
          Boolean boolValue = (Boolean) value;
          checkBox.setSelected(boolValue.booleanValue());
        }
      return checkBox;
    }
  }

  /**
   * A cell renderer for Date values.
   */
  private class DateCellRenderer
    extends DefaultTableCellRenderer
  {
    /**
     * Returns the component that is used for rendering the value.
     *
     * @param table the JTable
     * @param value the value of the object
     * @param isSelected is the cell selected?
     * @param hasFocus has the cell the focus?
     * @param row the row to render
     * @param column the cell to render
     * 
     * @return this component (the default table cell renderer)
     */
    public Component getTableCellRendererComponent(JTable table, Object value,
                                                   boolean isSelected,
                                                   boolean hasFocus, int row,
                                                   int column)
    {
      super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
                                          row, column);
      if (value instanceof Date)
        {
          Date dateValue = (Date) value;
          DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
          setText(df.format(dateValue));
        }
      return this;
    }
  }

  /**
   * A cell renderer for Double values.
   */
  private class DoubleCellRenderer
    extends DefaultTableCellRenderer
  {
    /**
     * Creates a new instance of NumberCellRenderer.
     */
    public DoubleCellRenderer()
    {
      setHorizontalAlignment(JLabel.RIGHT);
    }

    /**
     * Returns the component that is used for rendering the value.
     *
     * @param table the JTable
     * @param value the value of the object
     * @param isSelected is the cell selected?
     * @param hasFocus has the cell the focus?
     * @param row the row to render
     * @param column the cell to render
     * 
     * @return this component (the default table cell renderer)
     */
    public Component getTableCellRendererComponent(JTable table, Object value,
                                                   boolean isSelected,
                                                   boolean hasFocus, int row,
                                                   int column)
    {
      super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
                                          row, column);
      if (value instanceof Double)
        {
          Double doubleValue = (Double) value;
          NumberFormat nf = NumberFormat.getInstance();
          setText(nf.format(doubleValue.doubleValue()));
        }
      return this;
    }
  }

  /**
   * A cell renderer for Float values.
   */
  private class FloatCellRenderer
    extends DefaultTableCellRenderer
  {
    /**
     * Creates a new instance of NumberCellRenderer.
     */
    public FloatCellRenderer()
    {
      setHorizontalAlignment(JLabel.RIGHT);
    }

    /**
     * Returns the component that is used for rendering the value.
     *
     * @param table the JTable
     * @param value the value of the object
     * @param isSelected is the cell selected?
     * @param hasFocus has the cell the focus?
     * @param row the row to render
     * @param column the cell to render
     * 
     * @return this component (the default table cell renderer)
     */
    public Component getTableCellRendererComponent(JTable table, Object value,
                                                   boolean isSelected,
                                                   boolean hasFocus, int row,
                                                   int column)
    {
      super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
                                          row, column);
      if (value instanceof Float)
        {
          Float floatValue = (Float) value;
          NumberFormat nf = NumberFormat.getInstance();
          setText(nf.format(floatValue.floatValue()));
        }
      return this;
    }
  }

  /**
   * A cell renderer for Number values.
   */
  private class NumberCellRenderer
    extends DefaultTableCellRenderer
  {
    /**
     * Creates a new instance of NumberCellRenderer.
     */
    public NumberCellRenderer()
    {
      setHorizontalAlignment(JLabel.RIGHT);
    }
  }

  /**
   * A cell renderer for Icon values.
   */
  private class IconCellRenderer
    extends DefaultTableCellRenderer
  {
    IconCellRenderer()
    {
      setHorizontalAlignment(SwingConstants.CENTER);
    }
    
    
    /**
     * Returns the component that is used for rendering the value.
     *
     * @param table the JTable
     * @param value the value of the object
     * @param isSelected is the cell selected?
     * @param hasFocus has the cell the focus?
     * @param row the row to render
     * @param column the cell to render
     * 
     * @return this component (the default table cell renderer)
     */
    public Component getTableCellRendererComponent(JTable table, Object value,
                                                   boolean isSelected,
                                                   boolean hasFocus, int row,
                                                   int column)
    {
      super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
                                          row, column);
      if (value instanceof Icon)
        {
          Icon iconValue = (Icon) value;
          setIcon(iconValue);
        }
      else
        {
          setIcon(null);
        }
      setText("");
      return this;
    }
  }
  
    /**
     * The JTable text component (used in editing) always has the table
     * as its parent. The scrollRectToVisible must be adjusted taking the
     * relative component position.
     *
     * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
     */
    private class TableTextField extends JTextField
    {
      /**
       * Create the text field without the border.
       */
      TableTextField()
      {
        setBorder(BorderFactory.createLineBorder(getGridColor(), 2));
      }
    }    
  

  private static final long serialVersionUID = 3876025080382781659L;
  
  /**
   * This table, for referring identically name methods from inner classes.
   */
  final JTable this_table = this;


  /**
   * When resizing columns, do not automatically change any columns. In this
   * case the table should be enclosed in a {@link JScrollPane} in order to
   * accomodate cases in which the table size exceeds its visible area.
   */
  public static final int AUTO_RESIZE_OFF = 0;

  /**
   * When resizing column <code>i</code>, automatically change only the
   * single column <code>i+1</code> to provide or absorb excess space
   * requirements.
   */
  public static final int AUTO_RESIZE_NEXT_COLUMN = 1;

  /**
   * When resizing column <code>i</code> in a table of <code>n</code>
   * columns, automatically change all columns in the range <code>[i+1,
   * n)</code>, uniformly, to provide or absorb excess space requirements.
   */
  public static final int AUTO_RESIZE_SUBSEQUENT_COLUMNS = 2;
  
  /**
   * When resizing column <code>i</code> in a table of <code>n</code>
   * columns, automatically change all columns in the range <code>[0,
   * n)</code> (with the exception of column i) uniformly, to provide or
   * absorb excess space requirements.
   */
  public static final int AUTO_RESIZE_ALL_COLUMNS = 4;

  /**
   * When resizing column <code>i</code> in a table of <code>n</code>
   * columns, automatically change column <code>n-1</code> (the last column
   * in the table) to provide or absorb excess space requirements.
   */
  public static final int AUTO_RESIZE_LAST_COLUMN = 3;

  /**
   * A table mapping {@link java.lang.Class} objects to 
   * {@link TableCellEditor} objects. This table is consulted by the 
   * FIXME
   */
  protected Hashtable defaultEditorsByColumnClass = new Hashtable();

  /**
   * A table mapping {@link java.lang.Class} objects to 
   * {@link TableCellEditor} objects. This table is consulted by the 
   * FIXME
   */
  protected Hashtable defaultRenderersByColumnClass = new Hashtable();

  /**
   * The column that is edited, -1 if the table is not edited currently.
   */
  protected int editingColumn;

  /**
   * The row that is edited, -1 if the table is not edited currently.
   */
  protected int editingRow;

  /**
   * The component that is used for editing.
   * <code>null</code> if the table is not editing currently.
   *
   */
  protected transient Component editorComp;


  /**
   * Whether or not the table should automatically compute a matching
   * {@link TableColumnModel} and assign it to the {@link #columnModel}
   * property when the {@link #dataModel} property is changed. 
   *
   * @see #setModel(TableModel)
   * @see #createDefaultColumnsFromModel()
   * @see #setColumnModel(TableColumnModel)
   * @see #setAutoCreateColumnsFromModel(boolean)
   * @see #getAutoCreateColumnsFromModel()
   */
  protected boolean autoCreateColumnsFromModel;

  /**
   * A numeric code specifying the resizing behavior of the table. Must be
   * one of {@link #AUTO_RESIZE_ALL_COLUMNS} (the default), {@link
   * #AUTO_RESIZE_LAST_COLUMN}, {@link #AUTO_RESIZE_NEXT_COLUMN}, {@link
   * #AUTO_RESIZE_SUBSEQUENT_COLUMNS}, or {@link #AUTO_RESIZE_OFF}.
   * 
   * @see #doLayout()
   * @see #setAutoResizeMode(int)
   * @see #getAutoResizeMode()
   */
  protected int autoResizeMode;

  /**
   * The height in pixels of any row of the table. All rows in a table are
   * of uniform height. This differs from column width, which varies on a
   * per-column basis, and is stored in the individual columns of the
   * {@link #columnModel}.
   * 
   * @see #getRowHeight()
   * @see #setRowHeight(int)
   * @see TableColumn#getWidth()
   * @see TableColumn#setWidth(int)
   */
  protected int rowHeight;

  /**
   * The height in pixels of the gap left between any two rows of the table. 
   * 
   * @see #setRowMargin(int)
   * @see #getRowHeight()
   * @see #getIntercellSpacing()
   * @see #setIntercellSpacing(Dimension)
   * @see TableColumnModel#getColumnMargin()
   * @see TableColumnModel#setColumnMargin(int)
   */
  protected int rowMargin;

  /**
   * Whether or not the table should allow row selection. If the table
   * allows both row <em>and</em> column selection, it is said to allow
   * "cell selection". Previous versions of the JDK supported cell
   * selection as an independent concept, but it is now represented solely
   * in terms of simultaneous row and column selection.
   *
   * @see TableColumnModel#getColumnSelectionAllowed()
   * @see #setRowSelectionAllowed(boolean)
   * @see #getRowSelectionAllowed()
   * @see #getCellSelectionEnabled()
   * @see #setCellSelectionEnabled(boolean)
   */
  protected boolean rowSelectionAllowed;

  /**
   * Obsolete. Use {@link #rowSelectionAllowed}, {@link 
   * #getColumnSelectionAllowed}, or the combined methods {@link
   * #getCellSelectionEnabled} and {@link #setCellSelectionEnabled(boolean)}.
   */
  protected boolean cellSelectionEnabled;
  
  /**
   * The model for data stored in the table. Confusingly, the published API
   * requires that this field be called <code>dataModel</code>, despite its
   * property name. The table listens to its model as a {@link
   * TableModelListener}.
   *
   * @see #tableChanged(TableModelEvent)
   * @see TableModel#addTableModelListener(TableModelListener)
   */
  protected TableModel dataModel;

  /**
   * <p>A model of various aspects of the columns of the table, <em>not
   * including</em> the data stored in them. The {@link TableColumnModel}
   * is principally concerned with holding a set of {@link TableColumn}
   * objects, each of which describes the display parameters of a column
   * and the numeric index of the column from the data model which the
   * column is presenting.</p>
   *
   * <p>The TableColumnModel also contains a {@link ListSelectionModel} which
   * indicates which columns are currently selected. This selection model
   * works in combination with the {@link #selectionModel} of the table
   * itself to specify a <em>table selection</em>: a combination of row and
   * column selections.</p>
   *
   * <p>Most application programmers do not need to work with this property
   * at all: setting {@link #autoCreateColumnsFromModel} will construct the
   * columnModel automatically, and the table acts as a facade for most of
   * the interesting properties of the columnModel anyways.</p>
   * 
   * @see #setColumnModel(TableColumnModel)
   * @see #getColumnModel()
   */
  protected TableColumnModel columnModel;

  /**
   * A model of the rows of this table which are currently selected. This
   * model is used in combination with the column selection model held as a
   * member of the {@link #columnModel} property, to represent the rows and
   * columns (or both: cells) of the table which are currently selected.
   *
   * @see #rowSelectionAllowed
   * @see #setSelectionModel(ListSelectionModel)
   * @see #getSelectionModel()
   * @see TableColumnModel#getSelectionModel()
   * @see ListSelectionModel#addListSelectionListener(ListSelectionListener)   
   */
  protected ListSelectionModel selectionModel;

  /**
   * The current cell editor. 
   */
  protected TableCellEditor cellEditor;

  /**
   * Whether or not drag-and-drop is enabled on this table.
   *
   * @see #setDragEnabled(boolean)
   * @see #getDragEnabled()
   */
  private boolean dragEnabled;

  /**
   * The color to paint the grid lines of the table, when either {@link
   * #showHorizontalLines} or {@link #showVerticalLines} is set.
   *
   * @see #setGridColor(Color)
   * @see #getGridColor()
   */
  protected Color gridColor;

  /**
   * The size this table would prefer its viewport assume, if it is
   * contained in a {@link JScrollPane}.
   *
   * @see #setPreferredScrollableViewportSize(Dimension)
   * @see #getPreferredScrollableViewportSize()
   */
  protected Dimension preferredViewportSize;

  /**
   * The color to paint the background of selected cells. Fires a property
   * change event with name {@link #SELECTION_BACKGROUND_CHANGED_PROPERTY}
   * when its value changes.
   *
   * @see #setSelectionBackground(Color)
   * @see #getSelectionBackground()
   */
  protected Color selectionBackground;

  /**
   * The name carried in property change events when the {@link
   * #selectionBackground} property changes.
   */
  private static final String SELECTION_BACKGROUND_CHANGED_PROPERTY = "selectionBackground";

  /**
   * The color to paint the foreground of selected cells. Fires a property
   * change event with name {@link #SELECTION_FOREGROUND_CHANGED_PROPERTY}
   * when its value changes.
   *
   * @see #setSelectionForeground(Color)
   * @see #getSelectionForeground()
   */
  protected Color selectionForeground;

  /**
   * The name carried in property change events when the
   * {@link #selectionForeground} property changes.
   */
  private static final String SELECTION_FOREGROUND_CHANGED_PROPERTY = "selectionForeground";

  /**
   * The showHorizontalLines property.
   */
  protected boolean showHorizontalLines;

  /**
   * The showVerticalLines property.
   */
  protected boolean showVerticalLines;

  /**
   * The tableHeader property.
   */
  protected JTableHeader tableHeader;

  /**
   * The property handler for this table's columns.
   */
  TableColumnPropertyChangeHandler tableColumnPropertyChangeHandler =
    new TableColumnPropertyChangeHandler();

  /**
   * Whether cell editors should receive keyboard focus when the table is
   * activated.
   */
  private boolean surrendersFocusOnKeystroke = false;

  /**
   * A Rectangle object to be reused in {@link #getCellRect}. 
   */
  private Rectangle rectCache = new Rectangle();

  /**
   * Indicates if the rowHeight property has been set by a client program or by
   * the UI.
   *
   * @see #setUIProperty(String, Object)
   * @see LookAndFeel#installProperty(JComponent, String, Object)
   */
  private boolean clientRowHeightSet = false;

  /**
   * Stores the sizes and positions of each row, when using non-uniform row
   * heights. Initially the height of all rows is equal and stored in
   * {link #rowHeight}. However, when an application calls
   * {@link #setRowHeight(int,int)}, the table switches to non-uniform
   * row height mode which stores the row heights in the SizeSequence
   * object instead.
   *
   * @see #setRowHeight(int)
   * @see #getRowHeight()
   * @see #getRowHeight(int)
   * @see #setRowHeight(int, int)
   */
  private SizeSequence rowHeights;
  
  /**
   * This editor serves just a marker that the value must be simply changed to
   * the opposite one instead of starting the editing session.
   */
  private transient TableCellEditor booleanInvertingEditor; 
  
  /**
   * Creates a new <code>JTable</code> instance.
   */
  public JTable ()
  {
    this(null, null, null);
  }

  /**
   * Creates a new <code>JTable</code> instance with the given number
   * of rows and columns.
   *
   * @param numRows an <code>int</code> value
   * @param numColumns an <code>int</code> value
   */
  public JTable (int numRows, int numColumns)
  {
    this(new DefaultTableModel(numRows, numColumns));
  }

  /**
   * Creates a new <code>JTable</code> instance, storing the given data 
   * array and heaving the given column names. To see the column names,
   * you must place the JTable into the {@link JScrollPane}.
   *
   * @param data an <code>Object[][]</code> the table data
   * @param columnNames an <code>Object[]</code> the column headers
   */
  public JTable(Object[][] data, Object[] columnNames)
  {
    this(new DefaultTableModel(data, columnNames));
  }

  /**
   * Creates a new <code>JTable</code> instance, using the given data model
   * object that provides information about the table content. The table model
   * object is asked for the table size, other features and also receives
   * notifications in the case when the table has been edited by the user.
   * 
   * @param model
   *          the table model.
   */
  public JTable (TableModel model)
  {
    this(model, null, null);
  }

  /**
   * Creates a new <code>JTable</code> instance, using the given model object
   * that provides information about the table content. The table data model
   * object is asked for the table size, other features and also receives
   * notifications in the case when the table has been edited by the user. The
   * table column model provides more detailed control on the table column
   * related features.
   * 
   * @param dm
   *          the table data mode
   * @param cm
   *          the table column model
   */
  public JTable (TableModel dm, TableColumnModel cm)
  {
    this(dm, cm, null);
  }

  /**
   * Creates a new <code>JTable</code> instance, providing data model,
   * column model and list selection model. The list selection model
   * manages the selections.
   *
   * @param dm data model (manages table data)
   * @param cm column model (manages table columns)
   * @param sm list selection model (manages table selections)
   */
  public JTable (TableModel dm, TableColumnModel cm, ListSelectionModel sm)
  {
    boolean autoCreate = false;
    TableColumnModel columnModel;
    if (cm != null)
        columnModel = cm;
    else 
      {
        columnModel = createDefaultColumnModel();
        autoCreate = true;
      }
    
    // Initialise the intercelar spacing before setting the column model to
    // avoid firing unnecessary events.
    // The initial incellar spacing is new Dimenstion(1,1). 
    rowMargin = 1;
    columnModel.setColumnMargin(1);
    setColumnModel(columnModel);
    
    setSelectionModel(sm == null ? createDefaultSelectionModel() : sm);
    setModel(dm == null ? createDefaultDataModel() : dm);
    setAutoCreateColumnsFromModel(autoCreate);
    initializeLocalVars();
    // The following four lines properly set the lead selection indices.
    // After this, the UI will handle the lead selection indices.
    // FIXME: this should probably not be necessary, if the UI is installed
    // before the TableModel is set then the UI will handle things on its
    // own, but certain variables need to be set before the UI can be installed
    // so we must get the correct order for all the method calls in this
    // constructor.
    selectionModel.setAnchorSelectionIndex(0);    
    selectionModel.setLeadSelectionIndex(0);
    columnModel.getSelectionModel().setAnchorSelectionIndex(0);
    columnModel.getSelectionModel().setLeadSelectionIndex(0);
    updateUI();
  }
  
  /**
   * Creates a new <code>JTable</code> instance that uses data and column
   * names, stored in {@link Vector}s.
   *
   * @param data the table data
   * @param columnNames the table column names.
   */
  public JTable(Vector data, Vector columnNames)
  {
    this(new DefaultTableModel(data, columnNames));
  }  
  
  /**
   * Initialize local variables to default values.
   */
  protected void initializeLocalVars()
  {
    setTableHeader(createDefaultTableHeader());
    if (autoCreateColumnsFromModel)
      createDefaultColumnsFromModel();
    this.columnModel.addColumnModelListener(this);

    this.autoResizeMode = AUTO_RESIZE_SUBSEQUENT_COLUMNS;
    setRowHeight(16);
    this.rowMargin = 1;
    this.rowSelectionAllowed = true;
    // this.accessibleContext = new AccessibleJTable();
    this.cellEditor = null;
    // COMPAT: Both Sun and IBM have drag enabled
    this.dragEnabled = true;
    this.preferredViewportSize = new Dimension(450,400);
    this.showHorizontalLines = true;
    this.showVerticalLines = true;
    this.editingColumn = -1;
    this.editingRow = -1;
  }
  
  /**
   * Add the new table column. The table column class allows to specify column
   * features more precisely, setting the preferred width, column data type
   * (column class) and table headers.
   * 
   * There is no need the add columns to the table if the default column 
   * handling is sufficient.
   * 
   * @param column
   *          the new column to add.
   */
  public void addColumn(TableColumn column)
  {
    if (column.getHeaderValue() == null)
      {
        String name = dataModel.getColumnName(column.getModelIndex());
        column.setHeaderValue(name);
      }
    
    columnModel.addColumn(column);
    column.addPropertyChangeListener(tableColumnPropertyChangeHandler);
  }
  
  /**
   * Create the default editors for this table. The default method creates
   * the editor for Booleans.
   * 
   * Other fields are edited as strings at the moment.
   */
  protected void createDefaultEditors()
  {
    JCheckBox box = new BooleanCellRenderer().getCheckBox();
    box.setBorder(BorderFactory.createLineBorder(getGridColor(), 2));
    box.setBorderPainted(true);
    booleanInvertingEditor = new DefaultCellEditor(box);    
    setDefaultEditor(Boolean.class, booleanInvertingEditor);
  }
  
  /**
   * Create the default renderers for this table. The default method creates
   * renderers for Boolean, Number, Double, Date, Icon and ImageIcon.
   *
   */
  protected void createDefaultRenderers()
  {
    setDefaultRenderer(Boolean.class, new BooleanCellRenderer());
    setDefaultRenderer(Number.class, new NumberCellRenderer());
    setDefaultRenderer(Double.class, new DoubleCellRenderer());
    setDefaultRenderer(Double.class, new FloatCellRenderer());
    setDefaultRenderer(Date.class, new DateCellRenderer());
    setDefaultRenderer(Icon.class, new IconCellRenderer());
    setDefaultRenderer(ImageIcon.class, new IconCellRenderer());    
  }
  
  /**
   * @deprecated 1.0.2, replaced by <code>new JScrollPane(JTable)</code>
   */
  public static JScrollPane createScrollPaneForTable(JTable table)
  {
    return new JScrollPane(table);
  }
  
  /**
   * Create the default table column model that is used if the user-defined
   * column model is not provided. The default method creates
   * {@link DefaultTableColumnModel}.
   * 
   * @return the created table column model.
   */
  protected TableColumnModel createDefaultColumnModel()
  {
    return new DefaultTableColumnModel();
  }

  /**
   * Create the default table data model that is used if the user-defined
   * data model is not provided. The default method creates
   * {@link DefaultTableModel}.
   * 
   * @return the created table data model.
   */
  protected TableModel createDefaultDataModel()
  {
    return new DefaultTableModel();
  }

  /**
   * Create the default table selection model that is used if the user-defined
   * selection model is not provided. The default method creates
   * {@link DefaultListSelectionModel}.
   * 
   * @return the created table data model.
   */
  protected ListSelectionModel createDefaultSelectionModel()
  {
    return new DefaultListSelectionModel();
  }
  
  /**
   * Create the default table header, if the user - defined table header is not
   * provided.
   * 
   * @return the default table header.
   */
  protected JTableHeader createDefaultTableHeader()
  {
    return new JTableHeader(columnModel);
  }
  
  /**
   * Invoked when the column is added. Revalidates and repains the table.
   */
  public void columnAdded (TableColumnModelEvent event)
  {
    revalidate();
    repaint();
  }

  /**
   * Invoked when the column margin is changed. 
   * Revalidates and repains the table.
   */
  public void columnMarginChanged (ChangeEvent event)
  {
    revalidate();
    repaint();
  }

  /**
   * Invoked when the column is moved. Revalidates and repains the table.
   */
  public void columnMoved (TableColumnModelEvent event)
  {
    if (isEditing())
      editingCanceled(null);
    revalidate();
    repaint();
  }

  /**
   * Invoked when the column is removed. Revalidates and repains the table.
   */
  public void columnRemoved (TableColumnModelEvent event)
  {
    revalidate();
    repaint();
  }
  
  /**
   * Invoked when the the column selection changes, repaints the changed
   * columns. It is not recommended to override this method, register the
   * listener instead.
   */
  public void columnSelectionChanged (ListSelectionEvent event)
  {
    // We must limit the indices to the bounds of the JTable's model, because
    // we might get values of -1 or greater then columnCount in the case
    // when columns get removed.
    int idx0 = Math.max(0, Math.min(getColumnCount() - 1,
                                    event.getFirstIndex()));
    int idxn = Math.max(0, Math.min(getColumnCount() - 1,
                                    event.getLastIndex()));

    int minRow = 0;
    int maxRow = getRowCount() - 1;
    if (getRowSelectionAllowed())
      {
        minRow = selectionModel.getMinSelectionIndex();
        maxRow = selectionModel.getMaxSelectionIndex();
        int leadRow = selectionModel.getLeadSelectionIndex();
        if (minRow == -1 && maxRow == -1)
          {
            minRow = leadRow;
            maxRow = leadRow;
          }
        else
          {
            // In this case we need to repaint also the range to leadRow, not
            // only between min and max.
            if (leadRow != -1)
              {
                minRow = Math.min(minRow, leadRow);
                maxRow = Math.max(maxRow, leadRow);
              }
          }
      }
    if (minRow != -1 && maxRow != -1)
      {
        Rectangle first = getCellRect(minRow, idx0, false);
        Rectangle last = getCellRect(maxRow, idxn, false);
        Rectangle dirty = SwingUtilities.computeUnion(first.x, first.y,
                                                      first.width,
                                                      first.height, last);
        repaint(dirty);
      }
  }
 
  /**
   * Invoked when the editing is cancelled.
   */
  public void editingCanceled (ChangeEvent event)
  {
    if (editorComp!=null)
      {
        remove(editorComp);
        repaint(editorComp.getBounds());        
        editorComp = null;
      }
  }
  
  /**
   * Finish the current editing session and update the table with the
   * new value by calling {@link #setValueAt}.
   * 
   * @param event the change event
   */
  public void editingStopped (ChangeEvent event)
  {
    if (editorComp!=null)
      {
        remove(editorComp);        
        setValueAt(cellEditor.getCellEditorValue(), editingRow, editingColumn);            
        repaint(editorComp.getBounds());
        editorComp = null;
      }
    requestFocusInWindow();
  }

  /**
   * Invoked when the table changes.
   * <code>null</code> means everything changed.
   */
  public void tableChanged (TableModelEvent event)
  {
    // update the column model from the table model if the structure has
    // changed and the flag autoCreateColumnsFromModel is set
    if (event == null || (event.getFirstRow() == TableModelEvent.HEADER_ROW))
      handleCompleteChange(event);
    else if (event.getType() == TableModelEvent.INSERT)
      handleInsert(event);
    else if (event.getType() == TableModelEvent.DELETE)
      handleDelete(event);
    else
      handleUpdate(event);
  }

  /**
   * Handles a request for complete relayout. This is the case when
   * event.getFirstRow() == TableModelEvent.HEADER_ROW.
   *
   * @param ev the table model event
   */
  private void handleCompleteChange(TableModelEvent ev)
  {
    clearSelection();
    checkSelection();
    rowHeights = null;
    if (getAutoCreateColumnsFromModel())
      createDefaultColumnsFromModel();
    else
      resizeAndRepaint();
  }

  /**
   * Handles table model insertions.
   *
   * @param ev the table model event
   */
  private void handleInsert(TableModelEvent ev)
  {
    // Sync selection model with data model.
    int first = ev.getFirstRow();
    if (first < 0)
      first = 0;
    int last = ev.getLastRow();
    if (last < 0)
      last = getRowCount() - 1;
    selectionModel.insertIndexInterval(first, last - first + 1, true);
    checkSelection();

    // For variable height rows we must update the SizeSequence thing.
    if (rowHeights != null)
      {
        rowHeights.insertEntries(first, last - first + 1, rowHeight);
        // TODO: We repaint the whole thing when the rows have variable
        // heights. We might want to handle this better though.
        repaint();
      }
    else
      {
        // Repaint the dirty region and revalidate.
        int rowHeight = getRowHeight();
        Rectangle dirty = new Rectangle(0, first * rowHeight,
                                        getColumnModel().getTotalColumnWidth(),
                                        (getRowCount() - first) * rowHeight);
        repaint(dirty);
      }
    revalidate();
  }

  /**
   * Handles table model deletions.
   *
   * @param ev the table model event
   */
  private void handleDelete(TableModelEvent ev)
  {
    // Sync selection model with data model.
    int first = ev.getFirstRow();
    if (first < 0)
      first = 0;
    int last = ev.getLastRow();
    if (last < 0)
      last = getRowCount() - 1;

    selectionModel.removeIndexInterval(first, last);

    checkSelection();

    if (dataModel.getRowCount() == 0)
      clearSelection();

    // For variable height rows we must update the SizeSequence thing.
    if (rowHeights != null)
      {
        rowHeights.removeEntries(first, last - first + 1);
        // TODO: We repaint the whole thing when the rows have variable
        // heights. We might want to handle this better though.
        repaint();
      }
    else
      {
        // Repaint the dirty region and revalidate.
        int rowHeight = getRowHeight();
        int oldRowCount = getRowCount() + last - first + 1;
        Rectangle dirty = new Rectangle(0, first * rowHeight,
                                        getColumnModel().getTotalColumnWidth(),
                                        (oldRowCount - first) * rowHeight);
        repaint(dirty);
      }
    revalidate();
  }

  /**
   * Handles table model updates without structural changes.
   *
   * @param ev the table model event
   */
  private void handleUpdate(TableModelEvent ev)
  {
    if (rowHeights == null)
      {
        // Some cells have been changed without changing the structure.
        // Figure out the dirty rectangle and repaint.
        int firstRow = ev.getFirstRow();
        int lastRow = ev.getLastRow();
        int col = ev.getColumn();
        Rectangle dirty;
        if (col == TableModelEvent.ALL_COLUMNS)
          {
            // All columns changed. 
            dirty = new Rectangle(0, firstRow * getRowHeight(),
                                  getColumnModel().getTotalColumnWidth(), 0);
          }
        else
          {
            // Only one cell or column of cells changed.
            // We need to convert to view column first.
            int column = convertColumnIndexToModel(col);
            dirty = getCellRect(firstRow, column, false);
          }

        // Now adjust the height of the dirty region.
        dirty.height = (lastRow + 1) * getRowHeight();
        // .. and repaint.
        repaint(dirty);
      }
    else
      {
        // TODO: We repaint the whole thing when the rows have variable
        // heights. We might want to handle this better though.
        repaint();
      }
  }

  /**
   * Helper method for adjusting the lead and anchor indices when the
   * table structure changed. This sets the lead and anchor to -1 if there's
   * no more rows, or set them to 0 when they were at -1 and there are actually
   * some rows now.
   */
  private void checkSelection()
  {
    TableModel m = getModel();
    ListSelectionModel sm = selectionModel;
    if (m != null)
      {
        int lead = sm.getLeadSelectionIndex();
        int c = m.getRowCount();
        if (c == 0 && lead != -1)
          {
            // No rows in the model, reset lead and anchor to -1.
            sm.setValueIsAdjusting(true);
            sm.setAnchorSelectionIndex(-1);
            sm.setLeadSelectionIndex(-1);
            sm.setValueIsAdjusting(false);
          }
        else if (c != 0 && lead == -1)
          {
            // We have rows, but no lead/anchor. Set them to 0. We
            // do a little trick here so that the actual selection is not
            // touched.
            if (sm.isSelectedIndex(0))
              sm.addSelectionInterval(0, 0);
            else
              sm.removeSelectionInterval(0, 0);
          }
        // Nothing to do in the other cases.
      }
  }

  /**
   * Invoked when another table row is selected. It is not recommended
   * to override thid method, register the listener instead.
   */
  public void valueChanged (ListSelectionEvent event)
  {
    // If we are in the editing process, end the editing session.
    if (isEditing())
      editingStopped(null);
    
    // Repaint the changed region.
    int first = Math.max(0, Math.min(getRowCount() - 1, event.getFirstIndex()));
    int last = Math.max(0, Math.min(getRowCount() - 1, event.getLastIndex()));
    Rectangle rect1 = getCellRect(first, 0, false);
    Rectangle rect2 = getCellRect(last, getColumnCount() - 1, false);
    Rectangle dirty = SwingUtilities.computeUnion(rect2.x, rect2.y,
                                                  rect2.width, rect2.height,
                                                  rect1);
    repaint(dirty);
  }

 /**
   * Returns index of the column that contains specified point 
   * or -1 if this table doesn't contain this point.
   *
   * @param point point to identify the column
   * @return index of the column that contains specified point or 
   * -1 if this table doesn't contain this point.
   */
  public int columnAtPoint(Point point)
  {
    int ncols = getColumnCount();
    Dimension gap = getIntercellSpacing();
    TableColumnModel cols = getColumnModel();
    int x = point.x;

    for (int i = 0; i < ncols; ++i)
      {
        int width = cols.getColumn(i).getWidth()
                    + (gap == null ? 0 : gap.width);
        if (0 <= x && x < width)
          return i;
        x -= width;
      }
    return -1;
  }

  /**
   * Returns index of the row that contains specified point or -1 if this table
   * doesn't contain this point.
   * 
   * @param point point to identify the row
   * @return index of the row that contains specified point or -1 if this table
   *         doesn't contain this point.
   */
  public int rowAtPoint(Point point)
  {
    if (point != null)
      {
        int nrows = getRowCount();
        int r;
        int y = point.y;
        if (rowHeights == null)
          {
            int height = getRowHeight();
            r = y / height;
          }
        else
          r = rowHeights.getIndex(y);

        if (r < 0 || r >= nrows)
          return -1;
        else
          return r;
      }
    else
      return -1;
  }

  /** 
   * Calculate the visible rectangle for a particular row and column. The
   * row and column are specified in visual terms; the column may not match
   * the {@link #dataModel} column.
   *
   * @param row the visible row to get the cell rectangle of
   *
   * @param column the visible column to get the cell rectangle of, which may
   * differ from the {@link #dataModel} column
   *
   * @param includeSpacing whether or not to include the cell margins in the
   * resulting cell. If <code>false</code>, the result will only contain the
   * inner area of the target cell, not including its margins.
   *
   * @return a rectangle enclosing the specified cell
   */
  public Rectangle getCellRect(int row,
                               int column,
                               boolean includeSpacing)
  {
    Rectangle cellRect = new Rectangle(0, 0, 0, 0);

    // Check for valid range vertically.
    if (row >= getRowCount())
      {
        cellRect.height = getHeight();
      }
    else if (row >= 0)
      {
        cellRect.height = getRowHeight(row);
        if (rowHeights == null)
          cellRect.y = row * cellRect.height;
        else
          cellRect.y = rowHeights.getPosition(row);

        if (! includeSpacing)
          {
            // The rounding here is important.
            int rMargin = getRowMargin();
            cellRect.y += rMargin / 2;
            cellRect.height -= rMargin;
          }
      }
    // else row < 0, y = height = 0

    // Check for valid range horizontally.
    if (column < 0)
      {
        if (! getComponentOrientation().isLeftToRight())
          {
            cellRect.x = getWidth();
          }
      }
    else if (column >= getColumnCount())
      {
        if (getComponentOrientation().isLeftToRight())
          {
            cellRect.x = getWidth();
          }
      }
    else
      {
        TableColumnModel tcm = getColumnModel();
        if (getComponentOrientation().isLeftToRight())
          {
            for (int i = 0; i < column; i++)
              cellRect.x += tcm.getColumn(i).getWidth();
          }
        else
          {
            for (int i = tcm.getColumnCount() - 1; i > column; i--)
              cellRect.x += tcm.getColumn(i).getWidth();
          }
        cellRect.width = tcm.getColumn(column).getWidth();
        if (! includeSpacing)
          {
            // The rounding here is important.
            int cMargin = tcm.getColumnMargin();
            cellRect.x += cMargin / 2;
            cellRect.width -= cMargin;
          }
      }

    return cellRect;
  }

  public void clearSelection()
  {
    selectionModel.clearSelection();
    getColumnModel().getSelectionModel().clearSelection();
  }

  /**
   * Get the value of the selectedRow property by delegation to
   * the {@link ListSelectionModel#getMinSelectionIndex} method of the
   * {@link #selectionModel} field.
   *
   * @return The current value of the selectedRow property
   */
  public int getSelectedRow ()
  {    
    return selectionModel.getMinSelectionIndex();
  }
  
  /**
   * Get the value of the {@link #selectionModel} property.
   *
   * @return The current value of the property
   */
  public ListSelectionModel getSelectionModel()
  {
    //Neither Sun nor IBM returns null if rowSelection not allowed
    return selectionModel;
  }
  
  public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction)
  {
    if (orientation == SwingConstants.VERTICAL)
      return visibleRect.height * direction;
    else
      return visibleRect.width * direction;
  }

  /**
   * Get the value of the <code>scrollableTracksViewportHeight</code> property.
   *
   * @return The constant value <code>false</code>
   */
  public boolean getScrollableTracksViewportHeight()
  {
    return false;
  }
  
  /**
   * Get the value of the <code>scrollableTracksViewportWidth</code> property.
   *
   * @return <code>true</code> unless the {@link #autoResizeMode} property is
   * <code>AUTO_RESIZE_OFF</code>
   */
  public boolean getScrollableTracksViewportWidth()
  {
    if (autoResizeMode == AUTO_RESIZE_OFF)
      return false;
    else
      return true;
  }
  
  /**
   * Return the preferred scrolling amount (in pixels) for the given scrolling
   * direction and orientation. This method handles a partially exposed row by
   * returning the distance required to completely expose the item. When
   * scrolling the top item is completely exposed.
   * 
   * @param visibleRect the currently visible part of the component.
   * @param orientation the scrolling orientation
   * @param direction the scrolling direction (negative - up, positive -down).
   *          The values greater than one means that more mouse wheel or similar
   *          events were generated, and hence it is better to scroll the longer
   *          distance.
   * @author Audrius Meskauskas (audriusa@bioinformatics.org)
   */
  public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
                                        int direction)
  {
    int h = (rowHeight + rowMargin);
    int delta = h * direction;

    // Round so that the top would start from the row boundary
    if (orientation == SwingConstants.VERTICAL)
      {
        // Completely expose the top row
        int near = ((visibleRect.y + delta + h / 2) / h) * h;
        int diff = visibleRect.y + delta - near;
        delta -= diff;
      }
    return delta;
    // TODO when scrollng horizontally, scroll into the column boundary.
  }

  /**
   * Get the cell editor, suitable for editing the given cell. The default
   * method requests the editor from the column model. If the column model does
   * not provide the editor, the call is forwarded to the
   * {@link #getDefaultEditor(Class)} with the parameter, obtained from
   * {@link TableModel#getColumnClass(int)}.
   * 
   * @param row the cell row
   * @param column the cell column
   * @return the editor to edit that cell
   */
  public TableCellEditor getCellEditor(int row, int column)
  {
    TableCellEditor editor = columnModel.getColumn(column).getCellEditor();

    if (editor == null)
      {
        int mcolumn = convertColumnIndexToModel(column);
        editor = getDefaultEditor(dataModel.getColumnClass(mcolumn));
      }

    return editor;
  }
  
  /**
   * Get the default editor for editing values of the given type
   * (String, Boolean and so on).
   * 
   * @param columnClass the class of the value that will be edited.
   * 
   * @return the editor, suitable for editing this data type
   */
  public TableCellEditor getDefaultEditor(Class columnClass)
  {
    if (defaultEditorsByColumnClass.containsKey(columnClass))
      return (TableCellEditor) defaultEditorsByColumnClass.get(columnClass);
    else
      {
        JTextField t = new TableTextField();        
        TableCellEditor r = new DefaultCellEditor(t);
        defaultEditorsByColumnClass.put(columnClass, r);
        return r;
      }
  }
  
  /**
   * Get the cell renderer for rendering the given cell.
   * 
   * @param row the cell row
   * @param column the cell column
   * @return the cell renderer to render that cell.
   */
  public TableCellRenderer getCellRenderer(int row, int column)
  {
    TableCellRenderer renderer = columnModel.getColumn(column).getCellRenderer();
    if (renderer == null)
      {
        int mcolumn = convertColumnIndexToModel(column);
        renderer = getDefaultRenderer(dataModel.getColumnClass(mcolumn));
      }
    return renderer;
  }
  
  /**
   * Set default renderer for rendering the given data type.
   * 
   * @param columnClass the data type (String, Boolean and so on) that must be
   *          rendered.
   * @param rend the renderer that will rend this data type
   */
  public void setDefaultRenderer(Class columnClass, TableCellRenderer rend)
  {
    defaultRenderersByColumnClass.put(columnClass, rend);
  }
  
  /**
   * Get the default renderer for rendering the given data type.
   * 
   * @param columnClass the data that must be rendered
   * 
   * @return the appropriate defauld renderer for rendering that data type.
   */
  public TableCellRenderer getDefaultRenderer(Class columnClass)
  {
    if (defaultRenderersByColumnClass.containsKey(columnClass))
      return (TableCellRenderer) defaultRenderersByColumnClass.get(columnClass);
    else
      {
        TableCellRenderer r = new DefaultTableCellRenderer();
        defaultRenderersByColumnClass.put(columnClass, r);
        return r;
      }
  }
  
  /**
   * Convert the table model index into the table column number.
   * The model number need not match the real column position. The columns
   * may be rearranged by the user with mouse at any time by dragging the
   * column headers.
   *
   * @param vc the column number (0=first).
   * 
   * @return the table column model index of this column.
   * 
   * @see TableColumn#getModelIndex()
   */
  public int convertColumnIndexToModel(int vc)
  {
    if (vc < 0)
      return vc;
    else
      return columnModel.getColumn(vc).getModelIndex();
  }
  
  /**
   * Convert the table column number to the table column model index.
   * The model number need not match the real column position. The columns
   * may be rearranged by the user with mouse at any time by dragging the
   * column headers.
   *  
   * @param mc the table column index (0=first).
   * 
   * @return the table column number in the model
   * 
   * @see TableColumn#getModelIndex() 
   */
  public int convertColumnIndexToView(int mc)
  {
    if (mc < 0)
      return mc;
    int ncols = getColumnCount();
    for (int vc = 0; vc < ncols; ++vc)
      {
        if (columnModel.getColumn(vc).getModelIndex() == mc)
          return vc;
      }
    return -1;
  }
  
  /**
   * Prepare the renderer for rendering the given cell.
   * 
   * @param renderer the renderer being prepared
   * @param row the row of the cell being rendered
   * @param column the column of the cell being rendered
   * 
   * @return the component which .paint() method will paint the cell.
   */
  public Component prepareRenderer(TableCellRenderer renderer,
                                   int row,
                                   int column)
  {
    boolean rowSelAllowed = getRowSelectionAllowed();
    boolean colSelAllowed = getColumnSelectionAllowed();
    boolean isSel = false;
    if (rowSelAllowed && colSelAllowed || !rowSelAllowed && !colSelAllowed)
      isSel = isCellSelected(row, column);
    else
      isSel = isRowSelected(row) && getRowSelectionAllowed()
           || isColumnSelected(column) && getColumnSelectionAllowed();

    // Determine the focused cell. The focused cell is the cell at the
    // leadSelectionIndices of the row and column selection model.
    ListSelectionModel rowSel = getSelectionModel();
    ListSelectionModel colSel = getColumnModel().getSelectionModel();
    boolean hasFocus = hasFocus() && isEnabled()
                       && rowSel.getLeadSelectionIndex() == row
                       && colSel.getLeadSelectionIndex() == column;

    return renderer.getTableCellRendererComponent(this,
                                                  dataModel.getValueAt(row, 
						                       convertColumnIndexToModel(column)),
                                                  isSel,
                                                  hasFocus,
                                                  row, column);
  }


  /**
   * Get the value of the {@link #autoCreateColumnsFromModel} property.
   *
   * @return The current value of the property
   */
  public boolean getAutoCreateColumnsFromModel()
  {
    return autoCreateColumnsFromModel;
  }

  /**
   * Get the value of the {@link #autoResizeMode} property.
   *
   * @return The current value of the property
   */
  public int getAutoResizeMode()
  {
    return autoResizeMode;
  }

  /**
   * Get the value of the {@link #rowHeight} property.
   *
   * @return The current value of the property
   */
  public int getRowHeight()
  {
    return rowHeight;
  }

  /**
   * Get the height of the specified row.
   *
   * @param row the row whose height to return
   */
  public int getRowHeight(int row)
  {
    int rh = rowHeight;
    if (rowHeights != null)
      rh = rowHeights.getSize(row);
    return rh;
  }


  /**
   * Get the value of the {@link #rowMargin} property.
   *
   * @return The current value of the property
   */
  public int getRowMargin()
  {
    return rowMargin;
  }

  /**
   * Get the value of the {@link #rowSelectionAllowed} property.
   *
   * @return The current value of the property
   * 
   * @see #setRowSelectionAllowed(boolean)
   */
  public boolean getRowSelectionAllowed()
  {
    return rowSelectionAllowed;
  }

  /**
   * Get the value of the {@link #cellSelectionEnabled} property.
   *
   * @return The current value of the property
   */
  public boolean getCellSelectionEnabled()
  {
    return getColumnSelectionAllowed() && getRowSelectionAllowed();
  }

  /**
   * Get the value of the {@link #dataModel} property.
   *
   * @return The current value of the property
   */
  public TableModel getModel()
  {
    return dataModel;
  }

  /**
   * Get the value of the <code>columnCount</code> property by
   * delegation to the {@link #columnModel} field.
   *
   * @return The current value of the columnCount property
   */
  public int getColumnCount()
  {
    return columnModel.getColumnCount();    
  }

  /**
   * Get the value of the <code>rowCount</code> property by
   * delegation to the {@link #dataModel} field.
   *
   * @return The current value of the rowCount property
   */
  public int getRowCount()
  {
    return dataModel.getRowCount();
  }

  /**
   * Get the value of the {@link #columnModel} property.
   *
   * @return The current value of the property
   */
  public TableColumnModel getColumnModel()
  {
    return columnModel;
  }

  /**
   * Get the value of the <code>selectedColumn</code> property by
   * delegation to the {@link #columnModel} field.
   *
   * @return The current value of the selectedColumn property
   */
  public int getSelectedColumn()
  {
    return columnModel.getSelectionModel().getMinSelectionIndex();
  }

  private static int countSelections(ListSelectionModel lsm)
  {
    int lo = lsm.getMinSelectionIndex();
    int hi = lsm.getMaxSelectionIndex();
    int sum = 0;
    if (lo != -1 && hi != -1)
      {
        switch (lsm.getSelectionMode())
          {
          case ListSelectionModel.SINGLE_SELECTION:
            sum = 1;
            break;
            
          case ListSelectionModel.SINGLE_INTERVAL_SELECTION:
            sum = hi - lo + 1;
            break;
            
          case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:        
            for (int i = lo; i <= hi; ++i)
              if (lsm.isSelectedIndex(i))        
                ++sum;
            break;
          }
      }
    return sum;
  }

  private static int[] getSelections(ListSelectionModel lsm)
  {
    int sz = countSelections(lsm);
    int [] ret = new int[sz];

    int lo = lsm.getMinSelectionIndex();
    int hi = lsm.getMaxSelectionIndex();
    int j = 0;
    if (lo != -1 && hi != -1)
      {
        switch (lsm.getSelectionMode())
          {
          case ListSelectionModel.SINGLE_SELECTION:
            ret[0] = lo;
            break;      
      
          case ListSelectionModel.SINGLE_INTERVAL_SELECTION:            
            for (int i = lo; i <= hi; ++i)
              ret[j++] = i;
            break;
            
          case ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:        
            for (int i = lo; i <= hi; ++i)
              if (lsm.isSelectedIndex(i))        
                ret[j++] = i;
            break;
          }
      }
    return ret;
  }

  /**
   * Get the value of the <code>selectedColumnCount</code> property by
   * delegation to the {@link #columnModel} field.
   *
   * @return The current value of the selectedColumnCount property
   */  
  public int getSelectedColumnCount()
  {
    return countSelections(columnModel.getSelectionModel());
  }

  /**
   * Get the value of the <code>selectedColumns</code> property by
   * delegation to the {@link #columnModel} field.
   *
   * @return The current value of the selectedColumns property
   */
  public int[] getSelectedColumns()
  {
    return getSelections(columnModel.getSelectionModel());
  }

  /**
   * Get the value of the <code>columnSelectionAllowed</code> property.
   *
   * @return The current value of the columnSelectionAllowed property
   * 
   * @see #setColumnSelectionAllowed(boolean)
   */
  public boolean getColumnSelectionAllowed()
  {
    return getColumnModel().getColumnSelectionAllowed();
  }

  /**
   * Get the value of the <code>selectedRowCount</code> property by
   * delegation to the {@link #selectionModel} field.
   *
   * @return The current value of the selectedRowCount property
   */
  public int getSelectedRowCount()
  {
    return countSelections(selectionModel);
  }

  /**
   * Get the value of the <code>selectedRows</code> property by
   * delegation to the {@link #selectionModel} field.
   *
   * @return The current value of the selectedRows property
   */
  public int[] getSelectedRows()
  {
    return getSelections(selectionModel);
  }

  /**
   * Get the value of the {@link #accessibleContext} property.
   *
   * @return The current value of the property
   */
  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      {
        AccessibleJTable ctx = new AccessibleJTable();
        addPropertyChangeListener(ctx);
        TableColumnModel tcm = getColumnModel();
        tcm.addColumnModelListener(ctx);
        tcm.getSelectionModel().addListSelectionListener(ctx);
        getSelectionModel().addListSelectionListener(ctx);
        
        accessibleContext = ctx;
      }
    return accessibleContext;
  }

  /**
   * Get the value of the {@link #cellEditor} property.
   *
   * @return The current value of the property
   */
  public TableCellEditor getCellEditor()
  {
    return cellEditor;
  }

  /**
   * Get the value of the {@link #dragEnabled} property.
   *
   * @return The current value of the property
   */
  public boolean getDragEnabled()
  {
    return dragEnabled;
  }

  /**
   * Get the value of the {@link #gridColor} property.
   *
   * @return The current value of the property
   */
  public Color getGridColor()
  {
    return gridColor;
  }

  /**
   * Get the value of the <code>intercellSpacing</code> property.
   *
   * @return The current value of the property
   */
  public Dimension getIntercellSpacing()
  {
    return new Dimension(columnModel.getColumnMargin(), rowMargin);
  }

  /**
   * Get the value of the {@link #preferredViewportSize} property.
   *
   * @return The current value of the property
   */
  public Dimension getPreferredScrollableViewportSize()
  {
    return preferredViewportSize;
  }

  /**
   * Get the value of the {@link #selectionBackground} property.
   *
   * @return The current value of the property
   */
  public Color getSelectionBackground()
  {
    return selectionBackground;
  }

  /**
   * Get the value of the {@link #selectionForeground} property.
   *
   * @return The current value of the property
   */
  public Color getSelectionForeground()
  {
    return selectionForeground;
  }

  /**
   * Get the value of the {@link #showHorizontalLines} property.
   *
   * @return The current value of the property
   */
  public boolean getShowHorizontalLines()
  {
    return showHorizontalLines;
  }

  /**
   * Get the value of the {@link #showVerticalLines} property.
   *
   * @return The current value of the property
   */
  public boolean getShowVerticalLines()
  {
    return showVerticalLines;
  }

  /**
   * Get the value of the {@link #tableHeader} property.
   *
   * @return The current value of the property
   */
  public JTableHeader getTableHeader()
  {
    return tableHeader;
  }

  /**
   * Removes specified column from displayable columns of this table.
   *
   * @param column column to removed
   */
  public void removeColumn(TableColumn column)
  {    
    columnModel.removeColumn(column);
  }

  /**
   * Moves column at the specified index to new given location.
   *
   * @param column index of the column to move
   * @param targetColumn index specifying new location of the column
   */ 
  public void moveColumn(int column,int targetColumn) 
  {
    columnModel.moveColumn(column, targetColumn);
  }

  /**
   * Set the value of the {@link #autoCreateColumnsFromModel} flag.  If the
   * flag changes from <code>false</code> to <code>true</code>, the
   * {@link #createDefaultColumnsFromModel()} method is called.
   *
   * @param autoCreate  the new value of the flag.
   */ 
  public void setAutoCreateColumnsFromModel(boolean autoCreate)
  {
    if (autoCreateColumnsFromModel != autoCreate)
    {
      autoCreateColumnsFromModel = autoCreate;
      if (autoCreate)
        createDefaultColumnsFromModel();
    }
  }

  /**
   * Set the value of the {@link #autoResizeMode} property.
   *
   * @param a The new value of the autoResizeMode property
   */ 
  public void setAutoResizeMode(int a)
  {
    autoResizeMode = a;
    revalidate();
    repaint();
  }

  /**
   * Sets the height for all rows in the table. If you want to change the
   * height of a single row instead, use {@link #setRowHeight(int, int)}.
   *
   * @param r the height to set for all rows
   *
   * @see #getRowHeight()
   * @see #setRowHeight(int, int)
   * @see #getRowHeight(int)
   */ 
  public void setRowHeight(int r)
  {
    if (r < 1)
      throw new IllegalArgumentException();

    clientRowHeightSet = true;

    rowHeight = r;
    rowHeights = null;
    revalidate();
    repaint();
  }
  
  /**
   * Sets the height of a single row in the table.
   * 
   * @param rh the new row height
   * @param row the row to change the height of
   */
  public void setRowHeight(int row, int rh)
  {
    if (rowHeights == null)
      {
        rowHeights = new SizeSequence(getRowCount(), rowHeight);
      }
    rowHeights.setSize(row, rh);
  }
  
  /**
   * Set the value of the {@link #rowMargin} property.
   *
   * @param r The new value of the rowMargin property
   */ 
  public void setRowMargin(int r)
  {
    rowMargin = r;
    revalidate();
    repaint();
  }

  /**
   * Set the value of the {@link #rowSelectionAllowed} property.
   *
   * @param r The new value of the rowSelectionAllowed property
   * 
   * @see #getRowSelectionAllowed()
   */ 
  public void setRowSelectionAllowed(boolean r)
  {
    if (rowSelectionAllowed != r) 
      {
        rowSelectionAllowed = r;
        firePropertyChange("rowSelectionAllowed", !r, r);
        repaint();
      }
  }

  /**
   * Set the value of the {@link #cellSelectionEnabled} property.
   *
   * @param c The new value of the cellSelectionEnabled property
   */ 
  public void setCellSelectionEnabled(boolean c)
  {
    setColumnSelectionAllowed(c);
    setRowSelectionAllowed(c);
    // for backward-compatibility sake:
    cellSelectionEnabled = true;
  }

  /**
   * <p>Set the value of the {@link #dataModel} property.</p>
   *
   * <p>Unregister <code>this</code> as a {@link TableModelListener} from
   * previous {@link #dataModel} and register it with new parameter
   * <code>m</code>.</p>
   *
   * @param m The new value of the model property
   */ 
  public void setModel(TableModel m)
  {
    // Throw exception is m is null.
    if (m == null)
      throw new IllegalArgumentException();
   
    // Don't do anything if setting the current model again.
    if (dataModel == m)
      return;

    TableModel oldModel = dataModel;

    // Remove table as TableModelListener from old model.
    if (dataModel != null)
      dataModel.removeTableModelListener(this);
    
    if (m != null)
      {
        // Set property.
        dataModel = m;

        // Add table as TableModelListener to new model.
        dataModel.addTableModelListener(this);

        // Notify the tableChanged method.
        tableChanged(new TableModelEvent(dataModel,
                                         TableModelEvent.HEADER_ROW));

        // Automatically create columns.
        if (autoCreateColumnsFromModel)
          createDefaultColumnsFromModel();
      }

    // This property is bound, so we fire a property change event.
    firePropertyChange("model", oldModel, dataModel);

    // Repaint table.
    revalidate();
    repaint();
  }

  /**
   * <p>Set the value of the {@link #columnModel} property.</p>
   *
   * <p>Unregister <code>this</code> as a {@link TableColumnModelListener}
   * from previous {@link #columnModel} and register it with new parameter
   * <code>c</code>.</p>
   *
   * @param c The new value of the columnModel property
   */ 
  public void setColumnModel(TableColumnModel c)
  {
    if (c == null)
      throw new IllegalArgumentException();
    TableColumnModel tmp = columnModel;
    if (tmp != null)
      tmp.removeColumnModelListener(this);
    if (c != null)
      c.addColumnModelListener(this);
    columnModel = c;
    if (dataModel != null && columnModel != null)
      {
        int ncols = getColumnCount();
        TableColumn column;
        for (int i = 0; i < ncols; ++i)
          {
            column = columnModel.getColumn(i); 
            if (column.getHeaderValue()==null)
              column.setHeaderValue(dataModel.getColumnName(i));
          }
      }

    // according to Sun's spec we also have to set the tableHeader's
    // column model here
    if (tableHeader != null)
      tableHeader.setColumnModel(c);

    revalidate();
    repaint();
  }

  /**
   * Set the value of the <code>columnSelectionAllowed</code> property.
   *
   * @param c The new value of the property
   * 
   * @see #getColumnSelectionAllowed()
   */ 
  public void setColumnSelectionAllowed(boolean c)
  {
    if (columnModel.getColumnSelectionAllowed() != c)
      {
        columnModel.setColumnSelectionAllowed(c);
        firePropertyChange("columnSelectionAllowed", !c, c);
        repaint();
      }
  }

  /**
   * <p>Set the value of the {@link #selectionModel} property.</p>
   *
   * <p>Unregister <code>this</code> as a {@link ListSelectionListener}
   * from previous {@link #selectionModel} and register it with new
   * parameter <code>s</code>.</p>
   *
   * @param s The new value of the selectionModel property
   */ 
  public void setSelectionModel(ListSelectionModel s)
  {
    if (s == null)
      throw new IllegalArgumentException();
    ListSelectionModel tmp = selectionModel;
    if (tmp != null)
      tmp.removeListSelectionListener(this);
    if (s != null)
      s.addListSelectionListener(this);
    selectionModel = s;
    checkSelection();
  }

  /**
   * Set the value of the <code>selectionMode</code> property by
   * delegation to the {@link #selectionModel} field. The same selection
   * mode is set for row and column selection models.
   *
   * @param s The new value of the property
   */ 
  public void setSelectionMode(int s)
  { 
    selectionModel.setSelectionMode(s);    
    columnModel.getSelectionModel().setSelectionMode(s);
    
    repaint();
  }

  /**
   * <p>Set the value of the {@link #cellEditor} property.</p>
   *
   * <p>Unregister <code>this</code> as a {@link CellEditorListener} from
   * previous {@link #cellEditor} and register it with new parameter
   * <code>c</code>.</p>
   *
   * @param c The new value of the cellEditor property
   */ 
  public void setCellEditor(TableCellEditor c)
  {
    TableCellEditor tmp = cellEditor;
    if (tmp != null)
      tmp.removeCellEditorListener(this);
    if (c != null)
      c.addCellEditorListener(this);
    cellEditor = c;
  }

  /**
   * Set the value of the {@link #dragEnabled} property.
   *
   * @param d The new value of the dragEnabled property
   */ 
  public void setDragEnabled(boolean d)
  {
    dragEnabled = d;
  }

  /**
   * Set the value of the {@link #gridColor} property.
   *
   * @param g The new value of the gridColor property
   */ 
  public void setGridColor(Color g)
  {
    gridColor = g;
    repaint();
  }

  /**
   * Set the value of the <code>intercellSpacing</code> property.
   *
   * @param i The new value of the intercellSpacing property
   */ 
  public void setIntercellSpacing(Dimension i)
  {
    rowMargin = i.height;
    columnModel.setColumnMargin(i.width);
    repaint();
  }

  /**
   * Set the value of the {@link #preferredViewportSize} property.
   *
   * @param p The new value of the preferredViewportSize property
   */ 
  public void setPreferredScrollableViewportSize(Dimension p)
  {
    preferredViewportSize = p;
    revalidate();
    repaint();
  }

  /**
   * <p>Set the value of the {@link #selectionBackground} property.</p>
   *
   * <p>Fire a PropertyChangeEvent with name {@link
   * #SELECTION_BACKGROUND_CHANGED_PROPERTY} to registered listeners, if
   * selectionBackground changed.</p>
   *
   * @param s The new value of the selectionBackground property
   */ 
  public void setSelectionBackground(Color s)
  {
    Color tmp = selectionBackground;
    selectionBackground = s;
    if (((tmp == null && s != null)
         || (s == null && tmp != null)
         || (tmp != null && s != null && !tmp.equals(s))))
      firePropertyChange(SELECTION_BACKGROUND_CHANGED_PROPERTY, tmp, s);
    repaint();
  }

  /**
   * <p>Set the value of the {@link #selectionForeground} property.</p>
   *
   * <p>Fire a PropertyChangeEvent with name {@link
   * #SELECTION_FOREGROUND_CHANGED_PROPERTY} to registered listeners, if
   * selectionForeground changed.</p>
   *
   * @param s The new value of the selectionForeground property
   */ 
  public void setSelectionForeground(Color s)
  {
    Color tmp = selectionForeground;
    selectionForeground = s;
    if (((tmp == null && s != null)
         || (s == null && tmp != null)
         || (tmp != null && s != null && !tmp.equals(s))))
      firePropertyChange(SELECTION_FOREGROUND_CHANGED_PROPERTY, tmp, s);
    repaint();
  }

  /**
   * Set the value of the <code>showGrid</code> property.
   *
   * @param s The new value of the showGrid property
   */ 
  public void setShowGrid(boolean s)
  {
    setShowVerticalLines(s);
    setShowHorizontalLines(s);
  }

  /**
   * Set the value of the {@link #showHorizontalLines} property.
   *
   * @param s The new value of the showHorizontalLines property
   */ 
  public void setShowHorizontalLines(boolean s)
  {
    showHorizontalLines = s;
    repaint();
  }

  /**
   * Set the value of the {@link #showVerticalLines} property.
   *
   * @param s The new value of the showVerticalLines property
   */ 
  public void setShowVerticalLines(boolean s)
  {
    showVerticalLines = s;
    repaint();
  }

  /**
   * Set the value of the {@link #tableHeader} property.
   *
   * @param t The new value of the tableHeader property
   */ 
  public void setTableHeader(JTableHeader t)
  {
    if (tableHeader != null)
      tableHeader.setTable(null);
    tableHeader = t;
    if (tableHeader != null)
      tableHeader.setTable(this);
    revalidate();
    repaint();
  }

  protected void configureEnclosingScrollPane()
  {
    JScrollPane jsp = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, this);
    if (jsp != null && tableHeader != null)
      {
        jsp.setColumnHeaderView(tableHeader);
      }
  }

  protected void unconfigureEnclosingScrollPane()
  {
    JScrollPane jsp = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, this);
    if (jsp != null)
      {
        jsp.setColumnHeaderView(null);
      }    
  }


  public void addNotify()
  {
    super.addNotify();
    configureEnclosingScrollPane();
  }

  public void removeNotify()
  {
    super.addNotify();
    unconfigureEnclosingScrollPane();
  }


  /**
   * This distributes the superfluous width in a table evenly on its columns.
   *
   * The implementation used here is different to that one described in
   * the JavaDocs. It is much simpler, and seems to work very well.
   *
   * TODO: correctly implement the algorithm described in the JavaDoc
   */
  private void distributeSpill(TableColumn[] cols, int spill)
  {
    int average = spill / cols.length;
    for (int i = 0; i < cols.length; i++)
      {
        if (cols[i] != null)
          cols[i].setWidth(cols[i].getPreferredWidth() + average);
      }
  }
  
  /**
   * This distributes the superfluous width in a table, setting the width of the
   * column being resized strictly to its preferred width.
   */
  private void distributeSpillResizing(TableColumn[] cols, int spill,
                                       TableColumn resizeIt)
  {
    int average = 0;
    if (cols.length != 1)
      average = spill / (cols.length-1);
    for (int i = 0; i < cols.length; i++)
      {
        if (cols[i] != null && !cols[i].equals(resizeIt))
          cols[i].setWidth(cols[i].getPreferredWidth() + average);
      }
    resizeIt.setWidth(resizeIt.getPreferredWidth());
  }  
  
  /**
   * Set the widths of all columns, taking they preferred widths into
   * consideration. The excess space, if any, will be distrubuted between
   * all columns. This method also handles special cases when one of the
   * collumns is currently being resized.
   * 
   * @see TableColumn#setPreferredWidth(int)
   */
  public void doLayout()
  {
    TableColumn resizingColumn = null;
    
    int ncols = getColumnCount();
    if (ncols < 1)
      return;

    int prefSum = 0;
    int rCol = -1;

    if (tableHeader != null)
      resizingColumn = tableHeader.getResizingColumn();

    for (int i = 0; i < ncols; ++i)
      {
        TableColumn col = columnModel.getColumn(i);
        int p = col.getPreferredWidth();
        prefSum += p;
        if (resizingColumn == col)
          rCol = i;
      }

    int spill = getWidth() - prefSum;

    if (resizingColumn != null)
      {
        TableColumn col;
        TableColumn [] cols;
        
        switch (getAutoResizeMode())
          {
          case AUTO_RESIZE_LAST_COLUMN:
            col = columnModel.getColumn(ncols-1);
            col.setWidth(col.getPreferredWidth() + spill);
            break;
            
          case AUTO_RESIZE_NEXT_COLUMN:
            col = columnModel.getColumn(ncols-1);
            col.setWidth(col.getPreferredWidth() + spill);
            break;

          case AUTO_RESIZE_ALL_COLUMNS:
            cols = new TableColumn[ncols];
            for (int i = 0; i < ncols; ++i)
              cols[i] = columnModel.getColumn(i);
            distributeSpillResizing(cols, spill, resizingColumn);
            break;

          case AUTO_RESIZE_SUBSEQUENT_COLUMNS:
            
            // Subtract the width of the non-resized columns from the spill.
            int w = 0;
            int wp = 0;
            TableColumn column;
            for (int i = 0; i < rCol; i++)
              {
                column = columnModel.getColumn(i);
                w += column.getWidth();
                wp+= column.getPreferredWidth();
              }

            // The number of columns right from the column being resized.
            int n = ncols-rCol-1;
            if (n>0)
              {
                // If there are any columns on the right sied to resize.
                spill = (getWidth()-w) - (prefSum-wp);
                int average = spill / n;
            
                 // For all columns right from the column being resized:
                for (int i = rCol+1; i < ncols; i++)
                  {
                    column = columnModel.getColumn(i);
                    column.setWidth(column.getPreferredWidth() + average);
                  }
              }
            resizingColumn.setWidth(resizingColumn.getPreferredWidth());
            break;

          case AUTO_RESIZE_OFF:
          default:
            int prefWidth = resizingColumn.getPreferredWidth();
            resizingColumn.setWidth(prefWidth);
          }
      }
    else
      {
        TableColumn [] cols = new TableColumn[ncols];
        for (int i = 0; i < ncols; ++i)
          cols[i] = columnModel.getColumn(i);
        distributeSpill(cols, spill);
      }
    
    if (editorComp!=null)
      moveToCellBeingEdited(editorComp);
    
    int leftBoundary = getLeftResizingBoundary();
    int width = getWidth() - leftBoundary;
    repaint(leftBoundary, 0, width, getHeight());
    if (tableHeader != null)
      tableHeader.repaint(leftBoundary, 0, width, tableHeader.getHeight());
  }
  
  /**
   * Get the left boundary of the rectangle which changes during the column
   * resizing.
   */
  int getLeftResizingBoundary()
  {
    if (tableHeader == null || getAutoResizeMode() == AUTO_RESIZE_ALL_COLUMNS)
      return 0;
    else
      {
        TableColumn resizingColumn = tableHeader.getResizingColumn();
        if (resizingColumn == null)
          return 0;

        int rc = convertColumnIndexToView(resizingColumn.getModelIndex());
        int p = 0;

        for (int i = 0; i < rc; i++)
          p += columnModel.getColumn(i).getWidth();
        
        return p;
      }
  }
  
  
  /**
   * @deprecated Replaced by <code>doLayout()</code>
   */
  public void sizeColumnsToFit(boolean lastColumnOnly)
  {
    doLayout();
  }
  
  /**
   * Obsolete since JDK 1.4. Please use <code>doLayout()</code>.
   */
  public void sizeColumnsToFit(int resizingColumn)
  {
    doLayout();
  }

  public String getUIClassID()
  {
    return "TableUI";
  }

  /**
   * This method returns the table's UI delegate.
   *
   * @return The table's UI delegate.
   */
  public TableUI getUI()
  {
    return (TableUI) ui;
  }

  /**
   * This method sets the table's UI delegate.
   *
   * @param ui The table's UI delegate.
   */
  public void setUI(TableUI ui)
  {
    super.setUI(ui);
    // The editors and renderers must be recreated because they constructors
    // may use the look and feel properties.
    createDefaultEditors();
    createDefaultRenderers();
  }

  public void updateUI()
  {
    setUI((TableUI) UIManager.getUI(this));
  }
  
  /**
   * Get the class (datatype) of the column. The cells are rendered and edited
   * differently, depending from they data type.
   * 
   * @param column the column (not the model index).
   * 
   * @return the class, defining data type of that column (String.class for
   * String, Boolean.class for boolean and so on).
   */
  public Class getColumnClass(int column)
  {
    return getModel().getColumnClass(convertColumnIndexToModel(column));
  }
  
  /**
   * Get the name of the column. If the column has the column identifier set,
   * the return value is the result of the .toString() method call on that
   * identifier. If the identifier is not explicitly set, the returned value
   * is calculated by 
   * {@link javax.swing.table.AbstractTableModel#getColumnName(int)}.
   * 
   * @param column the column
   * 
   * @return the name of that column.
   */
  public String getColumnName(int column)
  {
    int modelColumn = columnModel.getColumn(column).getModelIndex();
    return dataModel.getColumnName(modelColumn);
  }
  
  /**
   * Get the column, currently being edited
   * 
   * @return the column, currently being edited.
   */
  public int getEditingColumn()
  {
    return editingColumn;
  }
  
  /**
   * Set the column, currently being edited
   * 
   * @param column the column, currently being edited.
   */
  public void setEditingColumn(int column)
  {
    editingColumn = column;
  }
  
  /**
   * Get the row currently being edited.
   * 
   * @return the row, currently being edited.
   */
  public int getEditingRow()
  {
    return editingRow;
  }
  
  /**
   * Set the row currently being edited.
   * 
   * @param row the row, that will be edited
   */
  public void setEditingRow(int row)
  {
    editingRow = row;
  }
  
  /**
   * Get the editor component that is currently editing one of the cells
   * 
   * @return the editor component or null, if none of the cells is being
   * edited.
   */
  public Component getEditorComponent()
  {
    return editorComp;
  }
  
  /**
   * Check if one of the table cells is currently being edited.
   * 
   * @return true if there is a cell being edited.
   */
  public boolean isEditing()
  {
    return editorComp != null;
  }
  
  /**
   * Set the default editor for the given column class (column data type).
   * By default, String is handled by text field and Boolean is handled by
   * the check box.
   *  
   * @param columnClass the column data type
   * @param editor the editor that will edit this data type
   * 
   * @see TableModel#getColumnClass(int)
   */
  public void setDefaultEditor(Class columnClass, TableCellEditor editor)
  {
    if (editor != null)
      defaultEditorsByColumnClass.put(columnClass, editor);
    else
      defaultEditorsByColumnClass.remove(columnClass);
  }
  
  public void addColumnSelectionInterval(int index0, int index1)
  {
    if ((index0 < 0 || index0 > (getColumnCount()-1)
         || index1 < 0 || index1 > (getColumnCount()-1)))
      throw new IllegalArgumentException("Column index out of range.");
    
    getColumnModel().getSelectionModel().addSelectionInterval(index0, index1);
  }
  
  public void addRowSelectionInterval(int index0, int index1)
  {            
    if ((index0 < 0 || index0 > (getRowCount()-1)
         || index1 < 0 || index1 > (getRowCount()-1)))
      throw new IllegalArgumentException("Row index out of range.");
      	
    getSelectionModel().addSelectionInterval(index0, index1);
  }
  
  public void setColumnSelectionInterval(int index0, int index1)
  {
    if ((index0 < 0 || index0 > (getColumnCount()-1)
         || index1 < 0 || index1 > (getColumnCount()-1)))
      throw new IllegalArgumentException("Column index out of range.");

    getColumnModel().getSelectionModel().setSelectionInterval(index0, index1);
  }
  
  public void setRowSelectionInterval(int index0, int index1)
  {    
    if ((index0 < 0 || index0 > (getRowCount()-1)
         || index1 < 0 || index1 > (getRowCount()-1)))
      throw new IllegalArgumentException("Row index out of range.");

    getSelectionModel().setSelectionInterval(index0, index1);
  }
  
  public void removeColumnSelectionInterval(int index0, int index1)  
  {
    if ((index0 < 0 || index0 > (getColumnCount()-1)
         || index1 < 0 || index1 > (getColumnCount()-1)))
      throw new IllegalArgumentException("Column index out of range.");

    getColumnModel().getSelectionModel().removeSelectionInterval(index0, index1);
  }
  
  public void removeRowSelectionInterval(int index0, int index1)
  {
    if ((index0 < 0 || index0 > (getRowCount()-1)
         || index1 < 0 || index1 > (getRowCount()-1)))
      throw new IllegalArgumentException("Row index out of range.");

    getSelectionModel().removeSelectionInterval(index0, index1);
  }
  
  /**
   * Checks if the given column is selected.
   * 
   * @param column the column
   * 
   * @return true if the column is selected (as reported by the selection
   * model, associated with the column model), false otherwise.
   */
  public boolean isColumnSelected(int column)
  {
    return getColumnModel().getSelectionModel().isSelectedIndex(column);
  }
  
  /**
   * Checks if the given row is selected.
   * 
   * @param row the row
   * 
   * @return true if the row is selected (as reported by the selection model),
   * false otherwise.
   */
  public boolean isRowSelected(int row)
  {
    return getSelectionModel().isSelectedIndex(row);
  }
  
  /**
   * Checks if the given cell is selected. The cell is selected if both
   * the cell row and the cell column are selected.
   * 
   * @param row the cell row
   * @param column the cell column
   * 
   * @return true if the cell is selected, false otherwise
   */
  public boolean isCellSelected(int row, int column)
  {
    return isRowSelected(row) && isColumnSelected(column);
  }
  
  /**
   * Select all table.
   */
  public void selectAll()
  {
    // The table is empty - nothing to do!
    if (getRowCount() == 0 || getColumnCount() == 0)
      return;
    
    // rowLead and colLead store the current lead selection indices
    int rowLead = selectionModel.getLeadSelectionIndex();
    int colLead = getColumnModel().getSelectionModel().getLeadSelectionIndex();
    // the following calls to setSelectionInterval change the lead selection
    // indices
    setColumnSelectionInterval(0, getColumnCount() - 1);
    setRowSelectionInterval(0, getRowCount() - 1);
    // the following addSelectionInterval calls restore the lead selection
    // indices to their previous values
    addColumnSelectionInterval(colLead,colLead);
    addRowSelectionInterval(rowLead, rowLead);
  }
  
  /**
   * Get the cell value at the given position.
   * 
   * @param row the row to get the value
   * @param column the actual column number (not the model index) 
   * to get the value.
   * 
   * @return the cell value, as returned by model.
   */
  public Object getValueAt(int row, int column)
  {
    return dataModel.getValueAt(row, convertColumnIndexToModel(column));
  }
  
  /**
   * Set value for the cell at the given position. The modified cell is
   * repainted.
   * 
   * @param value the value to set
   * @param row the row of the cell being modified
   * @param column the column of the cell being modified
   */
  public void setValueAt(Object value, int row, int column)
  {
    dataModel.setValueAt(value, row, convertColumnIndexToModel(column));
    
    repaint(getCellRect(row, column, true));
  }
  
  /**
   * Get table column with the given identified.
   * 
   * @param identifier the column identifier
   * 
   * @return the table column with this identifier
   * 
   * @throws IllegalArgumentException if <code>identifier</code> is 
   *         <code>null</code> or there is no column with that identifier.
   * 
   * @see TableColumn#setIdentifier(Object)
   */
  public TableColumn getColumn(Object identifier)
  {
    return columnModel.getColumn(columnModel.getColumnIndex(identifier));
  }

  /**
   * Returns <code>true</code> if the specified cell is editable, and
   * <code>false</code> otherwise.
   *
   * @param row  the row index.
   * @param column  the column index.
   *
   * @return true if the cell is editable, false otherwise.
   */
  public boolean isCellEditable(int row, int column)
  {
    return dataModel.isCellEditable(row, convertColumnIndexToModel(column));
  }

  /**
   * Clears any existing columns from the <code>JTable</code>'s
   * {@link TableColumnModel} and creates new columns to match the values in
   * the data ({@link TableModel}) used by the table.
   *
   * @see #setAutoCreateColumnsFromModel(boolean)
   */
  public void createDefaultColumnsFromModel()
  {
    assert columnModel != null : "The columnModel must not be null.";

    // remove existing columns
    int columnIndex = columnModel.getColumnCount() - 1;
    while (columnIndex >= 0)
    {
      columnModel.removeColumn(columnModel.getColumn(columnIndex));
      columnIndex--;
    }
  
    // add new columns to match the TableModel
    int columnCount = dataModel.getColumnCount();
    for (int c = 0; c < columnCount; c++)
    {
      TableColumn column = new TableColumn(c);
      column.setIdentifier(dataModel.getColumnName(c));
      column.setHeaderValue(dataModel.getColumnName(c));
      columnModel.addColumn(column);
      column.addPropertyChangeListener(tableColumnPropertyChangeHandler);
    }
  }

  public void changeSelection (int rowIndex, int columnIndex, boolean toggle, boolean extend)
  {
    if (toggle && extend)
      {
        // Leave the selection state as is, but move the anchor
        //   index to the specified location
        selectionModel.setAnchorSelectionIndex(rowIndex);
        getColumnModel().getSelectionModel().setAnchorSelectionIndex(columnIndex);
      }
    else if (toggle)
      {
        // Toggle the state of the specified cell
        if (isCellSelected(rowIndex,columnIndex))
          {
            selectionModel.removeSelectionInterval(rowIndex,rowIndex);
            getColumnModel().getSelectionModel().removeSelectionInterval(columnIndex,columnIndex);
          }
        else
          {
            selectionModel.addSelectionInterval(rowIndex,rowIndex);
            getColumnModel().getSelectionModel().addSelectionInterval(columnIndex,columnIndex);
          }
      }
    else if (extend)
      {
        // Extend the previous selection from the anchor to the 
        // specified cell, clearing all other selections
        selectionModel.setLeadSelectionIndex(rowIndex);
        getColumnModel().getSelectionModel().setLeadSelectionIndex(columnIndex);
      }
    else
      {
        // Clear the previous selection and ensure the new cell
        // is selected
         selectionModel.clearSelection();
        selectionModel.setSelectionInterval(rowIndex,rowIndex);
        getColumnModel().getSelectionModel().clearSelection();
        getColumnModel().getSelectionModel().setSelectionInterval(columnIndex, columnIndex);
        
        
      }
  }

  /**
   * Programmatically starts editing the specified cell.
   * 
   * @param row the row of the cell to edit.
   * @param column the column of the cell to edit.
   */
  public boolean editCellAt(int row, int column)
  {
    // Complete the previous editing session, if still active.
    if (isEditing())
      editingStopped(new ChangeEvent("editingStopped"));

    TableCellEditor editor = getCellEditor(row, column);
    
    // The boolean values are inverted by the single click without the
    // real editing session.
    if (editor == booleanInvertingEditor && isCellEditable(row, column))
      {
        if (Boolean.TRUE.equals(getValueAt(row, column)))
          setValueAt(Boolean.FALSE, row, column);
        else
          setValueAt(Boolean.TRUE, row, column);
        return false;
      }
    else
      {
        editingRow = row;
        editingColumn = column;

        setCellEditor(editor);
        editorComp = prepareEditor(cellEditor, row, column);

        // Remove the previous editor components, if present. Only one
        // editor component at time is allowed in the table.
        removeAll();
        add(editorComp);
        moveToCellBeingEdited(editorComp);
        scrollRectToVisible(editorComp.getBounds());
        editorComp.requestFocusInWindow();
        
        // Deliver the should select event.
        return editor.shouldSelectCell(null);        
      }
  }

  /**
   * Move the given component under the cell being edited. 
   * The table must be in the editing mode.
   * 
   * @param component the component to move.
   */
  private void moveToCellBeingEdited(Component component)
  {
     Rectangle r = getCellRect(editingRow, editingColumn, true);
     // Adjust bounding box of the editing component, so that it lies
     // 'above' the grid on all edges, not only right and bottom.
     // The table grid is painted only at the right and bottom edge of a cell.
     r.x -= 1;
     r.y -= 1;
     r.width += 1;
     r.height += 1;
     component.setBounds(r);
  }

  /**
   * Programmatically starts editing the specified cell.
   *
   * @param row the row of the cell to edit.
   * @param column the column of the cell to edit.
   */
  public boolean editCellAt (int row, int column, EventObject e)
  {
    return editCellAt(row, column);
  }

  /**
   * Discards the editor object.
   */
  public void removeEditor()
  {
    editingStopped(new ChangeEvent(this));
  }

  /**
   * Prepares the editor by querying for the value and selection state of the
   * cell at (row, column).
   *
   * @param editor the TableCellEditor to set up
   * @param row the row of the cell to edit
   * @param column the column of the cell to edit
   * @return the Component being edited
   */
  public Component prepareEditor (TableCellEditor editor, int row, int column)
  {
    return editor.getTableCellEditorComponent
      (this, getValueAt(row, column), isCellSelected(row, column), row, column);
  }

  /**
   * This revalidates the <code>JTable</code> and queues a repaint.
   */
  protected void resizeAndRepaint()
  {
    revalidate();
    repaint();
  }

  /**
   * Sets whether cell editors of this table should receive keyboard focus
   * when the editor is activated by a keystroke. The default setting is
   * <code>false</code> which means that the table should keep the keyboard
   * focus until the cell is selected by a mouse click.
   *
   * @param value the value to set
   *
   * @since 1.4
   */
  public void setSurrendersFocusOnKeystroke(boolean value)
  {
    // TODO: Implement functionality of this property (in UI impl).
    surrendersFocusOnKeystroke = value;
  }
  
  /**
   * Returns whether cell editors of this table should receive keyboard focus
   * when the editor is activated by a keystroke. The default setting is
   * <code>false</code> which means that the table should keep the keyboard
   * focus until the cell is selected by a mouse click.
   *
   * @return whether cell editors of this table should receive keyboard focus
   *         when the editor is activated by a keystroke
   *
   * @since 1.4
   */
  public boolean getSurrendersFocusOnKeystroke()
  {
    // TODO: Implement functionality of this property (in UI impl).
    return surrendersFocusOnKeystroke;
  }

  /**
   * Helper method for
   * {@link LookAndFeel#installProperty(JComponent, String, Object)}.
   * 
   * @param propertyName the name of the property
   * @param value the value of the property
   *
   * @throws IllegalArgumentException if the specified property cannot be set
   *         by this method
   * @throws ClassCastException if the property value does not match the
   *         property type
   * @throws NullPointerException if <code>c</code> or
   *         <code>propertyValue</code> is <code>null</code>
   */
  void setUIProperty(String propertyName, Object value)
  {
    if (propertyName.equals("rowHeight"))
      {
        if (! clientRowHeightSet)
          {
            setRowHeight(((Integer) value).intValue());
            clientRowHeightSet = false;
          }
      }
    else
      {
        super.setUIProperty(propertyName, value);
      }
  }
}
