This patch implements the 1.5 API method
DefaultListSelectionModel.moveLeadSelectionIndex(int) and then uses that
to implement several key bindings for JLists and JTables (in BasicListUI
and BasicTableUI).  Also fixed a small bug in
DefaultListSelectionModel.setLeadSelectionIndex(int), and added JTable
bindings to BasicLookAndFeel that weren't there yet.


2005-10-18  Anthony Balkissoon  <[EMAIL PROTECTED]>

        * javax/swing/DefaultListSelectionModel.java:
        (setLeadSelectionIndex): Avoid index out of bounds error on initial
        call of this method by checking explicitly for oldLeadIndex being -1.
        Also remove unused BitSet newRange and oldRange.
        (moveLeadSelectionIndex): New API method implemented (@since 1.5).
        * javax/swing/plaf/basic/BasicListUI.java:
        (ListAction.actionPerformed): Make code more readable by declaring
        local variables for the actionCommand and for the list's
        selectionModel.  Implemented the following bindings: 
        selectLastRowChangeLead, scrollDownChangeLead, scrollUpChangeLead, 
        selectFirstRowChangeLead, selectNextRowChangeLead, 
        selectPreviousRowChangeLead, addToSelection, toggleAndAnchor, 
        extendTo.
        (MouseInputHandler.mousePressed): Made code more readable by removing
        unnecessary full qualification from variable 'list'.  Change 
        behaviour of shift-click based on whether or not the anchor index is 
        selected.
        * javax/swing/plaf/basic/BasicLookAndFeel.java:
        (initComponentDefaults): Added remaining bindings for
        Table.ancestorMap.
        * javax/swing/plaf/basic/BasicTableUI.java:
        (TableAction.actionPerformed): Made type of variables rowModel and 
        colModel more specific to avoid many casts later on (makes code more
        readable).  Also declare local variable to store the action command to 
        make the code more readable. Implemented the following bindings: 
        selectNextRowChangeLead, selectPreviousRowChangeLead, 
        selectNextColumnChangeLead, selectPreviousColumnChangeLead,
        addToSelection, extendTo, toggleAndAnchor.  Added commented-out debug 
        statement to print unimplemented bindings when used.  Added check for 
        the SPACE character to make sure it doesn't stop editing.

--Tony
Index: javax/swing/DefaultListSelectionModel.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/DefaultListSelectionModel.java,v
retrieving revision 1.22
diff -u -r1.22 DefaultListSelectionModel.java
--- javax/swing/DefaultListSelectionModel.java	17 Oct 2005 15:16:46 -0000	1.22
+++ javax/swing/DefaultListSelectionModel.java	18 Oct 2005 17:43:49 -0000
@@ -239,13 +239,15 @@
   public void setLeadSelectionIndex(int leadIndex)
   {
     int oldLeadIndex = leadSelectionIndex;
+    if (oldLeadIndex == -1)
+      oldLeadIndex = leadIndex;
     if (setLeadCalledFromAdd == false)
       oldSel = sel.clone();
     leadSelectionIndex = leadIndex;
 
     if (anchorSelectionIndex == -1)
-      return;
-
+      return;    
+    
     int R1 = Math.min(anchorSelectionIndex, oldLeadIndex);
     int R2 = Math.max(anchorSelectionIndex, oldLeadIndex);
     int S1 = Math.min(anchorSelectionIndex, leadIndex);
@@ -254,8 +256,6 @@
     int lo = Math.min(R1, S1);
     int hi = Math.max(R2, S2);
 
-    BitSet oldRange = sel.get(lo, hi+1);
-
     if (isSelectedIndex(anchorSelectionIndex))
       {
         sel.clear(R1, R2+1);
@@ -265,10 +265,7 @@
       {
         sel.set(R1, R2+1);
         sel.clear(S1, S2+1);
-      }
-    
-    BitSet newRange = sel.get(lo, hi+1);
-    newRange.xor(oldRange);
+      }    
 
     int beg = sel.nextSetBit(0), end = -1;
     for(int i=beg; i >= 0; i=sel.nextSetBit(i+1)) 
@@ -277,6 +274,27 @@
       fireValueChanged(beg, end, valueIsAdjusting);    
   }
 
