/* 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.
    // These four lines are not needed.  A Mauve test that shows this is
    // gnu.testlet.javax.swing.JTable.constructors(linesNotNeeded).
    // selectionModel.setAnchorSelectionIndex(-1);
    // selectionModel.setLeadSelectionIndex(-1);
    // columnModel.getSelectionModel().setAnchorSelectionIndex(-1);
    // columnModel.getSelectionModel().setLeadSelectionIndex(-1);
    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 = false;
    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)
  {
    int block;
    if (orientation == SwingConstants.HORIZONTAL)
      {
        block = visibleRect.width;
      }
    else
      {
        int rowHeight = getRowHeight();
        if (rowHeight > 0)
          block = Math.max(rowHeight, // Little hack for useful rounding.
                           (visibleRect.height / rowHeight) * rowHeight);
        else
          block = visibleRect.height;
      }
    return block;
  }

  /**
   * 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 Roman Kennke (kennke@aicas.com)
   */
  public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation,
                                        int direction)
  {
    int unit;
    if (orientation == SwingConstants.HORIZONTAL)
      unit = 100;
    else
      {
        unit = getRowHeight();
        // The following adjustment doesn't work for variable height rows.
        // It fully exposes partially visible rows in the scrolling direction.
        if (rowHeights == null)
          {
            if (direction > 0)
              {
                // Scroll down.
                // How much pixles are exposed from the last item?
                int exposed = (visibleRect.y + visibleRect.height) % unit;
                if (exposed > 0 && exposed < unit - 1)
                  unit = unit - exposed - 1;
              }
            else
              {
                // Scroll up.
                int exposed = visibleRect.y % unit;
                if (exposed > 0 && exposed < unit)
                  unit = exposed;
              }
          }
      }
    return unit;
  }

  /**
   * 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 = null;
    if (columnModel.getColumnCount() > 0)
      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 = columnModel.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);
      }
  }
}
