/* BasicTableUI.java --
   Copyright (C) 2004 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.plaf.basic;

import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.CellRendererPane;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultListSelectionModel;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.TableUI;
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;

public class BasicTableUI extends TableUI
{
  public static ComponentUI createUI(JComponent comp) 
  {
    return new BasicTableUI();
  }

  protected FocusListener focusListener;  
  protected KeyListener keyListener;   
  protected MouseInputListener  mouseInputListener;   
  protected CellRendererPane rendererPane;   
  protected JTable table;

  /** The normal cell border. */
  Border cellBorder;

  /** The action bound to KeyStrokes. */
  TableAction action;

  /**
   * Listens for changes to the tables properties.
   */
  private PropertyChangeListener propertyChangeListener;

  /**
   * Handles key events for the JTable. Key events should be handled through
   * the InputMap/ActionMap mechanism since JDK1.3. This class is only there
   * for backwards compatibility.
   * 
   * @author Roman Kennke (kennke@aicas.com)
   */
  public class KeyHandler implements KeyListener
  {

    /**
     * Receives notification that a key has been pressed and released.
     * Activates the editing session for the focused cell by pressing the
     * character keys.
     *
     * @param event the key event
     */
    public void keyTyped(KeyEvent event)
    {
      // Key events should be handled through the InputMap/ActionMap mechanism
      // since JDK1.3. This class is only there for backwards compatibility.
      
      // Editor activation is a specific kind of response to ''any''
      // character key. Hence it is handled here.
      if (!table.isEditing() && table.isEnabled())
        {
          int r = table.getSelectedRow();
          int c = table.getSelectedColumn();
          if (table.isCellEditable(r, c))
            table.editCellAt(r, c);
        }
    }

    /**
     * Receives notification that a key has been pressed.
     *
     * @param event the key event
     */
    public void keyPressed(KeyEvent event)
    {
      // Key events should be handled through the InputMap/ActionMap mechanism
      // since JDK1.3. This class is only there for backwards compatibility.
    }

    /**
     * Receives notification that a key has been released.
     *
     * @param event the key event
     */
    public void keyReleased(KeyEvent event)
    {
      // Key events should be handled through the InputMap/ActionMap mechanism
      // since JDK1.3. This class is only there for backwards compatibility.
    }
  }

  public class FocusHandler implements FocusListener
  {
    public void focusGained(FocusEvent e)
    {
      // The only thing that is affected by a focus change seems to be
      // how the lead cell is painted. So we repaint this cell.
      repaintLeadCell();
    }

    public void focusLost(FocusEvent e)
    {
      // The only thing that is affected by a focus change seems to be
      // how the lead cell is painted. So we repaint this cell.
      repaintLeadCell();
    }

    /**
     * Repaints the lead cell in response to a focus change, to refresh
     * the display of the focus indicator.
     */
    private void repaintLeadCell()
    {
      int rowCount = table.getRowCount();
      int columnCount = table.getColumnCount();
      int rowLead = table.getSelectionModel().getLeadSelectionIndex();
      int columnLead = table.getColumnModel().getSelectionModel().
                                                       getLeadSelectionIndex();
      if (rowLead >= 0 && rowLead < rowCount && columnLead >= 0
          && columnLead < columnCount)
        {
          Rectangle dirtyRect = table.getCellRect(rowLead, columnLead, false);
          table.repaint(dirtyRect);
        }
    }
  }

  public class MouseInputHandler implements MouseInputListener
  {
    Point begin, curr;

    private void updateSelection(boolean controlPressed)
    {
      // Update the rows
      int lo_row = table.rowAtPoint(begin);
      int hi_row  = table.rowAtPoint(curr);
      ListSelectionModel rowModel = table.getSelectionModel();
      if (lo_row != -1 && hi_row != -1)
        {
          if (controlPressed && rowModel.getSelectionMode() 
              != ListSelectionModel.SINGLE_SELECTION)
            rowModel.addSelectionInterval(lo_row, hi_row);
          else
            rowModel.setSelectionInterval(lo_row, hi_row);
        }
      
      // Update the columns
      int lo_col = table.columnAtPoint(begin);
      int hi_col = table.columnAtPoint(curr);
      ListSelectionModel colModel = table.getColumnModel().
        getSelectionModel();
      if (lo_col != -1 && hi_col != -1)
        {
          if (controlPressed && colModel.getSelectionMode() != 
              ListSelectionModel.SINGLE_SELECTION)
            colModel.addSelectionInterval(lo_col, hi_col);
          else
            colModel.setSelectionInterval(lo_col, hi_col);
        }
    }
    
    /**
     * For the double click, start the cell editor.
     */
    public void mouseClicked(MouseEvent e)
    {
      Point p = e.getPoint();
      int row = table.rowAtPoint(p);
      int col = table.columnAtPoint(p);
      if (table.isCellEditable(row, col))
        {
          // If the cell editor is the default editor, we request the
          // number of the required clicks from it. Otherwise,
          // require two clicks (double click).
          TableCellEditor editor = table.getCellEditor(row, col);
          if (editor instanceof DefaultCellEditor)
            {
              DefaultCellEditor ce = (DefaultCellEditor) editor;
              if (e.getClickCount() < ce.getClickCountToStart())
                return;
            }
          table.editCellAt(row, col);
        }
    }

    public void mouseDragged(MouseEvent e) 
    {
      if (table.isEnabled())
        {
          curr = new Point(e.getX(), e.getY());
          updateSelection(e.isControlDown());
        }
    }

    public void mouseEntered(MouseEvent e)
    {
      // Nothing to do here.
    }

    public void mouseExited(MouseEvent e)
    {
      // Nothing to do here.
    }

    public void mouseMoved(MouseEvent e)
    {
      // Nothing to do here.
    }

    public void mousePressed(MouseEvent e) 
    {
      if (table.isEnabled())
        {
          ListSelectionModel rowModel = table.getSelectionModel();
          ListSelectionModel colModel = table.getColumnModel().getSelectionModel();
          int rowLead = rowModel.getLeadSelectionIndex();
          int colLead = colModel.getLeadSelectionIndex();

          begin = new Point(e.getX(), e.getY());
          curr = new Point(e.getX(), e.getY());
          //if control is pressed and the cell is already selected, deselect it
          if (e.isControlDown() && table.isCellSelected(
              table.rowAtPoint(begin), table.columnAtPoint(begin)))
            {                                       
              table.getSelectionModel().
              removeSelectionInterval(table.rowAtPoint(begin), 
                                      table.rowAtPoint(begin));
              table.getColumnModel().getSelectionModel().
              removeSelectionInterval(table.columnAtPoint(begin), 
                                      table.columnAtPoint(begin));
            }
          else
            updateSelection(e.isControlDown());

          // If we were editing, but the moved to another cell, stop editing
          if (rowLead != rowModel.getLeadSelectionIndex() ||
              colLead != colModel.getLeadSelectionIndex())
            if (table.isEditing())
              table.editingStopped(new ChangeEvent(e));

          // Must request focus explicitly.
          table.requestFocusInWindow();
        }
    }

    public void mouseReleased(MouseEvent e) 
    {
      if (table.isEnabled())
        {
          begin = null;
          curr = null;
        }
    }
  }

  /**
   * Listens for changes to the model property of the JTable and adjusts some
   * settings.
   *
   * @author Roman Kennke (kennke@aicas.com)
   */
  private class PropertyChangeHandler implements PropertyChangeListener
  {
    /**
     * Receives notification if one of the JTable's properties changes.
     *
     * @param ev the property change event
     */
    public void propertyChange(PropertyChangeEvent ev)
    {
      String propName = ev.getPropertyName();
      if (propName.equals("model"))
        {
          ListSelectionModel rowSel = table.getSelectionModel();
          rowSel.clearSelection();
          ListSelectionModel colSel = table.getColumnModel().getSelectionModel();
          colSel.clearSelection();
          TableModel model = table.getModel();

          // Adjust lead and anchor selection indices of the row and column
          // selection models.
          if (model.getRowCount() > 0)
            {
              rowSel.setAnchorSelectionIndex(0);
              rowSel.setLeadSelectionIndex(0);
            }
          else
            {
              rowSel.setAnchorSelectionIndex(-1);
              rowSel.setLeadSelectionIndex(-1);
            }
          if (model.getColumnCount() > 0)
            {
              colSel.setAnchorSelectionIndex(0);
              colSel.setLeadSelectionIndex(0);
            }
          else
            {
              colSel.setAnchorSelectionIndex(-1);
              colSel.setLeadSelectionIndex(-1);
            }
        }
    }
  }

  protected FocusListener createFocusListener() 
  {
    return new FocusHandler();
  }

  protected MouseInputListener createMouseInputListener() 
  {
    return new MouseInputHandler();
  }


  /**
   * Creates and returns a key listener for the JTable.
   *
   * @return a key listener for the JTable
   */
  protected KeyListener createKeyListener()
  {
    return new KeyHandler();
  }

  /**
   * Return the maximum size of the table. The maximum height is the row 
    * height times the number of rows. The maximum width is the sum of 
    * the maximum widths of each column.
    * 
    *  @param comp the component whose maximum size is being queried,
    *  this is ignored.
    *  @return a Dimension object representing the maximum size of the table,
    *  or null if the table has no elements.
   */
  public Dimension getMaximumSize(JComponent comp) 
  {
    int maxTotalColumnWidth = 0;
    for (int i = 0; i < table.getColumnCount(); i++)
      maxTotalColumnWidth += table.getColumnModel().getColumn(i).getMaxWidth();

    return new Dimension(maxTotalColumnWidth, getHeight());
  }

  /**
   * Return the minimum size of the table. The minimum height is the row 
    * height times the number of rows. The minimum width is the sum of 
    * the minimum widths of each column.
    * 
    *  @param comp the component whose minimum size is being queried,
    *  this is ignored.
    *  @return a Dimension object representing the minimum size of the table,
    *  or null if the table has no elements.
   */
  public Dimension getMinimumSize(JComponent comp) 
  {
    int minTotalColumnWidth = 0;
    for (int i = 0; i < table.getColumnCount(); i++)
      minTotalColumnWidth += table.getColumnModel().getColumn(i).getMinWidth();

    return new Dimension(minTotalColumnWidth, getHeight());
  }

  /**
   * Returns the preferred size for the table of that UI.
   *
   * @param comp ignored, the <code>table</code> field is used instead
   *
   * @return the preferred size for the table of that UI
   */
  public Dimension getPreferredSize(JComponent comp) 
  {
    int prefTotalColumnWidth = 0;
    for (int i = 0; i < table.getColumnCount(); i++)
      {
        TableColumn col = table.getColumnModel().getColumn(i);
        prefTotalColumnWidth += col.getPreferredWidth();
      }
    return new Dimension(prefTotalColumnWidth, getHeight());
  }

  /**
   * Returns the table height. This helper method is used by
   * {@link #getMinimumSize(JComponent)}, {@link #getPreferredSize(JComponent)}
   * and {@link #getMaximumSize(JComponent)} to determine the table height.
   *
   * @return the table height
   */
  private int getHeight()
  {
    int height = 0;
    int rowCount = table.getRowCount(); 
    if (rowCount > 0 && table.getColumnCount() > 0)
      {
        Rectangle r = table.getCellRect(rowCount - 1, 0, true);
        height = r.y + r.height;
      }
    return height;
  }

  protected void installDefaults() 
  {
    LookAndFeel.installColorsAndFont(table, "Table.background",
                                     "Table.foreground", "Table.font");
    table.setGridColor(UIManager.getColor("Table.gridColor"));
    table.setSelectionForeground(UIManager.getColor("Table.selectionForeground"));
    table.setSelectionBackground(UIManager.getColor("Table.selectionBackground"));
    table.setOpaque(true);
  }

  /**
   * Installs keyboard actions on the table.
   */
  protected void installKeyboardActions() 
  {
    // Install the input map.
    InputMap inputMap =
      (InputMap) SharedUIDefaults.get("Table.ancestorInputMap");
    SwingUtilities.replaceUIInputMap(table,
                                 JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
                                 inputMap);

    // FIXME: The JDK uses a LazyActionMap for parentActionMap
    SwingUtilities.replaceUIActionMap(table, getActionMap());

  }

  /**
   * Fetches the action map from  the UI defaults, or create a new one
   * if the action map hasn't been initialized.
   *
   * @return the action map
   */
  private ActionMap getActionMap()
  {
    ActionMap am = (ActionMap) UIManager.get("Table.actionMap");
    if (am == null)
      {
        am = createDefaultActions();
        UIManager.getLookAndFeelDefaults().put("Table.actionMap", am);
      }
    return am;
  }

  private ActionMap createDefaultActions()
  {
    ActionMapUIResource am = new ActionMapUIResource();
    Action action = new TableAction();

    am.put("cut", TransferHandler.getCutAction());
    am.put("copy", TransferHandler.getCopyAction());
    am.put("paste", TransferHandler.getPasteAction());

    am.put("cancel", action);
    am.put("selectAll", action);
    am.put("clearSelection", action);
    am.put("startEditing", action);

    am.put("selectNextRow", action);
    am.put("selectNextRowCell", action);
    am.put("selectNextRowExtendSelection", action);
    am.put("selectNextRowChangeLead", action);

    am.put("selectPreviousRow", action);
    am.put("selectPreviousRowCell", action);
    am.put("selectPreviousRowExtendSelection", action);
    am.put("selectPreviousRowChangeLead", action);

    am.put("selectNextColumn", action);
    am.put("selectNextColumnCell", action);
    am.put("selectNextColumnExtendSelection", action);
    am.put("selectNextColumnChangeLead", action);

    am.put("selectPreviousColumn", action);
    am.put("selectPreviousColumnCell", action);
    am.put("selectPreviousColumnExtendSelection", action);
    am.put("selectPreviousColumnChangeLead", action);

    am.put("scrollLeftChangeSelection", action);
    am.put("scrollLeftExtendSelection", action);
    am.put("scrollRightChangeSelection", action);
    am.put("scrollRightExtendSelection", action);

    am.put("scrollUpChangeSelection", action);
    am.put("scrollUpExtendSelection", action);
    am.put("scrollDownChangeSelection", action);
    am.put("scrolldownExtendSelection", action);

    am.put("selectFirstColumn", action);
    am.put("selectFirstColumnExtendSelection", action);
    am.put("selectLastColumn", action);
    am.put("selectLastColumnExtendSelection", action);

    am.put("selectFirstRow", action);
    am.put("selectFirstRowExtendSelection", action);
    am.put("selectLastRow", action);
    am.put("selectLastRowExtendSelection", action);

    am.put("addToSelection", action);
    am.put("toggleAndAnchor", action);
    am.put("extendTo", action);
    am.put("moveSelectionTo", action);

    return am;
  }

  /**
   * This class implements the actions that we want to happen
   * when specific keys are pressed for the JTable.  The actionPerformed
   * method is called when a key that has been registered for the JTable
   * is received.
   */
  private static class TableAction
    extends AbstractAction
  {
    /**
     * What to do when this action is called.
     *
     * @param e the ActionEvent that caused this action.
     */
    public void actionPerformed(ActionEvent e)
    {
      JTable table = (JTable) e.getSource();

      DefaultListSelectionModel rowModel 
          = (DefaultListSelectionModel) table.getSelectionModel();
      DefaultListSelectionModel colModel 
          = (DefaultListSelectionModel) table.getColumnModel().getSelectionModel();

      int rowLead = rowModel.getLeadSelectionIndex();
      int rowMax = table.getModel().getRowCount() - 1;
      
      int colLead = colModel.getLeadSelectionIndex();
      int colMax = table.getModel().getColumnCount() - 1;

      // The command with which the action has been called is stored
      // in this undocumented action value. This allows us to have only
      // one Action instance to serve all keyboard input for JTable.
      String command = (String) getValue("__command__");
      if (command.equals("selectPreviousRowExtendSelection"))
        {
          rowModel.setLeadSelectionIndex(Math.max(rowLead - 1, 0));
        }
      else if (command.equals("selectLastColumn"))
        {
          colModel.setSelectionInterval(colMax, colMax);
        }
      else if (command.equals("startEditing"))
        {
          if (table.isCellEditable(rowLead, colLead))
            table.editCellAt(rowLead, colLead);
        }
      else if (command.equals("selectFirstRowExtendSelection"))
        {              
          rowModel.setLeadSelectionIndex(0);
        }
      else if (command.equals("selectFirstColumn"))
        {
          colModel.setSelectionInterval(0, 0);
        }
      else if (command.equals("selectFirstColumnExtendSelection"))
        {
          colModel.setLeadSelectionIndex(0);
        }      
      else if (command.equals("selectLastRow"))
        {
          rowModel.setSelectionInterval(rowMax, rowMax);
        }
      else if (command.equals("selectNextRowExtendSelection"))
        {
          rowModel.setLeadSelectionIndex(Math.min(rowLead + 1, rowMax));
        }
      else if (command.equals("selectFirstRow"))
        {
          rowModel.setSelectionInterval(0, 0);
        }
      else if (command.equals("selectNextColumnExtendSelection"))
        {
          colModel.setLeadSelectionIndex(Math.min(colLead + 1, colMax));
        }
      else if (command.equals("selectLastColumnExtendSelection"))
        {
          colModel.setLeadSelectionIndex(colMax);
        }
      else if (command.equals("selectPreviousColumnExtendSelection"))
        {
          colModel.setLeadSelectionIndex(Math.max(colLead - 1, 0));
        }
      else if (command.equals("selectNextRow"))
        {
          rowModel.setSelectionInterval(Math.min(rowLead + 1, rowMax),
                                        Math.min(rowLead + 1, rowMax));
        }
      else if (command.equals("scrollUpExtendSelection"))
        {
          int target;
          if (rowLead == getFirstVisibleRowIndex(table))
            target = Math.max(0, rowLead - (getLastVisibleRowIndex(table) 
                - getFirstVisibleRowIndex(table) + 1));
          else
            target = getFirstVisibleRowIndex(table);
          
          rowModel.setLeadSelectionIndex(target);
          colModel.setLeadSelectionIndex(colLead);
        }
      else if (command.equals("selectPreviousRow"))
        {
          rowModel.setSelectionInterval(Math.max(rowLead - 1, 0),
                                        Math.max(rowLead - 1, 0));
        }
      else if (command.equals("scrollRightChangeSelection"))
        {
          int target;
          if (colLead == getLastVisibleColumnIndex(table))
            target = Math.min(colMax, colLead
                              + (getLastVisibleColumnIndex(table)
                              - getFirstVisibleColumnIndex(table) + 1));
          else
            target = getLastVisibleColumnIndex(table);
          
          colModel.setSelectionInterval(target, target);
          rowModel.setSelectionInterval(rowLead, rowLead);
        }
      else if (command.equals("selectPreviousColumn"))
        {
          colModel.setSelectionInterval(Math.max(colLead - 1, 0),
                                        Math.max(colLead - 1, 0));
        }
      else if (command.equals("scrollLeftChangeSelection"))
        {
          int target;
          if (colLead == getFirstVisibleColumnIndex(table))
            target = Math.max(0, colLead - (getLastVisibleColumnIndex(table) 
                                 - getFirstVisibleColumnIndex(table) + 1));
          else
            target = getFirstVisibleColumnIndex(table);
          
          colModel.setSelectionInterval(target, target);
          rowModel.setSelectionInterval(rowLead, rowLead);
        }
      else if (command.equals("clearSelection"))
        {
          table.clearSelection();
        }
      else if (command.equals("cancel"))
        {
          // FIXME: implement other parts of "cancel" like undo-ing last
          // selection.  Right now it just calls editingCancelled if
          // we're currently editing.
          if (table.isEditing())
            table.editingCanceled(new ChangeEvent("cancel"));
        }
      else if (command.equals("selectNextRowCell")
               || command.equals("selectPreviousRowCell")
               || command.equals("selectNextColumnCell")
               || command.equals("selectPreviousColumnCell"))
        {
          // If nothing is selected, select the first cell in the table
          if (table.getSelectedRowCount() == 0 && 
              table.getSelectedColumnCount() == 0)
            {
              rowModel.setSelectionInterval(0, 0);
              colModel.setSelectionInterval(0, 0);
              return;
            }
          
          // If the lead selection index isn't selected (ie a remove operation
          // happened, then set the lead to the first selected cell in the
          // table
          if (!table.isCellSelected(rowLead, colLead))
            {
              rowModel.addSelectionInterval(rowModel.getMinSelectionIndex(), 
                                            rowModel.getMinSelectionIndex());
              colModel.addSelectionInterval(colModel.getMinSelectionIndex(), 
                                            colModel.getMinSelectionIndex());
              return;
            }
          
          // multRowsSelected and multColsSelected tell us if multiple rows or
          // columns are selected, respectively
          boolean multRowsSelected, multColsSelected;
          multRowsSelected = table.getSelectedRowCount() > 1 &&
            table.getRowSelectionAllowed();
          
          multColsSelected = table.getSelectedColumnCount() > 1 &&
            table.getColumnSelectionAllowed();
          
          // If there is just one selection, select the next cell, and wrap
          // when you get to the edges of the table.
          if (!multColsSelected && !multRowsSelected)
            {
              if (command.indexOf("Column") != -1) 
                advanceSingleSelection(colModel, colMax, rowModel, rowMax, 
                    command.equals("selectPreviousColumnCell"));
              else
                advanceSingleSelection(rowModel, rowMax, colModel, colMax, 
                    command.equals("selectPreviousRowCell"));
              return;
            }
          
          
          // rowMinSelected and rowMaxSelected are the minimum and maximum
          // values respectively of selected cells in the row selection model
          // Similarly for colMinSelected and colMaxSelected.
          int rowMaxSelected = table.getRowSelectionAllowed() ? 
            rowModel.getMaxSelectionIndex() : table.getModel().getRowCount() - 1;
          int rowMinSelected = table.getRowSelectionAllowed() ? 
            rowModel.getMinSelectionIndex() : 0; 
          int colMaxSelected = table.getColumnSelectionAllowed() ? 
            colModel.getMaxSelectionIndex() : 
            table.getModel().getColumnCount() - 1;
          int colMinSelected = table.getColumnSelectionAllowed() ? 
            colModel.getMinSelectionIndex() : 0;
          
          // If there are multiple rows and columns selected, select the next
          // cell and wrap at the edges of the selection.  
          if (command.indexOf("Column") != -1) 
            advanceMultipleSelection(table, colModel, colMinSelected,
                                     colMaxSelected, rowModel, rowMinSelected,
                                     rowMaxSelected,
                                    command.equals("selectPreviousColumnCell"),
                                    true);
          
          else
            advanceMultipleSelection(table, rowModel, rowMinSelected,
                                     rowMaxSelected, colModel, colMinSelected,
                                     colMaxSelected,
                                     command.equals("selectPreviousRowCell"),
                                     false);
        }
      else if (command.equals("selectNextColumn"))
        {
          colModel.setSelectionInterval(Math.min(colLead + 1, colMax),
                                        Math.min(colLead + 1, colMax));
        }
      else if (command.equals("scrollLeftExtendSelection"))
        {
          int target;
          if (colLead == getFirstVisibleColumnIndex(table))
            target = Math.max(0, colLead - (getLastVisibleColumnIndex(table) 
                                 - getFirstVisibleColumnIndex(table) + 1));
          else
            target = getFirstVisibleColumnIndex(table);
          
          colModel.setLeadSelectionIndex(target);
          rowModel.setLeadSelectionIndex(rowLead);
        }
      else if (command.equals("scrollDownChangeSelection"))
        {
          int target;
          if (rowLead == getLastVisibleRowIndex(table))
            target = Math.min(rowMax, rowLead + (getLastVisibleRowIndex(table)
                                      - getFirstVisibleRowIndex(table) + 1));
          else
            target = getLastVisibleRowIndex(table);
          
          rowModel.setSelectionInterval(target, target);
          colModel.setSelectionInterval(colLead, colLead);
        }
      else if (command.equals("scrollRightExtendSelection"))
        {
          int target;
          if (colLead == getLastVisibleColumnIndex(table))
            target = Math.min(colMax, colLead + (getLastVisibleColumnIndex(table) 
                - getFirstVisibleColumnIndex(table) + 1));
          else
            target = getLastVisibleColumnIndex(table);
          
          colModel.setLeadSelectionIndex(target);
          rowModel.setLeadSelectionIndex(rowLead);
        }
      else if (command.equals("selectAll"))
        {
          table.selectAll();
        }
      else if (command.equals("selectLastRowExtendSelection"))
        {
          rowModel.setLeadSelectionIndex(rowMax);
          colModel.setLeadSelectionIndex(colLead);
        }
      else if (command.equals("scrollDownExtendSelection"))
        {
          int target;
          if (rowLead == getLastVisibleRowIndex(table))
            target = Math.min(rowMax, rowLead + (getLastVisibleRowIndex(table) 
                - getFirstVisibleRowIndex(table) + 1));
          else
            target = getLastVisibleRowIndex(table);
          
          rowModel.setLeadSelectionIndex(target);
          colModel.setLeadSelectionIndex(colLead);
        }      
      else if (command.equals("scrollUpChangeSelection"))
        {
          int target;
          if (rowLead == getFirstVisibleRowIndex(table))
            target = Math.max(0, rowLead - (getLastVisibleRowIndex(table) 
                - getFirstVisibleRowIndex(table) + 1));
          else
            target = getFirstVisibleRowIndex(table);
          
          rowModel.setSelectionInterval(target, target);
          colModel.setSelectionInterval(colLead, colLead);
        }
      else if (command.equals("selectNextRowChangeLead"))
          {
            if (rowModel.getSelectionMode() 
                != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
              {
                // just "selectNextRow"
                rowModel.setSelectionInterval(Math.min(rowLead + 1, rowMax),
                                              Math.min(rowLead + 1, rowMax));
                colModel.setSelectionInterval(colLead, colLead);
              }
            else
              rowModel.moveLeadSelectionIndex(Math.min(rowLead + 1, rowMax));
          }
      else if (command.equals("selectPreviousRowChangeLead"))
        {
          if (rowModel.getSelectionMode() 
              != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
            {
              // just selectPreviousRow
              rowModel.setSelectionInterval(Math.max(rowLead - 1, 0),
                                            Math.min(rowLead - 1, 0));
              colModel.setSelectionInterval(colLead, colLead);
            }
          else
            rowModel.moveLeadSelectionIndex(Math.max(rowLead - 1, 0));
        }
      else if (command.equals("selectNextColumnChangeLead"))
        {
          if (colModel.getSelectionMode() 
              != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)            
            {
              // just selectNextColumn
              rowModel.setSelectionInterval(rowLead, rowLead);
              colModel.setSelectionInterval(Math.min(colLead + 1, colMax),
                                            Math.min(colLead + 1, colMax));
            }
          else
            colModel.moveLeadSelectionIndex(Math.min(colLead + 1, colMax));
        }
      else if (command.equals("selectPreviousColumnChangeLead"))
        {
          if (colModel.getSelectionMode() 
              != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)            
            {
              // just selectPreviousColumn
              rowModel.setSelectionInterval(rowLead, rowLead);
              colModel.setSelectionInterval(Math.max(colLead - 1, 0),
                                            Math.max(colLead - 1, 0));
              
            }
          else
            colModel.moveLeadSelectionIndex(Math.max(colLead - 1, 0));
        }
      else if (command.equals("addToSelection"))
          {
            if (!table.isEditing())
              {
                int oldRowAnchor = rowModel.getAnchorSelectionIndex();
                int oldColAnchor = colModel.getAnchorSelectionIndex();
                rowModel.addSelectionInterval(rowLead, rowLead);
                colModel.addSelectionInterval(colLead, colLead);
                rowModel.setAnchorSelectionIndex(oldRowAnchor);
                colModel.setAnchorSelectionIndex(oldColAnchor);
              }
          }
      else if (command.equals("extendTo"))
        {
          rowModel.setSelectionInterval(rowModel.getAnchorSelectionIndex(),
                                        rowLead);
          colModel.setSelectionInterval(colModel.getAnchorSelectionIndex(),
                                        colLead);
        }
      else if (command.equals("toggleAndAnchor"))
        {
          if (rowModel.isSelectedIndex(rowLead))
            rowModel.removeSelectionInterval(rowLead, rowLead);
          else
            rowModel.addSelectionInterval(rowLead, rowLead);
          
          if (colModel.isSelectedIndex(colLead))
            colModel.removeSelectionInterval(colLead, colLead);
          else
            colModel.addSelectionInterval(colLead, colLead);
          
          rowModel.setAnchorSelectionIndex(rowLead);
          colModel.setAnchorSelectionIndex(colLead);
        }
      else if (command.equals("stopEditing"))
        {
          table.editingStopped(new ChangeEvent(command));
        }
      else 
        {
          // If we're here that means we bound this TableAction class
          // to a keyboard input but we either want to ignore that input
          // or we just haven't implemented its action yet.
          
          // Uncomment the following line to print the names of unused bindings
          // when their keys are pressed
          
          // System.out.println ("not implemented: "+e.getActionCommand());
        }

      // Any commands whose keyStrokes should be used by the Editor should not
      // cause editing to be stopped: ie, the SPACE sends "addToSelection" but 
      // if the table is in editing mode, the space should not cause us to stop
      // editing because it should be used by the Editor.
      if (table.isEditing() && command != "startEditing"
          && command != "addToSelection")
        table.editingStopped(new ChangeEvent("update"));
            
      table.scrollRectToVisible(table.getCellRect(
          rowModel.getLeadSelectionIndex(), colModel.getLeadSelectionIndex(), 
          false));
    }
    
    /**
     * Returns the column index of the first visible column.
     * @return the column index of the first visible column.
     */
    int getFirstVisibleColumnIndex(JTable table)
    {
      ComponentOrientation or = table.getComponentOrientation();
      Rectangle r = table.getVisibleRect();
      if (!or.isLeftToRight())
        r.translate((int) r.getWidth() - 1, 0);
      return table.columnAtPoint(r.getLocation());
    }
    
    /**
     * Returns the column index of the last visible column.
     *
     */
    int getLastVisibleColumnIndex(JTable table)
    {
      ComponentOrientation or = table.getComponentOrientation();
      Rectangle r = table.getVisibleRect();
      if (or.isLeftToRight())
        r.translate((int) r.getWidth() - 1, 0);
      return table.columnAtPoint(r.getLocation());      
    }
    
    /**
     * Returns the row index of the first visible row.
     *
     */
    int getFirstVisibleRowIndex(JTable table)
    {
      ComponentOrientation or = table.getComponentOrientation();
      Rectangle r = table.getVisibleRect();
      if (!or.isLeftToRight())
        r.translate((int) r.getWidth() - 1, 0);
      return table.rowAtPoint(r.getLocation());
    }
    
    /**
     * Returns the row index of the last visible row.
     *
     */
    int getLastVisibleRowIndex(JTable table)
    {
      ComponentOrientation or = table.getComponentOrientation();
      Rectangle r = table.getVisibleRect();
      r.translate(0, (int) r.getHeight() - 1);
      if (or.isLeftToRight())
        r.translate((int) r.getWidth() - 1, 0);
      // The next if makes sure that we don't return -1 simply because
      // there is white space at the bottom of the table (ie, the display
      // area is larger than the table)
      if (table.rowAtPoint(r.getLocation()) == -1)
        {
          if (getFirstVisibleRowIndex(table) == -1)
            return -1;
          else
            return table.getModel().getRowCount() - 1;
        }
      return table.rowAtPoint(r.getLocation());
    }

    /**
     * A helper method for the key bindings.  Used because the actions
     * for TAB, SHIFT-TAB, ENTER, and SHIFT-ENTER are very similar.
     *
     * Selects the next (previous if SHIFT pressed) column for TAB, or row for
     * ENTER from within the currently selected cells.
     *
     * @param firstModel the ListSelectionModel for columns (TAB) or
     * rows (ENTER)
     * @param firstMin the first selected index in firstModel
     * @param firstMax the last selected index in firstModel
     * @param secondModel the ListSelectionModel for rows (TAB) or 
     * columns (ENTER)
     * @param secondMin the first selected index in secondModel
     * @param secondMax the last selected index in secondModel
     * @param reverse true if shift was held for the event
     * @param eventIsTab true if TAB was pressed, false if ENTER pressed
     */
    void advanceMultipleSelection(JTable table, ListSelectionModel firstModel,
                                  int firstMin,
                                  int firstMax, ListSelectionModel secondModel, 
                                  int secondMin, int secondMax, boolean reverse,
                                  boolean eventIsTab)
    {
      // If eventIsTab, all the "firsts" correspond to columns, otherwise, to 
      // rows "seconds" correspond to the opposite
      int firstLead = firstModel.getLeadSelectionIndex();
      int secondLead = secondModel.getLeadSelectionIndex();
      int numFirsts = eventIsTab ? 
        table.getModel().getColumnCount() : table.getModel().getRowCount();
      int numSeconds = eventIsTab ? 
        table.getModel().getRowCount() : table.getModel().getColumnCount();

      // check if we have to wrap the "firsts" around, going to the other side
      if ((firstLead == firstMax && !reverse) || 
          (reverse && firstLead == firstMin))
        {
          firstModel.addSelectionInterval(reverse ? firstMax : firstMin, 
                                          reverse ? firstMax : firstMin);
          
          // check if we have to wrap the "seconds"
          if ((secondLead == secondMax && !reverse) || 
              (reverse && secondLead == secondMin))
            secondModel.addSelectionInterval(reverse ? secondMax : secondMin, 
                                             reverse ? secondMax : secondMin);

          // if we're not wrapping the seconds, we have to find out where we
          // are within the secondModel and advance to the next cell (or 
          // go back to the previous cell if reverse == true)
          else
            {
              int[] secondsSelected;
              if (eventIsTab && table.getRowSelectionAllowed() || 
                  !eventIsTab && table.getColumnSelectionAllowed())
                secondsSelected = eventIsTab ? 
                  table.getSelectedRows() : table.getSelectedColumns();
              else
                {
                  // if row selection is not allowed, then the entire column gets
                  // selected when you click on it, so consider ALL rows selected
                  secondsSelected = new int[numSeconds];
                  for (int i = 0; i < numSeconds; i++)
                  secondsSelected[i] = i;
                }

              // and now find the "next" index within the model
              int secondIndex = reverse ? secondsSelected.length - 1 : 0;
              if (!reverse)
                while (secondsSelected[secondIndex] <= secondLead)
                  secondIndex++;
              else
                while (secondsSelected[secondIndex] >= secondLead)
                  secondIndex--;
              
              // and select it - updating the lead selection index
              secondModel.addSelectionInterval(secondsSelected[secondIndex], 
                                               secondsSelected[secondIndex]);
            }
        }
      // We didn't have to wrap the firsts, so just find the "next" first
      // and select it, we don't have to change "seconds"
      else
        {
          int[] firstsSelected;
          if (eventIsTab && table.getColumnSelectionAllowed() || 
              !eventIsTab && table.getRowSelectionAllowed())
            firstsSelected = eventIsTab ? 
              table.getSelectedColumns() : table.getSelectedRows();
          else
            {
              // if selection not allowed, consider ALL firsts to be selected
              firstsSelected = new int[numFirsts];
              for (int i = 0; i < numFirsts; i++)
                firstsSelected[i] = i;
            }
          int firstIndex = reverse ? firstsSelected.length - 1 : 0;
          if (!reverse)
            while (firstsSelected[firstIndex] <= firstLead)
              firstIndex++;
          else 
            while (firstsSelected[firstIndex] >= firstLead)
              firstIndex--;
          firstModel.addSelectionInterval(firstsSelected[firstIndex], 
                                          firstsSelected[firstIndex]);
          secondModel.addSelectionInterval(secondLead, secondLead);
        }
    }
    
    /** 
     * A helper method for the key  bindings. Used because the actions
     * for TAB, SHIFT-TAB, ENTER, and SHIFT-ENTER are very similar.
     *
     * Selects the next (previous if SHIFT pressed) column (TAB) or row (ENTER)
     * in the table, changing the current selection.  All cells in the table
     * are eligible, not just the ones that are currently selected.
     * @param firstModel the ListSelectionModel for columns (TAB) or rows
     * (ENTER)
     * @param firstMax the last index in firstModel
     * @param secondModel the ListSelectionModel for rows (TAB) or columns
     * (ENTER)
     * @param secondMax the last index in secondModel
     * @param reverse true if SHIFT was pressed for the event
     */

    void advanceSingleSelection(ListSelectionModel firstModel, int firstMax, 
                                ListSelectionModel secondModel, int secondMax, 
                                boolean reverse)
    {
      // for TABs, "first" corresponds to columns and "seconds" to rows.
      // the opposite is true for ENTERs
      int firstLead = firstModel.getLeadSelectionIndex();
      int secondLead = secondModel.getLeadSelectionIndex();
      
      // if we are going backwards subtract 2 because we later add 1
      // for a net change of -1
      if (reverse && (firstLead == 0))
        {
          // check if we have to wrap around
          if (secondLead == 0)
            secondLead += secondMax + 1;
          secondLead -= 2;
        }
      
      // do we have to wrap the "seconds"?
      if (reverse && (firstLead == 0) || !reverse && (firstLead == firstMax))
        secondModel.setSelectionInterval((secondLead + 1) % (secondMax + 1), 
                                         (secondLead + 1) % (secondMax + 1));
      // if not, just reselect the current lead
      else
        secondModel.setSelectionInterval(secondLead, secondLead);
      
      // if we are going backwards, subtract 2  because we add 1 later
      // for net change of -1
      if (reverse)
        {
          // check for wraparound
          if (firstLead == 0)
            firstLead += firstMax + 1;
          firstLead -= 2;
        }
      // select the next "first"
      firstModel.setSelectionInterval((firstLead + 1) % (firstMax + 1), 
                                      (firstLead + 1) % (firstMax + 1));
    }
  }

  protected void installListeners() 
  {
    if (focusListener == null)
      focusListener = createFocusListener();
    table.addFocusListener(focusListener);
    if (keyListener == null)
      keyListener = createKeyListener();
    table.addKeyListener(keyListener);
    if (mouseInputListener == null)
      mouseInputListener = createMouseInputListener();
    table.addMouseListener(mouseInputListener);    
    table.addMouseMotionListener(mouseInputListener);
    if (propertyChangeListener == null)
      propertyChangeListener = new PropertyChangeHandler();
    table.addPropertyChangeListener(propertyChangeListener);
  }

  /**
   * Uninstalls UI defaults that have been installed by
   * {@link #installDefaults()}.
   */
  protected void uninstallDefaults()
  {
    // Nothing to do here for now.
  }

  /**
   * Uninstalls the keyboard actions that have been installed by
   * {@link #installKeyboardActions()}.
   */
  protected void uninstallKeyboardActions()
  {
    SwingUtilities.replaceUIInputMap(table, JComponent.
                                     WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
    SwingUtilities.replaceUIActionMap(table, null);
  }

  protected void uninstallListeners() 
  {
    table.removeFocusListener(focusListener);  
    table.removeKeyListener(keyListener);
    table.removeMouseListener(mouseInputListener);    
    table.removeMouseMotionListener(mouseInputListener);
    table.removePropertyChangeListener(propertyChangeListener);
    propertyChangeListener = null;
  }

  public void installUI(JComponent comp) 
  {
    table = (JTable) comp;
    rendererPane = new CellRendererPane();
    table.add(rendererPane);

    installDefaults();
    installKeyboardActions();
    installListeners();
  }

  public void uninstallUI(JComponent c) 
  {
    uninstallListeners();
    uninstallKeyboardActions();
    uninstallDefaults(); 

    table.remove(rendererPane);
    rendererPane = null;
    table = null;
  }

  /**
   * Paints a single cell in the table.
   *
   * @param g The graphics context to paint in
   * @param row The row number to paint
   * @param col The column number to paint
   * @param bounds The bounds of the cell to paint, assuming a coordinate
   * system beginning at <code>(0,0)</code> in the upper left corner of the
   * table
   * @param rend A cell renderer to paint with
   */
  void paintCell(Graphics g, int row, int col, Rectangle bounds,
                 TableCellRenderer rend)
  {
    Component comp = table.prepareRenderer(rend, row, col);
    rendererPane.paintComponent(g, comp, table, bounds);
  }
  
  /**
   * Paint the associated table.
   */
  public void paint(Graphics gfx, JComponent ignored) 
  {
    int ncols = table.getColumnCount();
    int nrows = table.getRowCount();
    if (nrows == 0 || ncols == 0)
      return;

    Rectangle clip = gfx.getClipBounds();

    // Determine the range of cells that are within the clip bounds.
    Point p1 = new Point(clip.x, clip.y);
    int c0 = table.columnAtPoint(p1);
    if (c0 == -1)
      c0 = 0;
    int r0 = table.rowAtPoint(p1);
    if (r0 == -1)
      r0 = 0;
    Point p2 = new Point(clip.x + clip.width, clip.y + clip.height);
    int cn = table.columnAtPoint(p2);
    if (cn == -1)
      cn = table.getColumnCount() - 1;
    int rn = table.rowAtPoint(p2);
    if (rn == -1)
      rn = table.getRowCount() - 1;

    int columnMargin = table.getColumnModel().getColumnMargin();
    int rowMargin = table.getRowMargin();

    TableColumnModel cmodel = table.getColumnModel();
    int[] widths = new int[cn + 1];
    for (int i = c0; i <= cn; i++)
      {
        widths[i] = cmodel.getColumn(i).getWidth() - columnMargin;
      }
    
    Rectangle bounds = table.getCellRect(r0, c0, false);
    // The left boundary of the area being repainted.
    int left = bounds.x;
    
    // The top boundary of the area being repainted.
    int top = bounds.y;
    
    // The bottom boundary of the area being repainted.
    int bottom;
    
    // paint the cell contents
    Color grid = table.getGridColor();    
    for (int r = r0; r <= rn; ++r)
      {
        for (int c = c0; c <= cn; ++c)
          {
            bounds.width = widths[c];
            paintCell(gfx, r, c, bounds, table.getCellRenderer(r, c));
            bounds.x += widths[c] + columnMargin;
          }
        bounds.x = left;
        bounds.y += table.getRowHeight(r);
        // Update row height for tables with custom heights.
        bounds.height = table.getRowHeight(r + 1) - rowMargin;
      }
    
    bottom = bounds.y - rowMargin;

    // paint vertical grid lines
    if (grid != null && table.getShowVerticalLines())
      {    
        Color save = gfx.getColor();
        gfx.setColor(grid);
        int x = left - columnMargin;
        for (int c = c0; c <= cn; ++c)
          {
            // The vertical grid is draw right from the cells, so we 
            // add before drawing.
            x += widths[c] + columnMargin;
            gfx.drawLine(x, top, x, bottom);
          }
        gfx.setColor(save);
      }

    // paint horizontal grid lines    
    if (grid != null && table.getShowHorizontalLines())
      {    
        Color save = gfx.getColor();
        gfx.setColor(grid);
        int y = top - rowMargin;
        for (int r = r0; r <= rn; ++r)
          {
            // The horizontal grid is draw below the cells, so we 
            // add before drawing.
            y += table.getRowHeight(r);
            gfx.drawLine(left, y, p2.x, y);
          }
        gfx.setColor(save);
      }
  }
}