+  /**
+   * Moves the lead selection index to <code>leadIndex</code> without 
+   * changing the selection values.
+   * 
+   * If leadAnchorNotificationEnabled is true, send a notification covering the
+   * old and new lead cells.
+   * 
+   * @param leadIndex the new lead selection index
+   * @since 1.5
+   */
+  public void moveLeadSelectionIndex (int leadIndex)
+  {
+    if (leadSelectionIndex == leadIndex)
+      return;
+    
+    leadSelectionIndex = leadIndex;
+    if (isLeadAnchorNotificationEnabled())
+      fireValueChanged(Math.min(leadSelectionIndex, leadIndex),
+                       Math.max(leadSelectionIndex, leadIndex));
+  }
+  
   /**
    * Gets the value of the [EMAIL PROTECTED] #leadAnchorNotificationEnabled} property.
    * 
Index: javax/swing/plaf/basic/BasicListUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicListUI.java,v
retrieving revision 1.33
diff -u -r1.33 BasicListUI.java
--- javax/swing/plaf/basic/BasicListUI.java	17 Oct 2005 19:08:23 -0000	1.33
+++ javax/swing/plaf/basic/BasicListUI.java	18 Oct 2005 17:43:49 -0000
@@ -59,6 +59,7 @@
 import javax.swing.AbstractAction;
 import javax.swing.ActionMap;
 import javax.swing.CellRendererPane;
+import javax.swing.DefaultListSelectionModel;
 import javax.swing.InputMap;
 import javax.swing.JComponent;
 import javax.swing.JList;
@@ -228,34 +229,40 @@
     {
       int lead = list.getLeadSelectionIndex();
       int max = list.getModel().getSize() - 1;
+      DefaultListSelectionModel selModel = (DefaultListSelectionModel)list.getSelectionModel();
+      String command = e.getActionCommand();
       // Do nothing if list is empty
       if (max == -1)
         return;
       
-      if (e.getActionCommand().equals("selectNextRow"))
+      if (command.equals("selectNextRow"))
         {
           selectNextIndex();
         }
-      else if (e.getActionCommand().equals("selectPreviousRow"))
+      else if (command.equals("selectPreviousRow"))
         {
           selectPreviousIndex();
         }
-      else if (e.getActionCommand().equals("clearSelection"))
+      else if (command.equals("clearSelection"))
         {
           list.clearSelection();
         }
-      else if (e.getActionCommand().equals("selectAll"))
+      else if (command.equals("selectAll"))
         {
           list.setSelectionInterval(0, max);
           // this next line is to restore the lead selection index to the old
           // position, because select-all should not change the lead index
           list.addSelectionInterval(lead, lead);
         }
-      else if (e.getActionCommand().equals("selectLastRow"))
+      else if (command.equals("selectLastRow"))
         {
           list.setSelectedIndex(list.getModel().getSize() - 1); 
         }
-      else if (e.getActionCommand().equals("scrollDownExtendSelection"))
+      else if (command.equals("selectLastRowChangeLead"))
+        {
+          selModel.moveLeadSelectionIndex(list.getModel().getSize() - 1);
+        }
+      else if (command.equals("scrollDownExtendSelection"))
         {
           int target;
           if (lead == list.getLastVisibleIndex())
@@ -266,9 +273,22 @@
             }
           else
             target = list.getLastVisibleIndex();
-          list.getSelectionModel().setLeadSelectionIndex(target);
+          selModel.setLeadSelectionIndex(target);
         }
-      else if (e.getActionCommand().equals("scrollUpExtendSelection"))
+      else if (command.equals("scrollDownChangeLead"))
+        {
+          int target;
+          if (lead == list.getLastVisibleIndex())
+            {
+              target = Math.min
+                (max, lead + (list.getLastVisibleIndex() -
+                    list.getFirstVisibleIndex() + 1));
+            }
+          else
+            target = list.getLastVisibleIndex();
+          selModel.moveLeadSelectionIndex(target);
+        }
+      else if (command.equals("scrollUpExtendSelection"))
         {
           int target;
           if (lead == list.getFirstVisibleIndex())
@@ -279,26 +299,42 @@
             }
           else
             target = list.getFirstVisibleIndex();
-          list.getSelectionModel().setLeadSelectionIndex(target);
+          selModel.setLeadSelectionIndex(target);
         }
-      else if (e.getActionCommand().equals("selectNextRowExtendSelection"))
+      else if (command.equals("scrollUpChangeLead"))
         {
-          list.getSelectionModel().
-            setLeadSelectionIndex(Math.min(lead + 1,max));
+          int target;
+          if (lead == list.getFirstVisibleIndex())
+            {
+              target = Math.max 
+                (0, lead - (list.getLastVisibleIndex() - 
+                    list.getFirstVisibleIndex() + 1));
+            }
+          else
+            target = list.getFirstVisibleIndex();
+          selModel.moveLeadSelectionIndex(target);
+        }
+      else if (command.equals("selectNextRowExtendSelection"))
+        {
+          selModel.setLeadSelectionIndex(Math.min(lead + 1,max));
         }
-      else if (e.getActionCommand().equals("selectFirstRow"))
+      else if (command.equals("selectFirstRow"))
         {
           list.setSelectedIndex(0);
         }
-      else if (e.getActionCommand().equals("selectFirstRowExtendSelection"))
+      else if (command.equals("selectFirstRowChangeLead"))
+          {
+            selModel.moveLeadSelectionIndex(0);
+          }
+      else if (command.equals("selectFirstRowExtendSelection"))
         {
-          list.getSelectionModel().setLeadSelectionIndex(0);
+          selModel.setLeadSelectionIndex(0);
         }
-      else if (e.getActionCommand().equals("selectPreviousRowExtendSelection"))
+      else if (command.equals("selectPreviousRowExtendSelection"))
         {
-          list.getSelectionModel().setLeadSelectionIndex(Math.max(0,lead - 1));
+          selModel.setLeadSelectionIndex(Math.max(0,lead - 1));
         }
-      else if (e.getActionCommand().equals("scrollUp"))
+      else if (command.equals("scrollUp"))
         {
           int target;
           if (lead == list.getFirstVisibleIndex())
@@ -311,12 +347,11 @@
             target = list.getFirstVisibleIndex();
           list.setSelectedIndex(target);          
         }
-      else if (e.getActionCommand().equals("selectLastRowExtendSelection"))
+      else if (command.equals("selectLastRowExtendSelection"))
         {
-          list.getSelectionModel().
-            setLeadSelectionIndex(list.getModel().getSize() - 1);
+          selModel.setLeadSelectionIndex(list.getModel().getSize() - 1);
         }
-      else if (e.getActionCommand().equals("scrollDown"))
+      else if (command.equals("scrollDown"))
         {
           int target;
           if (lead == list.getLastVisibleIndex())
@@ -329,6 +364,41 @@
             target = list.getLastVisibleIndex();
           list.setSelectedIndex(target);
         }
+      else if (command.equals("selectNextRowChangeLead"))
+          {
+            if (selModel.getSelectionMode() != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
+              selectNextIndex();
+            else
+              {
+                selModel.moveLeadSelectionIndex(Math.min(max, lead + 1));
+              }
+          }
+      else if (command.equals("selectPreviousRowChangeLead"))
+        {
+          if (selModel.getSelectionMode() != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
+            selectPreviousIndex();
+          else
+            {
+              selModel.moveLeadSelectionIndex(Math.max(0, lead - 1));
+            }
+        }      
+      else if (command.equals("addToSelection"))
+        {
+          list.addSelectionInterval(lead, lead);
+        }
+      else if (command.equals("extendTo"))
+        {
+          selModel.setSelectionInterval(selModel.getAnchorSelectionIndex(),
+                                        lead);
+        }
+      else if (command.equals("toggleAndAnchor"))
+        {
+          if (!list.isSelectedIndex(lead))
+            list.addSelectionInterval(lead, lead);
+          else
+            list.removeSelectionInterval(lead, lead);
+          selModel.setAnchorSelectionIndex(lead);
+        }
       else 
         {
           // DEBUG: uncomment the following line to print out 
@@ -356,48 +426,46 @@
     public void mouseClicked(MouseEvent event)
     {
       Point click = event.getPoint();
-      int index = BasicListUI.this.locationToIndex(list, click);
+      int index = locationToIndex(list, click);
       if (index == -1)
         return;
       if (event.isShiftDown())
         {
-          if (BasicListUI.this.list.getSelectionMode() == 
-              ListSelectionModel.SINGLE_SELECTION)
-            BasicListUI.this.list.setSelectedIndex(index);
-          else if (BasicListUI.this.list.getSelectionMode() == 
+          if (list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION)
+            list.setSelectedIndex(index);
+          else if (list.getSelectionMode() == 
                    ListSelectionModel.SINGLE_INTERVAL_SELECTION)
             // COMPAT: the IBM VM is compatible with the following line of code.
             // However, compliance with Sun's VM would correspond to replacing 
             // getAnchorSelectionIndex() with getLeadSelectionIndex().This is 
             // both unnatural and contradictory to the way they handle other 
             // similar UI interactions.
-            BasicListUI.this.list.setSelectionInterval
-              (BasicListUI.this.list.getAnchorSelectionIndex(), index);
+            list.setSelectionInterval(list.getAnchorSelectionIndex(), index);
           else
             // COMPAT: both Sun and IBM are compatible instead with:
-            // BasicListUI.this.list.setSelectionInterval
-            //     (BasicListUI.this.list.getLeadSelectionIndex(),index);
+            // list.setSelectionInterval
+            //     (list.getLeadSelectionIndex(),index);
             // Note that for IBM this is contradictory to what they did in 
             // the above situation for SINGLE_INTERVAL_SELECTION.  
             // The most natural thing to do is the following:
-            BasicListUI.this.list.getSelectionModel().
-              setLeadSelectionIndex(index);
+            if (list.isSelectedIndex(list.getAnchorSelectionIndex()))
+              list.getSelectionModel().setLeadSelectionIndex(index);
+            else
+              list.addSelectionInterval(list.getAnchorSelectionIndex(), index);
         }
       else if (event.isControlDown())
         {
-          if (BasicListUI.this.list.getSelectionMode() == 
-              ListSelectionModel.SINGLE_SELECTION)
-            BasicListUI.this.list.setSelectedIndex(index);
-          else if (BasicListUI.this.list.isSelectedIndex(index))
-            BasicListUI.this.list.removeSelectionInterval(index,index);
+          if (list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION)
+            list.setSelectedIndex(index);
+          else if (list.isSelectedIndex(index))
+            list.removeSelectionInterval(index,index);
           else
-            BasicListUI.this.list.addSelectionInterval(index,index);
+            list.addSelectionInterval(index,index);
         }
       else
-        BasicListUI.this.list.setSelectedIndex(index);
+        list.setSelectedIndex(index);
       
-      BasicListUI.this.list.ensureIndexIsVisible
-        (BasicListUI.this.list.getLeadSelectionIndex());
+      list.ensureIndexIsVisible(list.getLeadSelectionIndex());
     }
 
     /**
Index: javax/swing/plaf/basic/BasicLookAndFeel.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java,v
retrieving revision 1.62
diff -u -r1.62 BasicLookAndFeel.java
--- javax/swing/plaf/basic/BasicLookAndFeel.java	18 Oct 2005 11:05:10 -0000	1.62
+++ javax/swing/plaf/basic/BasicLookAndFeel.java	18 Oct 2005 17:43:49 -0000
@@ -896,6 +896,24 @@
       "TabbedPane.tabRunOverlay", new Integer(2),
       "TabbedPane.textIconGap", new Integer(4),
       "Table.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
+        "ctrl DOWN", "selectNextRowChangeLead",
+        "ctrl RIGHT", "selectNextColumnChangeLead",
+        "ctrl UP", "selectPreviousRowChangeLead",
+        "ctrl LEFT", "selectPreviousColumnChangeLead",
+        "CUT", "cut",
+        "SPACE", "addToSelection",
+        "ctrl SPACE", "toggleAndAnchor",
+        "shift SPACE", "extendTo",
+        "shift ctrl SPACE", "moveSelectionTo",
+        "ctrl X", "cut",
+        "ctrl C", "copy",
+        "ctrl KP_RIGHT", "selectNextColumnChangeLead",
+        "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
+        "ctrl V", "paste",
+        "ctrl KP_DOWN", "selectNextRowChangeLead",
+        "COPY", "copy",
+        "ctrl KP_UP", "selectPreviousRowChangeLead",
+        "PASTE", "paste",
         "shift PAGE_DOWN","scrollDownExtendSelection",
         "PAGE_DOWN", "scrollDownChangeSelection",
         "END",  "selectLastColumn",
Index: javax/swing/plaf/basic/BasicTableUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicTableUI.java,v
retrieving revision 1.31
diff -u -r1.31 BasicTableUI.java
--- javax/swing/plaf/basic/BasicTableUI.java	13 Oct 2005 18:43:50 -0000	1.31
+++ javax/swing/plaf/basic/BasicTableUI.java	18 Oct 2005 17:43:49 -0000
@@ -57,6 +57,7 @@
 import javax.swing.ActionMap;
 import javax.swing.BorderFactory;
 import javax.swing.CellRendererPane;
+import javax.swing.DefaultListSelectionModel;
 import javax.swing.InputMap;
 import javax.swing.JComponent;
 import javax.swing.JTable;
@@ -437,8 +438,8 @@
      */
     public void actionPerformed (ActionEvent e)
     {
-      ListSelectionModel rowModel = table.getSelectionModel();
-      ListSelectionModel colModel = table.getColumnModel().getSelectionModel();
+      DefaultListSelectionModel rowModel = (DefaultListSelectionModel) table.getSelectionModel();
+      DefaultListSelectionModel colModel = (DefaultListSelectionModel) table.getColumnModel().getSelectionModel();
 
       int rowLead = rowModel.getLeadSelectionIndex();
       int rowMax = table.getModel().getRowCount() - 1;
@@ -446,74 +447,75 @@
       int colLead = colModel.getLeadSelectionIndex();
       int colMax = table.getModel().getColumnCount() - 1;
       
-      if (e.getActionCommand().equals("selectPreviousRowExtendSelection"))
+      String command = e.getActionCommand();
+      
+      if (command.equals("selectPreviousRowExtendSelection"))
         {
           rowModel.setLeadSelectionIndex(Math.max(rowLead - 1, 0));
           colModel.setLeadSelectionIndex(colLead);
         }
-      else if (e.getActionCommand().equals("selectLastColumn"))
+      else if (command.equals("selectLastColumn"))
         {
-          table.clearSelection();
           rowModel.setSelectionInterval(rowLead, rowLead);
           colModel.setSelectionInterval(colMax, colMax);
         }
-      else if (e.getActionCommand().equals("startEditing"))
+      else if (command.equals("startEditing"))
         {
           if (table.isCellEditable(rowLead, colLead))
             table.editCellAt(rowLead,colLead);
         }
-      else if (e.getActionCommand().equals("selectFirstRowExtendSelection"))
+      else if (command.equals("selectFirstRowExtendSelection"))
         {              
           rowModel.setLeadSelectionIndex(0);
           colModel.setLeadSelectionIndex(colLead);
         }
-      else if (e.getActionCommand().equals("selectFirstColumn"))
+      else if (command.equals("selectFirstColumn"))
         {
           rowModel.setSelectionInterval(rowLead, rowLead);
           colModel.setSelectionInterval(0, 0);
         }
-      else if (e.getActionCommand().equals("selectFirstColumnExtendSelection"))
+      else if (command.equals("selectFirstColumnExtendSelection"))
         {
           colModel.setLeadSelectionIndex(0);
           rowModel.setLeadSelectionIndex(rowLead);
-        }
-      else if (e.getActionCommand().equals("selectLastRow"))
+        }      
+      else if (command.equals("selectLastRow"))
         {
           rowModel.setSelectionInterval(rowMax,rowMax);
           colModel.setSelectionInterval(colLead, colLead);
         }
