Index: javax/swing/text/JTextComponent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/JTextComponent.java,v
retrieving revision 1.24
diff -u -r1.24 JTextComponent.java
--- javax/swing/text/JTextComponent.java	16 Feb 2005 12:36:22 -0000	1.24
+++ javax/swing/text/JTextComponent.java	27 Feb 2005 19:39:04 -0000
@@ -1025,15 +1025,26 @@
   {
     try
       {
-	return doc.getText(getSelectionStart(), getSelectionEnd());
+        int a = getSelectionStart();
+        int b = getSelectionEnd();
+
+        // moveCaretPosition(int) can set selection start ahead the
+        // selection end.
+        if (a > b)
+          {
+            int t = a;
+            a = b;
+            b = t;
+          };
+
+        return doc.getText(a, b-a);
       }
     catch (BadLocationException e)
       {
-	// This should never happen.
-	return null;
+        // This should never happen.
+        return "";
       }
   }
-
   /**
    * Returns a string that specifies the name of the Look and Feel class
    * that renders this component.
@@ -1229,7 +1240,8 @@
 
   /**
    * Moves the caret to a given position. This selects the text between
-   * the old and the new position of the caret.
+   * the old and the new position of the caret. With this method, it is
+   * possible to set the selection start ahead the selection end.
    */
   public void moveCaretPosition(int position)
   {
@@ -1268,17 +1280,36 @@
    */
   public int getSelectionStart()
   {
-    return Math.min(caret.getDot(), caret.getMark());
+    return caret.getMark();
   }
 
   /**
-   * Selects the text from the given postion to the selection end position.
+   * Ensures that the given position is inside the document.
+   * @param position The position
+   * @return 0 if the position negative, doucument length if position is
+   * outside the document bounds, position otherwise.
+   */
+  private int ensureBounds(int position)
+  {
+    int l = getDocument().getLength();
+    if (position < 0)
+      return 0;
+    else if (position > l)
+      return l;
+    else
+      return position;
+  }
+
+  /**
+   * Selects the text from the given position till the current selection
+   * end position. If the position <code>start</code>is ahead the current
+   * selection end, the text is unselected.
    *
    * @param end the start positon of the selected text.
    */
   public void setSelectionStart(int start)
   {
-    select(start, getSelectionEnd());
+    setCaretPosition(ensureBounds(start));
   }
 
   /**
@@ -1288,37 +1319,41 @@
    */
   public int getSelectionEnd()
   {
-    return Math.max(caret.getDot(), caret.getMark());
+    return caret.getDot();
   }
 
   /**
    * Selects the text from the selection start postion to the given position.
+   * If the position is negative, the selection moves to the beginning of
+   * the document. If the position <code>end</code>is before the current
+   * selection start, the text is unselected. If you need to set the selection
+   * start ahead the selection end, use {@link #moveCaretPosition(int)}.
    *
    * @param end the end positon of the selected text.
    */
   public void setSelectionEnd(int end)
   {
-    select(getSelectionStart(), end);
+    int p = ensureBounds(end);
+    if (p>= getSelectionStart())
+      moveCaretPosition(p);
+    else
+      setCaretPosition(end);
   }
 
   /**
    * Selects a part of the content of the text component.
    *
+   * The negative position is assumed to indicated the beginning of
+   * the document. The position outside the document bounds
+   * is assumed to indicate the end of the document.
+   *
    * @param start the start position of the selected text
-   * @param ent the end position of the selected text
+   * @param end the end position of the selected text
    */
   public void select(int start, int end)
   {
-    int length = doc.getLength();
-    
-    start = Math.max(start, 0);
-    start = Math.min(start, length);
-
-    end = Math.max(end, 0);
-    end = Math.min(end, length);
-
-    setCaretPosition(start);
-    moveCaretPosition(end);
+    setCaretPosition(ensureBounds(start));
+    moveCaretPosition(ensureBounds(end));
   }
 
   /**
@@ -1329,6 +1364,10 @@
     select(0, doc.getLength());
   }
 
+  /**
+   * Replaces the current selection with the given string content.
+   * @param content the replacement for selection
+   */
   public synchronized void replaceSelection(String content)
   {
     int dot = caret.getDot();
@@ -1337,28 +1376,37 @@
     // If content is empty delete selection.
     if (content == null)
       {
-	caret.setDot(dot);
-	return;
+        caret.setDot(dot);
+        return;
       }
 
     try
       {
-	int start = getSelectionStart();
-	int end = getSelectionEnd();
-	
-	// Remove selected text.
-	if (dot != mark)
-	  doc.remove(start, end - start);
+        int start = getSelectionStart();
+        int end = getSelectionEnd();
+
+        // moveCaretPosition(int) can set selection start ahead the
+        // selection end.
+        if (start>end)
+          {
+            int t = start;
+            start = end;
+            end = t;
+          }
+
+        // Remove selected text.
+        if (dot != mark)
+          doc.remove(start, end - start);
 
-	// Insert new text.
-	doc.insertString(start, content, null);
+        // Insert new text.
+        doc.insertString(start, content, null);
 
-	// Set dot to new position.
-	setCaretPosition(start + content.length());
+        // Set dot to new position.
+        setCaretPosition(start + content.length());
       }
     catch (BadLocationException e)
       {
-	// This should never happen.
+        // This should never happen.        
       }
   }
 
