1:
37:
38:
39: package ;
40:
41: import ;
42:
43:
52: public class PlainDocument extends AbstractDocument
53: {
54: private static final long serialVersionUID = 4758290289196893664L;
55:
56: public static final String lineLimitAttribute = "lineLimit";
57: public static final String tabSizeAttribute = "tabSize";
58:
59:
64: private Element rootElement;
65:
66: public PlainDocument()
67: {
68: this(new GapContent());
69: }
70:
71: public PlainDocument(AbstractDocument.Content content)
72: {
73: super(content);
74: rootElement = createDefaultRoot();
75:
76:
77: putProperty("tabSize", new Integer(8));
78: }
79:
80: private void reindex()
81: {
82: Element[] lines;
83: try
84: {
85: String str = content.getString(0, content.length());
86:
87: ArrayList elts = new ArrayList();
88: int j = 0;
89: for (int i = str.indexOf('\n', 0); i != -1; i = str.indexOf('\n', i + 1))
90: {
91: elts.add(createLeafElement(rootElement, SimpleAttributeSet.EMPTY, j, i + 1));
92: j = i + 1;
93: }
94:
95: if (j < content.length())
96: elts.add(createLeafElement(rootElement, SimpleAttributeSet.EMPTY, j, content.length()));
97:
98: lines = new Element[elts.size()];
99: for (int i = 0; i < elts.size(); ++i)
100: lines[i] = (Element) elts.get(i);
101: }
102: catch (BadLocationException e)
103: {
104: lines = new Element[1];
105: lines[0] = createLeafElement(rootElement, SimpleAttributeSet.EMPTY, 0, 1);
106: }
107:
108: ((BranchElement) rootElement).replace(0, rootElement.getElementCount(), lines);
109: }
110:
111: protected AbstractDocument.AbstractElement createDefaultRoot()
112: {
113: BranchElement root =
114: (BranchElement) createBranchElement(null, null);
115:
116: Element[] array = new Element[1];
117: array[0] = createLeafElement(root, null, 0, 1);
118: root.replace(0, 0, array);
119:
120: return root;
121: }
122:
123: protected void insertUpdate(DefaultDocumentEvent event,
124: AttributeSet attributes)
125: {
126:
127: String text = null;
128: int offset = event.getOffset();
129: int length = event.getLength();
130: try
131: {
132: text = getText(offset, length);
133: }
134: catch (BadLocationException ex)
135: {
136: AssertionError err = new AssertionError();
137: err.initCause(ex);
138: throw err;
139: }
140:
141: boolean hasLineBreak = text.indexOf('\n') != -1;
142: boolean prevCharIsLineBreak = false;
143: try
144: {
145: prevCharIsLineBreak =
146: offset > 0 && getText(offset - 1, 1).charAt(0) == '\n';
147: }
148: catch (BadLocationException ex)
149: {
150: AssertionError err = new AssertionError();
151: err.initCause(ex);
152: throw err;
153: }
154: boolean lastCharIsLineBreak = text.charAt(text.length() - 1) == '\n';
155: int lineIndex = -1;
156: int lineStart = -1;
157: int lineEnd = -1;
158: Element[] removed = null;
159: BranchElement root = (BranchElement) rootElement;
160: boolean updateStructure = true;
161:
162: if (prevCharIsLineBreak && ! lastCharIsLineBreak)
163: {
164:
165:
166: lineIndex = root.getElementIndex(offset - 1);
167: Element prevLine = root.getElement(lineIndex);
168: Element nextLine = root.getElement(lineIndex + 1);
169: lineStart = prevLine.getStartOffset();
170: lineEnd = nextLine.getEndOffset();
171: removed = new Element[]{ prevLine, nextLine };
172: }
173: else if (hasLineBreak)
174: {
175: lineIndex = root.getElementIndex(offset);
176: Element line = root.getElement(lineIndex);
177: lineStart = line.getStartOffset();
178: lineEnd = line.getEndOffset();
179: removed = new Element[]{ line };
180: }
181: else
182: {
183: updateStructure = false;
184: }
185:
186: if (updateStructure)
187: {
188:
189: ArrayList lines = new ArrayList();
190: int len = lineEnd - lineStart;
191: try
192: {
193: text = getText(lineStart, len);
194: }
195: catch (BadLocationException ex)
196: {
197: AssertionError err = new AssertionError();
198: err.initCause(ex);
199: throw err;
200: }
201: int prevLineBreak = 0;
202: int lineBreak = text.indexOf('\n');
203: do
204: {
205: lineBreak++;
206: lines.add(createLeafElement(root, null, lineStart + prevLineBreak,
207: lineStart + lineBreak));
208: prevLineBreak = lineBreak;
209: lineBreak = text.indexOf('\n', prevLineBreak);
210: } while (prevLineBreak < len);
211:
212:
213: Element[] added = (Element[]) lines.toArray(new Element[lines.size()]);
214: event.addEdit(new ElementEdit(root, lineIndex, removed, added));
215: root.replace(lineIndex, removed.length, added);
216: }
217: super.insertUpdate(event, attributes);
218: }
219:
220: protected void removeUpdate(DefaultDocumentEvent event)
221: {
222: super.removeUpdate(event);
223:
224:
225:
226:
227: Element[] added = new Element[1];
228: Element[] removed;
229: int p0 = event.getOffset();
230:
231:
232: int i1 = rootElement.getElementIndex(p0);
233: int i2 = rootElement.getElementIndex(p0 + event.getLength());
234: if (i1 != i2)
235: {
236:
237:
238:
239: removed = new Element [i2 - i1 + 1];
240: for (int i = i1; i <= i2; i++)
241: removed[i-i1] = rootElement.getElement(i);
242:
243: int start = rootElement.getElement(i1).getStartOffset();
244: int end = rootElement.getElement(i2).getEndOffset();
245: added[0] = createLeafElement(rootElement,
246: SimpleAttributeSet.EMPTY,
247: start, end);
248:
249:
250: ElementEdit e = new ElementEdit(rootElement, i1, removed, added);
251: event.addEdit(e);
252:
253:
254: ((BranchElement) rootElement).replace(i1, i2 - i1 + 1, added);
255: }
256: }
257:
258: public Element getDefaultRootElement()
259: {
260: return rootElement;
261: }
262:
263: public Element getParagraphElement(int pos)
264: {
265: Element root = getDefaultRootElement();
266: return root.getElement(root.getElementIndex(pos));
267: }
268:
269:
284: public void insertString(int offs, String str, AttributeSet atts)
285: throws BadLocationException
286: {
287: String string = str;
288: if (str != null && Boolean.TRUE.equals(getProperty("filterNewlines")))
289: string = str.replaceAll("\n", " ");
290: super.insertString(offs, string, atts);
291: }
292: }