-      else if (e.getActionCommand().equals("selectNextRowExtendSelection"))
+      else if (command.equals("selectNextRowExtendSelection"))
         {
           rowModel.setLeadSelectionIndex(Math.min(rowLead + 1, rowMax));
           colModel.setLeadSelectionIndex(colLead);
         }
-      else if (e.getActionCommand().equals("selectFirstRow"))
+      else if (command.equals("selectFirstRow"))
         {
           rowModel.setSelectionInterval(0,0);
           colModel.setSelectionInterval(colLead, colLead);
         }
-      else if (e.getActionCommand().equals("selectNextColumnExtendSelection"))
+      else if (command.equals("selectNextColumnExtendSelection"))
         {
           colModel.setLeadSelectionIndex(Math.min(colLead + 1, colMax));
           rowModel.setLeadSelectionIndex(rowLead);
         }
-      else if (e.getActionCommand().equals("selectLastColumnExtendSelection"))
+      else if (command.equals("selectLastColumnExtendSelection"))
         {
           colModel.setLeadSelectionIndex(colMax);
           rowModel.setLeadSelectionIndex(rowLead);
         }
-      else if (e.getActionCommand().equals("selectPreviousColumnExtendSelection"))
+      else if (command.equals("selectPreviousColumnExtendSelection"))
         {
           colModel.setLeadSelectionIndex(Math.max(colLead - 1, 0));
           rowModel.setLeadSelectionIndex(rowLead);
         }
