summaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/swing/text/GapContent.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/text/GapContent.java')
-rw-r--r--libjava/classpath/javax/swing/text/GapContent.java167
1 files changed, 136 insertions, 31 deletions
diff --git a/libjava/classpath/javax/swing/text/GapContent.java b/libjava/classpath/javax/swing/text/GapContent.java
index 80dcfa56e06..28d1d6ee01f 100644
--- a/libjava/classpath/javax/swing/text/GapContent.java
+++ b/libjava/classpath/javax/swing/text/GapContent.java
@@ -1,5 +1,5 @@
/* GapContent.java --
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,8 +39,10 @@ exception statement from your version. */
package javax.swing.text;
import java.io.Serializable;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Comparator;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Vector;
@@ -68,8 +70,8 @@ public class GapContent
/**
* A {@link Position} implementation for <code>GapContent</code>.
*/
- class GapContentPosition
- implements Position, Comparable
+ private class GapContentPosition
+ implements Position, Comparable
{
/** The index within the buffer array. */
@@ -130,7 +132,7 @@ public class GapContent
}
}
- class InsertUndo extends AbstractUndoableEdit
+ private class InsertUndo extends AbstractUndoableEdit
{
public int where, length;
String text;
@@ -169,7 +171,7 @@ public class GapContent
}
- class UndoRemove extends AbstractUndoableEdit
+ private class UndoRemove extends AbstractUndoableEdit
{
public int where;
String text;
@@ -206,7 +208,41 @@ public class GapContent
}
}
-
+
+ /**
+ * Compares WeakReference objects in a List by comparing the referenced
+ * objects instead.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+ private class WeakPositionComparator
+ implements Comparator
+ {
+
+ /**
+ * Compares two objects of type WeakReference. The objects are compared
+ * using the referenced objects compareTo() method.
+ */
+ public int compare(Object o1, Object o2)
+ {
+ // Unwrap references.
+ if (o1 instanceof WeakReference)
+ o1 = ((WeakReference) o1).get();
+ if (o2 instanceof WeakReference)
+ o2 = ((WeakReference) o2).get();
+
+ GapContentPosition p1 = (GapContentPosition) o1;
+ GapContentPosition p2 = (GapContentPosition) o2;
+
+ int retVal;
+ if (p1 == null || p2 == null)
+ retVal = -1;
+ else
+ retVal = p1.compareTo(p2);
+ return retVal;
+ }
+ }
+
/** The serialization UID (compatible with JDK1.5). */
private static final long serialVersionUID = -6226052713477823730L;
@@ -233,9 +269,10 @@ public class GapContent
/**
* The positions generated by this GapContent. They are kept in an ordered
- * fashion, so they can be looked up easily.
+ * fashion, so they can be looked up easily. The value objects will be
+ * WeakReference objects that in turn hold GapContentPosition objects.
*/
- ArrayList positions;
+ private ArrayList positions;
/**
* Creates a new GapContent object.
@@ -310,8 +347,12 @@ public class GapContent
int length = length();
int strLen = str.length();
+ if (where < 0)
+ throw new BadLocationException("The where argument cannot be smaller"
+ + " than the zero", where);
+
if (where >= length)
- throw new BadLocationException("the where argument cannot be greater"
+ throw new BadLocationException("The where argument cannot be greater"
+ " than the content length", where);
replace(where, 0, str.toCharArray(), strLen);
@@ -446,18 +487,22 @@ public class GapContent
throw new BadLocationException("The offset was out of the bounds of this"
+ " buffer", offset);
+ clearPositionReferences();
+
// We store the actual array index in the GapContentPosition. The real
// offset is then calculated in the GapContentPosition.
int mark = offset;
if (offset >= gapStart)
mark += gapEnd - gapStart;
GapContentPosition pos = new GapContentPosition(mark);
+ WeakReference r = new WeakReference(pos);
// Add this into our list in a sorted fashion.
- int index = Collections.binarySearch(positions, pos);
+ int index = Collections.binarySearch(positions, r,
+ new WeakPositionComparator());
if (index < 0)
index = -(index + 1);
- positions.add(index, pos);
+ positions.add(index, r);
return pos;
}
@@ -557,7 +602,7 @@ public class GapContent
assert newGapEnd > gapEnd : "The new gap end must be greater than the "
+ "old gap end.";
- setPositionsInRange(gapEnd, newGapEnd - gapEnd, newGapEnd + 1);
+ setPositionsInRange(gapEnd, newGapEnd - gapEnd, newGapEnd);
gapEnd = newGapEnd;
}
@@ -566,7 +611,7 @@ public class GapContent
*
* @return the allocated buffer array
*/
- protected Object getArray()
+ protected final Object getArray()
{
return buffer;
}
@@ -642,19 +687,30 @@ public class GapContent
int endOffset = offset + length;
int index1 = Collections.binarySearch(positions,
- new GapContentPosition(offset));
+ new GapContentPosition(offset),
+ new WeakPositionComparator());
if (index1 < 0)
index1 = -(index1 + 1);
// Search the first index with the specified offset. The binarySearch does
// not necessarily find the first one.
- while (index1 > 0
- && ((GapContentPosition) positions.get(index1 - 1)).mark == offset)
- index1--;
+ while (index1 > 0)
+ {
+ WeakReference r = (WeakReference) positions.get(index1 - 1);
+ GapContentPosition p = (GapContentPosition) r.get();
+ if (p != null && p.mark == offset || p == null)
+ index1--;
+ else
+ break;
+ }
for (ListIterator i = positions.listIterator(index1); i.hasNext();)
{
- GapContentPosition p = (GapContentPosition) i.next();
+ WeakReference r = (WeakReference) i.next();
+ GapContentPosition p = (GapContentPosition) r.get();
+ if (p == null)
+ continue;
+
if (p.mark > endOffset)
break;
if (p.mark >= offset && p.mark <= endOffset)
@@ -672,24 +728,35 @@ public class GapContent
* @param length the length of the range to search
* @param value the new value for each mark
*/
- void setPositionsInRange(int offset, int length, int value)
+ private void setPositionsInRange(int offset, int length, int value)
{
int endOffset = offset + length;
int index1 = Collections.binarySearch(positions,
- new GapContentPosition(offset));
+ new GapContentPosition(offset),
+ new WeakPositionComparator());
if (index1 < 0)
index1 = -(index1 + 1);
// Search the first index with the specified offset. The binarySearch does
// not necessarily find the first one.
- while (index1 > 0
- && ((GapContentPosition) positions.get(index1 - 1)).mark == offset)
- index1--;
+ while (index1 > 0)
+ {
+ WeakReference r = (WeakReference) positions.get(index1 - 1);
+ GapContentPosition p = (GapContentPosition) r.get();
+ if (p != null && p.mark == offset || p == null)
+ index1--;
+ else
+ break;
+ }
for (ListIterator i = positions.listIterator(index1); i.hasNext();)
{
- GapContentPosition p = (GapContentPosition) i.next();
+ WeakReference r = (WeakReference) i.next();
+ GapContentPosition p = (GapContentPosition) r.get();
+ if (p == null)
+ continue;
+
if (p.mark > endOffset)
break;
@@ -707,23 +774,35 @@ public class GapContent
* @param length the length of the range to search
* @param incr the increment
*/
- void adjustPositionsInRange(int offset, int length, int incr)
+ private void adjustPositionsInRange(int offset, int length, int incr)
{
int endOffset = offset + length;
int index1 = Collections.binarySearch(positions,
- new GapContentPosition(offset));
+ new GapContentPosition(offset),
+ new WeakPositionComparator());
if (index1 < 0)
index1 = -(index1 + 1);
// Search the first index with the specified offset. The binarySearch does
// not necessarily find the first one.
- while (index1 > 0
- && ((GapContentPosition) positions.get(index1 - 1)).mark == offset)
- index1--;
+ while (index1 > 0)
+ {
+ WeakReference r = (WeakReference) positions.get(index1 - 1);
+ GapContentPosition p = (GapContentPosition) r.get();
+ if (p != null && p.mark == offset || p == null)
+ index1--;
+ else
+ break;
+ }
+
for (ListIterator i = positions.listIterator(index1); i.hasNext();)
{
- GapContentPosition p = (GapContentPosition) i.next();
+ WeakReference r = (WeakReference) i.next();
+ GapContentPosition p = (GapContentPosition) r.get();
+ if (p == null)
+ continue;
+
if (p.mark > endOffset)
break;
@@ -747,6 +826,17 @@ public class GapContent
}
/**
+ * @specnote This method is not very well specified and the positions vector
+ * is implementation specific. The undo positions are managed
+ * differently in this implementation, this method is only here
+ * for binary compatibility.
+ */
+ protected void updateUndoPositions(Vector positions, int offset, int length)
+ {
+ // We do nothing here.
+ }
+
+ /**
* Outputs debugging info to System.err. It prints out the buffer array,
* the gapStart is marked by a &lt; sign, the gapEnd is marked by a &gt;
* sign and each position is marked by a # sign.
@@ -776,8 +866,23 @@ public class GapContent
{
for (Iterator i = positions.iterator(); i.hasNext();)
{
- GapContentPosition pos = (GapContentPosition) i.next();
+ WeakReference r = (WeakReference) i.next();
+ GapContentPosition pos = (GapContentPosition) r.get();
System.err.println("position at: " + pos.mark);
}
}
+
+ /**
+ * Clears all GC'ed references in the positions array.
+ */
+ private void clearPositionReferences()
+ {
+ Iterator i = positions.iterator();
+ while (i.hasNext())
+ {
+ WeakReference r = (WeakReference) i.next();
+ if (r.get() == null)
+ i.remove();
+ }
+ }
}