I fixed the GapContent so that it really searches for the first
occurance of marks in the marks list. Collections.binarySearch doesn't
guarantee to find the first object.

2006-06-21  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/text/GapContent.java
        (GapContentPosition.GapContentPosition): Replace
        Collections.binarySearch with call to local search() to make
        sure we find the first object that equals the searched object.
        (setPositionsInRange): Likewise.
        (adjustPositionsInRange): Likewise.
        (search): New helper method.

/Roman

-- 
“Improvement makes straight roads, but the crooked roads, without
Improvement, are roads of Genius.” - William Blake
Index: javax/swing/text/GapContent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/GapContent.java,v
retrieving revision 1.51
diff -u -1 -0 -r1.51 GapContent.java
--- javax/swing/text/GapContent.java	20 Jun 2006 15:36:39 -0000	1.51
+++ javax/swing/text/GapContent.java	21 Jun 2006 09:15:40 -0000
@@ -38,20 +38,21 @@
 
 package javax.swing.text;
 
 import java.io.Serializable;
 import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 import java.util.Vector;
 import java.util.WeakHashMap;
 
 import javax.swing.undo.AbstractUndoableEdit;
 import javax.swing.undo.CannotRedoException;
 import javax.swing.undo.CannotUndoException;
 import javax.swing.undo.UndoableEdit;
 
 /**
@@ -87,21 +88,21 @@
      */
     GapContentPosition(int offset)
     {
       // Try to find the mark in the positionMarks array, and store the index
       // to it.
       synchronized (GapContent.this)
         {
           // Try to make space.
           garbageCollect();
           Mark m = new Mark(offset);
-          int i = Collections.binarySearch(marks, m);
+          int i = search(marks, m);
           if (i >= 0) // mark found
             {
               m = (Mark) marks.get(i);
             }
           else
             {
               i = -i - 1;
               marks.add(i, m);
             }
           m.refCount++;
@@ -758,25 +759,25 @@
    * @param toStart a boolean indicating if the positions should be crunched
    *        to the start (true) or to the end (false)
    */
   private void setPositionsInRange(int start, int end, boolean toStart)
   {
     synchronized (this)
       {
         // Find the start and end indices in the positionMarks array.
         Mark m = new Mark(0); // For comparison / search only.
         m.mark = start;
-        int startIndex = Collections.binarySearch(marks, m);
+        int startIndex = search(marks, m);
         if (startIndex < 0) // Translate to insertion index, if not found.
           startIndex = - startIndex - 1;
         m.mark = end;
-        int endIndex = Collections.binarySearch(marks, m);
+        int endIndex = search(marks, m);
         if (endIndex < 0) // Translate to insertion index - 1, if not found.
           endIndex = - endIndex - 2;
 
         // Actually adjust the marks.
         for (int i = startIndex; i <= endIndex; i++)
           ((Mark) marks.get(i)).mark = toStart ? start : end;
       }
 
   }
 
@@ -790,26 +791,26 @@
    * @param incr the increment
    */
   private void adjustPositionsInRange(int startOffs, int endOffs, int incr)
   {
     synchronized (this)
       {
         // Find the start and end indices in the positionMarks array.
         Mark m = new Mark(0); // For comparison / search only.
 
         m.mark = startOffs;
-        int startIndex = Collections.binarySearch(marks, m);
+        int startIndex = search(marks, m);
         if (startIndex < 0) // Translate to insertion index, if not found.
           startIndex = - startIndex - 1;
 
         m.mark = endOffs;
-        int endIndex = Collections.binarySearch(marks, m);
+        int endIndex = search(marks, m);
         if (endIndex < 0) // Translate to insertion index - 1, if not found.
           endIndex = - endIndex - 2;
         // Actually adjust the marks.
         for (int i = startIndex; i <= endIndex; i++) {
           ((Mark) marks.get(i)).mark += incr;
         }
       }
 
   }
 
@@ -897,11 +898,37 @@
             GapContentPosition pos = (GapContentPosition) ref.get();
             Mark m = pos.mark;
             m.refCount--;
             if (m.refCount == 0)
               marks.remove(m);
           }
         ref = queueOfDeath.poll();
       }
   }
 
+  /**
+   * Searches the first occurance of object <code>o</code> in list
+   * <code>l</code>. This performs a binary search by calling
+   * [EMAIL PROTECTED] Collections#binarySearch(List, Object)} and when an object has been
+   * found, it searches backwards to the first occurance of that object in the
+   * list. The meaning of the return value is the same as in
+   * <code>Collections.binarySearch()</code>.
+   *
+   * @param l the list to search through
+   * @param o the object to be searched
+   *
+   * @return the index of the first occurance of o in l, or -i + 1 if not found
+   */
+  private int search(List l, Object o)
+  {
+    int i = Collections.binarySearch(l, o);
+    while (i > 0)
+      {
+        Object o2 = l.get(i - 1);
+        if (o2.equals(o))
+          i--;
+        else
+          break;
+      }
+    return i;
+  }
 }

Attachment: signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil

Reply via email to