-      else if (e.getActionCommand().equals("selectNextRow"))
+      else if (command.equals("selectNextRow"))
         {
           rowModel.setSelectionInterval(Math.min(rowLead + 1, rowMax),
                                         Math.min(rowLead + 1, rowMax));
           colModel.setSelectionInterval(colLead,colLead);
         }
-      else if (e.getActionCommand().equals("scrollUpExtendSelection"))
+      else if (command.equals("scrollUpExtendSelection"))
         {
           int target;
           if (rowLead == getFirstVisibleRowIndex())
@@ -526,13 +528,13 @@
           rowModel.setLeadSelectionIndex(target);
           colModel.setLeadSelectionIndex(colLead);
         }
-      else if (e.getActionCommand().equals("selectPreviousRow"))
+      else if (command.equals("selectPreviousRow"))
         {
           rowModel.setSelectionInterval(Math.max(rowLead - 1, 0),
                                         Math.max(rowLead - 1, 0));
           colModel.setSelectionInterval(colLead,colLead);
         }
-      else if (e.getActionCommand().equals("scrollRightChangeSelection"))
+      else if (command.equals("scrollRightChangeSelection"))
         {
           int target;
           if (colLead == getLastVisibleColumnIndex())
@@ -545,13 +547,13 @@
           colModel.setSelectionInterval(target, target);
           rowModel.setSelectionInterval(rowLead, rowLead);
         }
