001: /*
002: * Copyright 2000,2005 wingS development team.
003: *
004: * This file is part of wingS (http://wingsframework.org).
005: *
006: * wingS is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU Lesser General Public License
008: * as published by the Free Software Foundation; either version 2.1
009: * of the License, or (at your option) any later version.
010: *
011: * Please see COPYING for the complete licence.
012: */
013: package org.wings.text;
014:
015: import org.wings.event.SDocumentEvent;
016: import org.wings.event.SDocumentListener;
017: import org.wings.util.EditTranscriptGenerator;
018: import org.wings.util.SStringBuilder;
019:
020: import javax.swing.event.DocumentEvent;
021: import javax.swing.event.EventListenerList;
022: import javax.swing.text.BadLocationException;
023: import java.lang.reflect.Array;
024: import java.util.ArrayList;
025: import java.util.Iterator;
026: import java.util.List;
027:
028: /**
029: * @author hengels
030: */
031: public class DefaultDocument implements SDocument {
032: private final SStringBuilder buffer = new SStringBuilder();
033: private EventListenerList listeners = null;
034:
035: /**
036: * Indicates if we should fire event immediately when they arise,
037: * or if we should collect them for a later delivery
038: */
039: private boolean delayEvents = false;
040:
041: /**
042: * All delayed events are stored here
043: */
044: protected final ArrayList delayedEvents = new ArrayList(5);
045:
046: public DefaultDocument() {
047: }
048:
049: public DefaultDocument(String text) {
050: buffer.append(text);
051: }
052:
053: public void setText(String text) {
054: String origText = buffer.toString();
055: if (origText.equals(text)) {
056: return;
057: }
058: buffer.setLength(0);
059: if (text != null) {
060: buffer.append(text);
061: }
062: if ((listeners == null) || (listeners.getListenerCount() > 0)) {
063: // If there are any document listeners: Generate document change events!
064: List actions = EditTranscriptGenerator.generateEvents(
065: origText, text);
066:
067: // and fire them!
068: fireChangeUpdate(0, buffer.length());
069: for (int i = 0; i < actions.size(); i++) {
070: DocumentEvent de = (DocumentEvent) actions.get(i);
071: if (de.getType().equals(DocumentEvent.EventType.INSERT)) {
072: fireInsertUpdate(de.getOffset(), de.getLength());
073: } else if (de.getType().equals(
074: DocumentEvent.EventType.REMOVE)) {
075: fireRemoveUpdate(de.getOffset(), de.getLength());
076: }
077: }
078: }
079: }
080:
081: public String getText() {
082: return buffer.length() == 0 ? "" : buffer.toString();
083: }
084:
085: public String getText(int offset, int length)
086: throws BadLocationException {
087: try {
088: return buffer.substring(offset, length);
089: } catch (IndexOutOfBoundsException e) {
090: throw new BadLocationException(e.getMessage(), offset);
091: }
092: }
093:
094: public int getLength() {
095: return buffer.length();
096: }
097:
098: public void remove(int offset, int length)
099: throws BadLocationException {
100: if (length == 0) {
101: return;
102: }
103: try {
104: buffer.delete(offset, offset + length);
105: fireRemoveUpdate(offset, length);
106: } catch (IndexOutOfBoundsException e) {
107: throw new BadLocationException(e.getMessage(), offset);
108: }
109: }
110:
111: public void insert(int offset, String string)
112: throws BadLocationException {
113: if (string == null || string.length() == 0) {
114: return;
115: }
116: try {
117: buffer.insert(offset, string);
118: fireInsertUpdate(offset, string.length());
119: } catch (IndexOutOfBoundsException e) {
120: throw new BadLocationException(e.getMessage(), offset);
121: }
122: }
123:
124: public SDocumentListener[] getDocumentListeners() {
125: if (listeners != null) {
126: return (SDocumentListener[]) listeners
127: .getListeners(SDocumentListener.class);
128: } else {
129: return (SDocumentListener[]) Array.newInstance(
130: SDocumentListener.class, 0);
131: }
132: }
133:
134: public void addDocumentListener(SDocumentListener listener) {
135: if (listeners == null)
136: listeners = new EventListenerList();
137: listeners.add(SDocumentListener.class, listener);
138: }
139:
140: public void removeDocumentListener(SDocumentListener listener) {
141: if (listeners == null)
142: return;
143: listeners.remove(SDocumentListener.class, listener);
144: }
145:
146: protected void fireInsertUpdate(int offset, int length) {
147: SDocumentEvent e = new SDocumentEvent(this , offset, length,
148: SDocumentEvent.INSERT);
149:
150: if (delayEvents) {
151: delayedEvents.add(e);
152: } else {
153: if (listeners == null || listeners.getListenerCount() == 0)
154: return;
155:
156: Object[] listeners = this .listeners.getListenerList();
157: for (int i = listeners.length - 2; i >= 0; i -= 2) {
158: ((SDocumentListener) listeners[i + 1]).insertUpdate(e);
159: }
160: }
161: }
162:
163: protected void fireRemoveUpdate(int offset, int length) {
164: SDocumentEvent e = new SDocumentEvent(this , offset, length,
165: SDocumentEvent.REMOVE);
166:
167: if (delayEvents) {
168: delayedEvents.add(e);
169: } else {
170: if (listeners == null || listeners.getListenerCount() == 0)
171: return;
172:
173: Object[] listeners = this .listeners.getListenerList();
174: for (int i = listeners.length - 2; i >= 0; i -= 2) {
175: ((SDocumentListener) listeners[i + 1]).removeUpdate(e);
176: }
177: }
178: }
179:
180: protected void fireChangeUpdate(int offset, int length) {
181: SDocumentEvent e = new SDocumentEvent(this , offset, length,
182: SDocumentEvent.CHANGE);
183:
184: if (delayEvents) {
185: delayedEvents.add(e);
186: } else {
187: if (listeners == null || listeners.getListenerCount() == 0)
188: return;
189:
190: Object[] listeners = this .listeners.getListenerList();
191: for (int i = listeners.length - 2; i >= 0; i -= 2) {
192: ((SDocumentListener) listeners[i + 1]).changedUpdate(e);
193: }
194: }
195: }
196:
197: public boolean getDelayEvents() {
198: return delayEvents;
199: }
200:
201: public void setDelayEvents(boolean b) {
202: delayEvents = b;
203: }
204:
205: public void fireDelayedIntermediateEvents() {
206: for (Iterator iter = delayedEvents.iterator(); iter.hasNext();) {
207: SDocumentEvent e = (SDocumentEvent) iter.next();
208:
209: switch (e.getType()) {
210: case SDocumentEvent.INSERT:
211: fireInsertUpdate(e.getOffset(), e.getLength());
212: case SDocumentEvent.REMOVE:
213: fireRemoveUpdate(e.getOffset(), e.getLength());
214: case SDocumentEvent.CHANGE:
215: fireChangeUpdate(e.getOffset(), e.getLength());
216: }
217: }
218: delayedEvents.clear();
219: }
220:
221: public void fireDelayedFinalEvents() {
222:
223: }
224: }
|