39 |
package javax.swing.text; |
package javax.swing.text; |
40 |
|
|
41 |
import java.io.Serializable; |
import java.io.Serializable; |
42 |
|
import java.util.Collections; |
43 |
|
import java.util.LinkedList; |
44 |
|
import java.util.ListIterator; |
45 |
|
|
46 |
import javax.swing.undo.UndoableEdit; |
import javax.swing.undo.UndoableEdit; |
47 |
|
|
60 |
public class GapContent |
public class GapContent |
61 |
implements AbstractDocument.Content, Serializable |
implements AbstractDocument.Content, Serializable |
62 |
{ |
{ |
63 |
|
|
64 |
|
/** |
65 |
|
* A {@link Position} implementation for <code>GapContent</code>. |
66 |
|
*/ |
67 |
|
class GapContentPosition implements Position, Comparable |
68 |
|
{ |
69 |
|
|
70 |
|
/** The index within the buffer array. */ |
71 |
|
int mark; |
72 |
|
|
73 |
|
/** |
74 |
|
* Creates a new GapContentPosition object. |
75 |
|
* |
76 |
|
* @param mark the mark of this Position |
77 |
|
*/ |
78 |
|
GapContentPosition(int mark) |
79 |
|
{ |
80 |
|
this.mark = mark; |
81 |
|
} |
82 |
|
|
83 |
|
/** |
84 |
|
* Comparable interface implementation. This is used to store all |
85 |
|
* positions in an ordered fashion. |
86 |
|
* |
87 |
|
* @param o the object to be compared to this |
88 |
|
* |
89 |
|
* @return a negative integer if this is less than <code>o</code>, zero |
90 |
|
* if both are equal or a positive integer if this is greater |
91 |
|
* than <code>o</code> |
92 |
|
* |
93 |
|
* @throws ClassCastException if <code>o</code> is not a GapContentPosition |
94 |
|
* or Integer object |
95 |
|
*/ |
96 |
|
public int compareTo(Object o) |
97 |
|
{ |
98 |
|
if (o instanceof Integer) |
99 |
|
{ |
100 |
|
int otherMark = ((Integer) o).intValue(); |
101 |
|
return mark - otherMark; |
102 |
|
} |
103 |
|
else |
104 |
|
{ |
105 |
|
GapContentPosition other = (GapContentPosition) o; |
106 |
|
return mark - other.mark; |
107 |
|
} |
108 |
|
} |
109 |
|
|
110 |
|
/** |
111 |
|
* Returns the current offset of this Position within the content. |
112 |
|
* |
113 |
|
* @return the current offset of this Position within the content. |
114 |
|
*/ |
115 |
|
public int getOffset() |
116 |
|
{ |
117 |
|
if (mark < gapStart) |
118 |
|
return mark; |
119 |
|
else |
120 |
|
return mark - (gapEnd - gapStart); |
121 |
|
} |
122 |
|
} |
123 |
|
|
124 |
private static final long serialVersionUID = 8374645204155842629L; |
private static final long serialVersionUID = 8374645204155842629L; |
125 |
|
|
126 |
/** |
/** |
145 |
int gapEnd; |
int gapEnd; |
146 |
|
|
147 |
/** |
/** |
148 |
|
* The positions generated by this GapContent. They are kept in an |
149 |
|
* ordered fashion, so they can be looked up easily. |
150 |
|
*/ |
151 |
|
LinkedList positions; |
152 |
|
|
153 |
|
/** |
154 |
* Creates a new GapContent object. |
* Creates a new GapContent object. |
155 |
*/ |
*/ |
156 |
public GapContent() |
public GapContent() |
169 |
gapStart = 0; |
gapStart = 0; |
170 |
gapEnd = size - 1; |
gapEnd = size - 1; |
171 |
buffer[size - 1] = '\n'; |
buffer[size - 1] = '\n'; |
172 |
|
positions = new LinkedList(); |
173 |
} |
} |
174 |
|
|
175 |
/** |
/** |
359 |
*/ |
*/ |
360 |
public Position createPosition(final int offset) throws BadLocationException |
public Position createPosition(final int offset) throws BadLocationException |
361 |
{ |
{ |
362 |
return new Position() |
if (offset < 0 || offset > length()) |
363 |
{ |
throw new BadLocationException("The offset was out of the bounds of this" |
364 |
int off = offset; |
+ " buffer", offset); |
365 |
|
|
366 |
public int getOffset() |
// We store the actual array index in the GapContentPosition. The real |
367 |
{ |
// offset is then calculated in the GapContentPosition. |
368 |
return off; |
int mark = offset; |
369 |
} |
if (offset > gapStart) |
370 |
}; |
mark += gapEnd - gapStart; |
371 |
|
GapContentPosition pos = new GapContentPosition(mark); |
372 |
|
|
373 |
|
// Add this into our list in a sorted fashion. |
374 |
|
int index = Collections.binarySearch(positions, pos); |
375 |
|
if (index < 0) |
376 |
|
index = -(index + 1); |
377 |
|
positions.add(index, pos); |
378 |
|
|
379 |
|
return pos; |
380 |
} |
} |
381 |
|
|
382 |
/** |
/** |
389 |
*/ |
*/ |
390 |
protected void shiftEnd(int newSize) |
protected void shiftEnd(int newSize) |
391 |
{ |
{ |
392 |
|
int delta = (gapEnd - gapStart) - newSize; |
393 |
char[] newBuf = (char[]) allocateArray(length() + newSize); |
char[] newBuf = (char[]) allocateArray(length() + newSize); |
394 |
System.arraycopy(buffer, 0, newBuf, 0, gapStart); |
System.arraycopy(buffer, 0, newBuf, 0, gapStart); |
395 |
System.arraycopy(buffer, gapEnd, newBuf, gapStart + newSize, |
System.arraycopy(buffer, gapEnd, newBuf, gapStart + newSize, |
396 |
buffer.length - gapEnd); |
buffer.length - gapEnd); |
397 |
gapEnd = gapStart + newSize; |
gapEnd = gapStart + newSize; |
398 |
buffer = newBuf; |
buffer = newBuf; |
399 |
|
|
400 |
|
// Update the marks after the gapEnd. |
401 |
|
int index = Collections.binarySearch(positions, new Integer(gapEnd)); |
402 |
|
if (index < 0) |
403 |
|
{ |
404 |
|
index = -(index + 1); |
405 |
|
} |
406 |
|
for (ListIterator i = positions.listIterator(index); i.hasNext();) |
407 |
|
{ |
408 |
|
GapContentPosition p = (GapContentPosition) i.next(); |
409 |
|
p.mark += delta; |
410 |
|
} |
411 |
} |
} |
412 |
|
|
413 |
/** |
/** |
419 |
{ |
{ |
420 |
int newGapEnd = newGapStart + (gapEnd - gapStart); |
int newGapEnd = newGapStart + (gapEnd - gapStart); |
421 |
|
|
422 |
|
|
423 |
|
// Update the positions between newGapEnd and (old) gapEnd. The marks |
424 |
|
// must be shifted by (gapEnd - newGapEnd). |
425 |
|
int index1 = Collections.binarySearch(positions, new Integer(gapEnd)); |
426 |
|
int index2 = Collections.binarySearch(positions, new Integer(newGapEnd)); |
427 |
|
int i1 = Math.min(index1, index2); |
428 |
|
int i2 = Math.max(index1, index2); |
429 |
|
for (ListIterator i = positions.listIterator(i1); i.hasNext();) |
430 |
|
{ |
431 |
|
if (i.nextIndex() > i2) |
432 |
|
break; |
433 |
|
|
434 |
|
GapContentPosition p = (GapContentPosition) i.next(); |
435 |
|
p.mark += gapEnd - newGapEnd; |
436 |
|
} |
437 |
|
|
438 |
if (newGapStart == gapStart) |
if (newGapStart == gapStart) |
439 |
return; |
return; |
440 |
else if (newGapStart < gapStart) |
else if (newGapStart < gapStart) |