Methods Summary |
---|
protected java.lang.Object | allocateArray(int len)Allocate an array to store items of the type
appropriate (which is determined by the subclass).
return new char[len];
|
final int | compare(javax.swing.text.GapContent$MarkData o1, javax.swing.text.GapContent$MarkData o2)Compares two marks.
if (o1.index < o2.index) {
return -1;
} else if (o1.index > o2.index) {
return 1;
} else {
return 0;
}
|
public javax.swing.text.Position | createPosition(int offset)Creates a position within the content that will
track change as the content is mutated.
while ( queue.poll() != null ) {
unusedMarks++;
}
if (unusedMarks > Math.max(5, (marks.size() / 10))) {
removeUnusedMarks();
}
int g0 = getGapStart();
int g1 = getGapEnd();
int index = (offset < g0) ? offset : offset + (g1 - g0);
search.index = index;
int sortIndex = findSortIndex(search);
MarkData m;
StickyPosition position;
if (sortIndex < marks.size()
&& (m = marks.elementAt(sortIndex)).index == index
&& (position = m.getPosition()) != null) {
//position references the correct StickyPostition
} else {
position = new StickyPosition();
m = new MarkData(index,position,queue);
position.setMark(m);
marks.insertElementAt(m, sortIndex);
}
return position;
|
final int | findMarkAdjustIndex(int searchIndex)Finds the index to start mark adjustments given
some search index.
search.index = Math.max(searchIndex, 1);
int index = findSortIndex(search);
// return the first in the series
// (ie. there may be duplicates).
for (int i = index - 1; i >= 0; i--) {
MarkData d = marks.elementAt(i);
if (d.index != search.index) {
break;
}
index -= 1;
}
return index;
|
final int | findSortIndex(javax.swing.text.GapContent$MarkData o)Finds the index of where to insert a new mark.
int lower = 0;
int upper = marks.size() - 1;
int mid = 0;
if (upper == -1) {
return 0;
}
int cmp = 0;
MarkData last = marks.elementAt(upper);
cmp = compare(o, last);
if (cmp > 0)
return upper + 1;
while (lower <= upper) {
mid = lower + ((upper - lower) / 2);
MarkData entry = marks.elementAt(mid);
cmp = compare(o, entry);
if (cmp == 0) {
// found a match
return mid;
} else if (cmp < 0) {
upper = mid - 1;
} else {
lower = mid + 1;
}
}
// didn't find it, but we indicate the index of where it would belong.
return (cmp < 0) ? mid : mid + 1;
|
protected int | getArrayLength()Get the length of the allocated array.
char[] carray = (char[]) getArray();
return carray.length;
|
public void | getChars(int where, int len, javax.swing.text.Segment chars)Retrieves a portion of the content. If the desired content spans
the gap, we copy the content. If the desired content does not
span the gap, the actual store is returned to avoid the copy since
it is contiguous.
int end = where + len;
if (where < 0 || end < 0) {
throw new BadLocationException("Invalid location", -1);
}
if (end > length() || where > length()) {
throw new BadLocationException("Invalid location", length() + 1);
}
int g0 = getGapStart();
int g1 = getGapEnd();
char[] array = (char[]) getArray();
if ((where + len) <= g0) {
// below gap
chars.array = array;
chars.offset = where;
} else if (where >= g0) {
// above gap
chars.array = array;
chars.offset = g1 + where - g0;
} else {
// spans the gap
int before = g0 - where;
if (chars.isPartialReturn()) {
// partial return allowed, return amount before the gap
chars.array = array;
chars.offset = where;
chars.count = before;
return;
}
// partial return not allowed, must copy
chars.array = new char[len];
chars.offset = 0;
System.arraycopy(array, where, chars.array, 0, before);
System.arraycopy(array, g1, chars.array, before, len - before);
}
chars.count = len;
|
int | getNewArraySize(int reqSize)Overridden to make growth policy less agressive for large
text amount.
if (reqSize < GROWTH_SIZE) {
return super.getNewArraySize(reqSize);
} else {
return reqSize + GROWTH_SIZE;
}
|
protected java.util.Vector | getPositionsInRange(java.util.Vector v, int offset, int length)Returns a Vector containing instances of UndoPosRef for the
Positions in the range
offset to offset + length .
If v is not null the matching Positions are placed in
there. The vector with the resulting Positions are returned.
int endOffset = offset + length;
int startIndex;
int endIndex;
int g0 = getGapStart();
int g1 = getGapEnd();
// Find the index of the marks.
if (offset < g0) {
if (offset == 0) {
// findMarkAdjustIndex start at 1!
startIndex = 0;
}
else {
startIndex = findMarkAdjustIndex(offset);
}
if (endOffset >= g0) {
endIndex = findMarkAdjustIndex(endOffset + (g1 - g0) + 1);
}
else {
endIndex = findMarkAdjustIndex(endOffset + 1);
}
}
else {
startIndex = findMarkAdjustIndex(offset + (g1 - g0));
endIndex = findMarkAdjustIndex(endOffset + (g1 - g0) + 1);
}
Vector placeIn = (v == null) ? new Vector(Math.max(1, endIndex -
startIndex)) : v;
for (int counter = startIndex; counter < endIndex; counter++) {
placeIn.addElement(new UndoPosRef(marks.elementAt(counter)));
}
return placeIn;
|
public java.lang.String | getString(int where, int len)Retrieves a portion of the content.
Segment s = new Segment();
getChars(where, len, s);
return new String(s.array, s.offset, s.count);
|
public javax.swing.undo.UndoableEdit | insertString(int where, java.lang.String str)Inserts a string into the content.
if (where > length() || where < 0) {
throw new BadLocationException("Invalid insert", length());
}
char[] chars = str.toCharArray();
replace(where, 0, chars, chars.length);
return new InsertUndo(where, str.length());
|
public int | length()Returns the length of the content.
int len = getArrayLength() - (getGapEnd() - getGapStart());
return len;
|
private void | readObject(java.io.ObjectInputStream s)
// --- serialization -------------------------------------
s.defaultReadObject();
marks = new MarkVector();
search = new MarkData(0);
queue = new ReferenceQueue();
|
public javax.swing.undo.UndoableEdit | remove(int where, int nitems)Removes part of the content.
if (where + nitems >= length()) {
throw new BadLocationException("Invalid remove", length() + 1);
}
String removedString = getString(where, nitems);
UndoableEdit edit = new RemoveUndo(where, removedString);
replace(where, nitems, empty, 0);
return edit;
|
final void | removeUnusedMarks()Remove all unused marks out of the sorted collection
of marks.
int n = marks.size();
MarkVector cleaned = new MarkVector(n);
for (int i = 0; i < n; i++) {
MarkData mark = marks.elementAt(i);
if (mark.get() != null) {
cleaned.addElement(mark);
}
}
marks = cleaned;
unusedMarks = 0;
|
protected void | resetMarksAtZero()Resets all the marks that have an offset of 0 to have an index of
zero as well.
if (marks != null && getGapStart() == 0) {
int g1 = getGapEnd();
for (int counter = 0, maxCounter = marks.size();
counter < maxCounter; counter++) {
MarkData mark = marks.elementAt(counter);
if (mark.index <= g1) {
mark.index = 0;
}
else {
break;
}
}
}
|
protected void | shiftEnd(int newSize)Make the gap bigger, moving any necessary data and updating
the appropriate marks
// --- gap management -------------------------------
int oldGapEnd = getGapEnd();
super.shiftEnd(newSize);
// Adjust marks.
int dg = getGapEnd() - oldGapEnd;
int adjustIndex = findMarkAdjustIndex(oldGapEnd);
int n = marks.size();
for (int i = adjustIndex; i < n; i++) {
MarkData mark = marks.elementAt(i);
mark.index += dg;
}
|
protected void | shiftGap(int newGapStart)Move the start of the gap to a new location,
without changing the size of the gap. This
moves the data in the array and updates the
marks accordingly.
int oldGapStart = getGapStart();
int dg = newGapStart - oldGapStart;
int oldGapEnd = getGapEnd();
int newGapEnd = oldGapEnd + dg;
int gapSize = oldGapEnd - oldGapStart;
// shift gap in the character array
super.shiftGap(newGapStart);
// update the marks
if (dg > 0) {
// Move gap up, move data and marks down.
int adjustIndex = findMarkAdjustIndex(oldGapStart);
int n = marks.size();
for (int i = adjustIndex; i < n; i++) {
MarkData mark = marks.elementAt(i);
if (mark.index >= newGapEnd) {
break;
}
mark.index -= gapSize;
}
} else if (dg < 0) {
// Move gap down, move data and marks up.
int adjustIndex = findMarkAdjustIndex(newGapStart);
int n = marks.size();
for (int i = adjustIndex; i < n; i++) {
MarkData mark = marks.elementAt(i);
if (mark.index >= oldGapEnd) {
break;
}
mark.index += gapSize;
}
}
resetMarksAtZero();
|
protected void | shiftGapEndUp(int newGapEnd)Adjust the gap end upward. This doesn't move
any data, but it does update any marks affected
by the boundary change. All marks from the old
gap end up to the new gap end are squeezed
to the end of the gap (their location has been
removed).
int adjustIndex = findMarkAdjustIndex(getGapEnd());
int n = marks.size();
for (int i = adjustIndex; i < n; i++) {
MarkData mark = marks.elementAt(i);
if (mark.index >= newGapEnd) {
break;
}
mark.index = newGapEnd;
}
// shift the gap in the character array
super.shiftGapEndUp(newGapEnd);
resetMarksAtZero();
|
protected void | shiftGapStartDown(int newGapStart)Adjust the gap end downward. This doesn't move
any data, but it does update any marks affected
by the boundary change. All marks from the old
gap start down to the new gap start are squeezed
to the end of the gap (their location has been
removed).
// Push aside all marks from oldGapStart down to newGapStart.
int adjustIndex = findMarkAdjustIndex(newGapStart);
int n = marks.size();
int g0 = getGapStart();
int g1 = getGapEnd();
for (int i = adjustIndex; i < n; i++) {
MarkData mark = marks.elementAt(i);
if (mark.index > g0) {
// no more marks to adjust
break;
}
mark.index = g1;
}
// shift the gap in the character array
super.shiftGapStartDown(newGapStart);
resetMarksAtZero();
|
protected void | updateUndoPositions(java.util.Vector positions, int offset, int length)Resets the location for all the UndoPosRef instances
in positions .
This is meant for internal usage, and is generally not of interest
to subclasses.
// Find the indexs of the end points.
int endOffset = offset + length;
int g1 = getGapEnd();
int startIndex;
int endIndex = findMarkAdjustIndex(g1 + 1);
if (offset != 0) {
startIndex = findMarkAdjustIndex(g1);
}
else {
startIndex = 0;
}
// Reset the location of the refenences.
for(int counter = positions.size() - 1; counter >= 0; counter--) {
UndoPosRef ref = (UndoPosRef)positions.elementAt(counter);
ref.resetLocation(endOffset, g1);
}
// We have to resort the marks in the range startIndex to endIndex.
// We can take advantage of the fact that it will be in
// increasing order, accept there will be a bunch of MarkData's with
// the index g1 (or 0 if offset == 0) interspersed throughout.
if (startIndex < endIndex) {
Object[] sorted = new Object[endIndex - startIndex];
int addIndex = 0;
int counter;
if (offset == 0) {
// If the offset is 0, the positions won't have incremented,
// have to do the reverse thing.
// Find the elements in startIndex whose index is 0
for (counter = startIndex; counter < endIndex; counter++) {
MarkData mark = marks.elementAt(counter);
if (mark.index == 0) {
sorted[addIndex++] = mark;
}
}
for (counter = startIndex; counter < endIndex; counter++) {
MarkData mark = marks.elementAt(counter);
if (mark.index != 0) {
sorted[addIndex++] = mark;
}
}
}
else {
for (counter = startIndex; counter < endIndex; counter++) {
MarkData mark = marks.elementAt(counter);
if (mark.index != g1) {
sorted[addIndex++] = mark;
}
}
for (counter = startIndex; counter < endIndex; counter++) {
MarkData mark = marks.elementAt(counter);
if (mark.index == g1) {
sorted[addIndex++] = mark;
}
}
}
// And replace
marks.replaceRange(startIndex, endIndex, sorted);
}
|