StringContent.java [plain text]
package javax.swing.text;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoableEdit;
public final class StringContent implements AbstractDocument.Content, Serializable
{
private char[] content;
private int count;
private Vector positions = new Vector();
private class InsertUndo extends AbstractUndoableEdit
{
private int start;
private int length;
private String redoContent;
public InsertUndo(int start, int length)
{
super();
this.start = start;
this.length = length;
}
public void undo()
{
super.undo();
try
{
StringContent.this.checkLocation(this.start, this.length);
this.redoContent = new String(StringContent.this.content, this.start, this.length);
StringContent.this.remove(this.start, this.length);
}
catch (BadLocationException b)
{
throw new CannotUndoException();
}
}
public void redo()
{
super.redo();
try
{
StringContent.this.insertString(this.start, this.redoContent);
}
catch (BadLocationException b)
{
throw new CannotRedoException();
}
}
}
private class RemoveUndo extends AbstractUndoableEdit
{
private int start;
private String undoString;
public RemoveUndo(int start, String str)
{
super();
this.start = start;
this.undoString = str;
}
public void undo()
{
super.undo();
try
{
StringContent.this.insertString(this.start, this.undoString);
}
catch (BadLocationException bad)
{
throw new CannotUndoException();
}
}
public void redo()
{
super.redo();
try
{
int end = this.undoString.length();
StringContent.this.remove(this.start, end);
}
catch (BadLocationException bad)
{
throw new CannotRedoException();
}
}
}
private class StickyPosition implements Position
{
private int offset = -1;
public StickyPosition(int offset)
{
this.offset = offset;
}
private void setOffset(int offset)
{
this.offset = this.offset >= 0 ? offset : -1;
}
public int getOffset()
{
return offset < 0 ? 0 : offset;
}
}
public StringContent()
{
this(1);
}
public StringContent(int initialLength)
{
super();
if (initialLength < 1)
initialLength = 1;
this.content = new char[initialLength];
this.content[0] = '\n';
this.count = 1;
}
protected Vector getPositionsInRange(Vector v,
int offset,
int length)
{
Vector refPos = new Vector();
Iterator iter = this.positions.iterator();
while(iter.hasNext())
{
Position p = (Position)iter.next();
if ((offset <= p.getOffset())
&& (p.getOffset() <= (offset + length)))
refPos.add(p);
}
return refPos;
}
public Position createPosition(int offset) throws BadLocationException
{
if (offset < this.count || offset > this.count)
checkLocation(offset, 0);
StickyPosition sp = new StickyPosition(offset);
this.positions.add(sp);
return sp;
}
public int length()
{
return this.count;
}
public UndoableEdit insertString(int where, String str)
throws BadLocationException
{
checkLocation(where, 0);
if (where == this.count)
throw new BadLocationException("Invalid location", 1);
if (str == null)
throw new NullPointerException();
char[] insert = str.toCharArray();
char[] temp = new char[this.content.length + insert.length];
this.count += insert.length;
if (where > 0)
System.arraycopy(this.content, 0, temp, 0, where);
System.arraycopy(insert, 0, temp, where, insert.length);
System.arraycopy(this.content, where, temp, (where + insert.length), (temp.length - where - insert.length));
if (this.content.length < temp.length)
this.content = new char[temp.length];
System.arraycopy(temp, 0, this.content, 0, temp.length);
Vector refPos = getPositionsInRange(this.positions, where, temp.length - where);
Iterator iter = refPos.iterator();
while (iter.hasNext())
{
StickyPosition p = (StickyPosition)iter.next();
p.setOffset(p.getOffset() + str.length());
}
InsertUndo iundo = new InsertUndo(where, insert.length);
return iundo;
}
public UndoableEdit remove(int where, int nitems) throws BadLocationException
{
checkLocation(where, nitems);
char[] temp = new char[(this.content.length - nitems)];
this.count = this.count - nitems;
RemoveUndo rundo = new RemoveUndo(where, new String(this.content, where, nitems));
System.arraycopy(this.content, 0, temp, 0, where);
System.arraycopy(this.content, where + nitems, temp, where, this.content.length - where - nitems);
this.content = new char[temp.length];
System.arraycopy(temp, 0, this.content, 0, this.content.length);
Vector refPos = getPositionsInRange(this.positions, where, this.content.length + nitems - where);
Iterator iter = refPos.iterator();
while (iter.hasNext())
{
StickyPosition p = (StickyPosition)iter.next();
int result = p.getOffset() - nitems;
p.setOffset(result);
if (result < 0)
this.positions.remove(p);
}
return rundo;
}
public String getString(int where, int len) throws BadLocationException
{
checkLocation(where, len);
return new String (this.content, where, len);
}
public void getChars(int where, int len, Segment txt) throws BadLocationException
{
checkLocation(where, len);
if (txt != null)
{
txt.array = this.content;
txt.offset = where;
txt.count = len;
}
}
private void checkLocation(int where, int len) throws BadLocationException
{
if (where < 0)
throw new BadLocationException("Invalid location", 1);
else if (where > this.count)
throw new BadLocationException("Invalid location", this.count);
else if ((where + len)>this.count)
throw new BadLocationException("Invalid range", this.count);
}
}