-      else if (e.getActionCommand().equals("selectPreviousColumn"))
+      else if (command.equals("selectPreviousColumn"))
         {
           rowModel.setSelectionInterval(rowLead,rowLead);
           colModel.setSelectionInterval(Math.max(colLead - 1, 0),
                                         Math.max(colLead - 1, 0));
         }
-      else if (e.getActionCommand().equals("scrollLeftChangeSelection"))
+      else if (command.equals("scrollLeftChangeSelection"))
         {
           int target;
           if (colLead == getFirstVisibleColumnIndex())
@@ -564,11 +566,11 @@
           colModel.setSelectionInterval(target, target);
           rowModel.setSelectionInterval(rowLead, rowLead);
         }
-      else if (e.getActionCommand().equals("clearSelection"))
+      else if (command.equals("clearSelection"))
         {
           table.clearSelection();
         }
-      else if (e.getActionCommand().equals("cancel"))
+      else if (command.equals("cancel"))
         {
           // FIXME: implement other parts of "cancel" like undo-ing last
           // selection.  Right now it just calls editingCancelled if
@@ -576,10 +578,10 @@
           if (table.isEditing())
             table.editingCanceled(new ChangeEvent("cancel"));
         }
-      else if (e.getActionCommand().equals("selectNextRowCell")
-               || e.getActionCommand().equals("selectPreviousRowCell")
-               || e.getActionCommand().equals("selectNextColumnCell")
-               || e.getActionCommand().equals("selectPreviousColumnCell"))
+      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 && 
@@ -615,13 +617,13 @@
           // when you get to the edges of the table.
           if (!multColsSelected && !multRowsSelected)
             {
-              if (e.getActionCommand().indexOf("Column") != -1) 
+              if (command.indexOf("Column") != -1) 
                 advanceSingleSelection(colModel, colMax, rowModel, rowMax, 
-                                       (e.getActionCommand().equals
+                                       (command.equals
                                         ("selectPreviousColumnCell")));
               else
                 advanceSingleSelection(rowModel, rowMax, colModel, colMax, 
-                                       (e.getActionCommand().equals 
+                                       (command.equals 
                                         ("selectPreviousRowCell")));
               return;
             }
@@ -642,25 +644,25 @@
           
           // If there are multiple rows and columns selected, select the next
           // cell and wrap at the edges of the selection.  
-          if (e.getActionCommand().indexOf("Column") != -1) 
+          if (command.indexOf("Column") != -1) 
             advanceMultipleSelection(colModel, colMinSelected, colMaxSelected, 
                                      rowModel, rowMinSelected, rowMaxSelected, 
-                                     (e.getActionCommand().equals
+                                     (command.equals
                                       ("selectPreviousColumnCell")), true);
           
           else
             advanceMultipleSelection(rowModel, rowMinSelected, rowMaxSelected, 
                                      colModel, colMinSelected, colMaxSelected, 
-                                     (e.getActionCommand().equals 
+                                     (command.equals 
                                       ("selectPreviousRowCell")), false);
         }
-      else if (e.getActionCommand().equals("selectNextColumn"))
+      else if (command.equals("selectNextColumn"))
         {
           rowModel.setSelectionInterval(rowLead,rowLead);
           colModel.setSelectionInterval(Math.min(colLead + 1, colMax),
                                         Math.min(colLead + 1, colMax));
         }
-      else if (e.getActionCommand().equals("scrollLeftExtendSelection"))
+      else if (command.equals("scrollLeftExtendSelection"))
         {
           int target;
           if (colLead == getFirstVisibleColumnIndex())
@@ -673,7 +675,7 @@
           colModel.setLeadSelectionIndex(target);
           rowModel.setLeadSelectionIndex(rowLead);
         }
-      else if (e.getActionCommand().equals("scrollDownChangeSelection"))
+      else if (command.equals("scrollDownChangeSelection"))
         {
           int target;
           if (rowLead == getLastVisibleRowIndex())
@@ -686,7 +688,7 @@
           rowModel.setSelectionInterval(target, target);
           colModel.setSelectionInterval(colLead, colLead);
         }
-      else if (e.getActionCommand().equals("scrollRightExtendSelection"))
+      else if (command.equals("scrollRightExtendSelection"))
         {
           int target;
           if (colLead == getLastVisibleColumnIndex())
@@ -699,16 +701,16 @@
           colModel.setLeadSelectionIndex(target);
           rowModel.setLeadSelectionIndex(rowLead);
         }
-      else if (e.getActionCommand().equals("selectAll"))
+      else if (command.equals("selectAll"))
         {
           table.selectAll();
         }
-      else if (e.getActionCommand().equals("selectLastRowExtendSelection"))
+      else if (command.equals("selectLastRowExtendSelection"))
         {
           rowModel.setLeadSelectionIndex(rowMax);
           colModel.setLeadSelectionIndex(colLead);
         }
-      else if (e.getActionCommand().equals("scrollDownExtendSelection"))
+      else if (command.equals("scrollDownExtendSelection"))
         {
           int target;
           if (rowLead == getLastVisibleRowIndex())
@@ -720,8 +722,8 @@
           
           rowModel.setLeadSelectionIndex(target);
           colModel.setLeadSelectionIndex(colLead);
-        }
-      else if (e.getActionCommand().equals("scrollUpChangeSelection"))
+        }      
+      else if (command.equals("scrollUpChangeSelection"))
         {
           int target;
           if (rowLead == getFirstVisibleRowIndex())
@@ -734,22 +736,119 @@
           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 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());
         }
 
-      if (table.isEditing() && e.getActionCommand() != "startEditing")
-        table.editingCanceled(new ChangeEvent("update"));
-      table.repaint();
-      
+      // 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));
+      table.repaint();
     }
     
+    /**
+     * Returns the column index of the first visible column.
+     * @return the column index of the first visible column.
+     */
     int getFirstVisibleColumnIndex()
     {
       ComponentOrientation or = table.getComponentOrientation();
_______________________________________________
Classpath-patches mailing list
Classpath-patches@gnu.org
http://lists.gnu.org/mailman/listinfo/classpath-patches

Reply via email to