2005-01-02 Michael Koch <konqueror@gmx.de>
[official-gcc.git] / libjava / javax / swing / text / AbstractDocument.java
blob79bad04ccaa929dfa6466721c2c16f98b312c451
1 /* AbstractDocument.java --
2 Copyright (C) 2002, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing.text;
41 import java.io.PrintStream;
42 import java.io.Serializable;
43 import java.util.Collections;
44 import java.util.Dictionary;
45 import java.util.Enumeration;
46 import java.util.EventListener;
47 import java.util.Vector;
49 import javax.swing.event.DocumentEvent;
50 import javax.swing.event.DocumentListener;
51 import javax.swing.event.EventListenerList;
52 import javax.swing.event.UndoableEditEvent;
53 import javax.swing.event.UndoableEditListener;
54 import javax.swing.tree.TreeNode;
55 import javax.swing.undo.AbstractUndoableEdit;
56 import javax.swing.undo.CompoundEdit;
57 import javax.swing.undo.UndoableEdit;
59 public abstract class AbstractDocument
60 implements Document, Serializable
62 private static final long serialVersionUID = -116069779446114664L;
63 protected static final String BAD_LOCATION = "document location failure";
64 public static final String BidiElementName = "bidi level";
65 public static final String ContentElementName = "content";
66 public static final String ParagraphElementName = "paragraph";
67 public static final String SectionElementName = "section";
68 public static final String ElementNameAttribute = "$ename";
70 Content content;
71 AttributeContext context;
72 protected EventListenerList listenerList = new EventListenerList();
74 protected AbstractDocument(Content doc)
76 this(doc, StyleContext.getDefaultStyleContext());
79 protected AbstractDocument(Content doc, AttributeContext ctx)
81 content = doc;
82 context = ctx;
85 // These still need to be implemented by a derived class:
86 public abstract Element getParagraphElement(int pos);
88 public abstract Element getDefaultRootElement();
90 protected Element createBranchElement(Element parent,
91 AttributeSet attributes)
93 return new BranchElement(parent, attributes);
96 protected Element createLeafElement(Element parent, AttributeSet attributes,
97 int start, int end)
99 return new LeafElement(parent, attributes, start, end);
102 public Position createPosition(final int offset) throws BadLocationException
104 if (offset < 0 || offset > getLength())
105 throw new BadLocationException(getText(0, getLength()), offset);
107 return new Position()
109 public int getOffset()
111 return offset;
116 protected void fireChangedUpdate(DocumentEvent event)
118 DocumentListener[] listeners = getDocumentListeners();
120 for (int index = 0; index < listeners.length; ++index)
121 listeners[index].changedUpdate(event);
124 protected void fireInsertUpdate(DocumentEvent event)
126 DocumentListener[] listeners = getDocumentListeners();
128 for (int index = 0; index < listeners.length; ++index)
129 listeners[index].insertUpdate(event);
132 protected void fireRemoveUpdate(DocumentEvent event)
134 DocumentListener[] listeners = getDocumentListeners();
136 for (int index = 0; index < listeners.length; ++index)
137 listeners[index].removeUpdate(event);
140 protected void fireUndoableEditUpdate(UndoableEditEvent event)
142 UndoableEditListener[] listeners = getUndoableEditListeners();
144 for (int index = 0; index < listeners.length; ++index)
145 listeners[index].undoableEditHappened(event);
148 public int getAsynchronousLoadPriority()
150 return 0;
153 protected AttributeContext getAttributeContext()
155 return context;
158 public Element getBidiRootElement()
160 return null;
163 protected Content getContent()
165 return content;
168 protected Thread getCurrentWriter()
170 return null;
173 public Dictionary getDocumentProperties()
175 return null;
178 public Position getEndPosition()
180 return new Position()
182 public int getOffset()
184 return getLength();
189 public int getLength()
191 return content.length() - 1;
194 public EventListener[] getListeners(Class listenerType)
196 return listenerList.getListeners(listenerType);
199 public Object getProperty(Object key)
201 return null;
204 public Element[] getRootElements()
206 Element[] elements = new Element[1];
207 elements[0] = getDefaultRootElement();
208 return elements;
211 public Position getStartPosition()
213 return new Position()
215 public int getOffset()
217 return 0;
222 public String getText(int offset, int length) throws BadLocationException
224 return content.getString(offset, length);
227 public void getText(int offset, int length, Segment segment)
228 throws BadLocationException
230 content.getChars(offset, length, segment);
233 public void insertString(int offset, String text, AttributeSet attributes)
234 throws BadLocationException
236 // Just return when no text to insert was given.
237 if (text == null || text.length() == 0)
238 return;
240 DefaultDocumentEvent event =
241 new DefaultDocumentEvent(offset, text.length(),
242 DocumentEvent.EventType.INSERT);
243 content.insertString(offset, text);
244 insertUpdate(event, attributes);
245 fireInsertUpdate(event);
248 protected void insertUpdate(DefaultDocumentEvent chng, AttributeSet attr)
252 protected void postRemoveUpdate(DefaultDocumentEvent chng)
256 public void putProperty(Object key, Object value)
260 public void readLock()
264 public void readUnlock()
268 public void remove(int offset, int length) throws BadLocationException
270 DefaultDocumentEvent event =
271 new DefaultDocumentEvent(offset, length,
272 DocumentEvent.EventType.REMOVE);
273 removeUpdate(event);
274 content.remove(offset, length);
275 postRemoveUpdate(event);
276 fireRemoveUpdate(event);
280 * Replaces some text in the document.
282 * @since 1.4
284 public void replace(int offset, int length, String text,
285 AttributeSet attributes)
286 throws BadLocationException
288 remove(offset, length);
289 insertString(offset, text, attributes);
293 * Adds a <code>DocumentListener</code> object to this document.
295 * @param listener the listener to add
297 public void addDocumentListener(DocumentListener listener)
299 listenerList.add(DocumentListener.class, listener);
303 * Removes a <code>DocumentListener</code> object from this document.
305 * @param listener the listener to remove
307 public void removeDocumentListener(DocumentListener listener)
309 listenerList.remove(DocumentListener.class, listener);
313 * Returns add added <code>DocumentListener</code> objects.
315 * @return an array of listeners
317 public DocumentListener[] getDocumentListeners()
319 return (DocumentListener[]) getListeners(DocumentListener.class);
323 * Adds a <code>UndoableEditListener</code> object to this document.
325 * @param listener the listener to add
327 public void addUndoableEditListener(UndoableEditListener listener)
329 listenerList.add(UndoableEditListener.class, listener);
333 * Removes a <code>UndoableEditListener</code> object from this document.
335 * @param listener the listener to remove
337 public void removeUndoableEditListener(UndoableEditListener listener)
339 listenerList.remove(UndoableEditListener.class, listener);
343 * Returns add added <code>UndoableEditListener</code> objects.
345 * @return an array of listeners
347 public UndoableEditListener[] getUndoableEditListeners()
349 return (UndoableEditListener[]) getListeners(UndoableEditListener.class);
352 protected void removeUpdate(DefaultDocumentEvent chng)
356 public void render(Runnable r)
360 public void setAsynchronousLoadPriority(int p)
364 public void setDocumentProperties(Dictionary x)
368 protected void writeLock()
372 protected void writeUnlock()
376 public interface AttributeContext
378 AttributeSet addAttribute(AttributeSet old, Object name, Object value);
380 AttributeSet addAttributes(AttributeSet old, AttributeSet attributes);
382 AttributeSet getEmptySet();
384 void reclaim(AttributeSet attributes);
386 AttributeSet removeAttribute(AttributeSet old, Object name);
388 AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes);
390 AttributeSet removeAttributes(AttributeSet old, Enumeration names);
393 public interface Content
395 Position createPosition(int offset) throws BadLocationException;
397 int length();
399 UndoableEdit insertString(int where, String str)
400 throws BadLocationException;
402 UndoableEdit remove(int where, int nitems) throws BadLocationException;
404 String getString(int where, int len) throws BadLocationException;
406 void getChars(int where, int len, Segment txt) throws BadLocationException;
409 public abstract class AbstractElement
410 implements Element, MutableAttributeSet, TreeNode, Serializable
412 private static final long serialVersionUID = 1265312733007397733L;
413 int count;
414 int offset;
416 AttributeSet attributes;
418 Element element_parent;
419 Vector element_children;
421 TreeNode tree_parent;
422 Vector tree_children;
424 public AbstractElement(Element p, AttributeSet s)
426 element_parent = p;
427 attributes = s;
430 // TreeNode implementation
432 public abstract Enumeration children();
434 public abstract boolean getAllowsChildren();
436 public TreeNode getChildAt(int index)
438 return (TreeNode) tree_children.get(index);
441 public int getChildCount()
443 return tree_children.size();
446 public int getIndex(TreeNode node)
448 return tree_children.indexOf(node);
451 public TreeNode getParent()
453 return tree_parent;
456 public abstract boolean isLeaf();
459 // MutableAttributeSet support
461 public void addAttribute(Object name, Object value)
463 attributes = getAttributeContext().addAttribute(attributes, name, value);
466 public void addAttributes(AttributeSet attrs)
468 attributes = getAttributeContext().addAttributes(attributes, attrs);
471 public void removeAttribute(Object name)
473 attributes = getAttributeContext().removeAttribute(attributes, name);
476 public void removeAttributes(AttributeSet attrs)
478 attributes = getAttributeContext().removeAttributes(attributes, attrs);
481 public void removeAttributes(Enumeration names)
483 attributes = getAttributeContext().removeAttributes(attributes, names);
486 public void setResolveParent(AttributeSet parent)
488 attributes = getAttributeContext().addAttribute(attributes, ResolveAttribute, parent);
492 // AttributeSet interface support
494 public boolean containsAttribute(Object name, Object value)
496 return attributes.containsAttribute(name, value);
499 public boolean containsAttributes(AttributeSet attrs)
501 return attributes.containsAttributes(attrs);
504 public AttributeSet copyAttributes()
506 return attributes.copyAttributes();
509 public Object getAttribute(Object key)
511 return attributes.getAttribute(key);
514 public int getAttributeCount()
516 return attributes.getAttributeCount();
519 public Enumeration getAttributeNames()
521 return attributes.getAttributeNames();
524 public AttributeSet getResolveParent()
526 return attributes.getResolveParent();
529 public boolean isDefined(Object attrName)
531 return attributes.isDefined(attrName);
534 public boolean isEqual(AttributeSet attrs)
536 return attributes.isEqual(attrs);
539 // Element interface support
541 public AttributeSet getAttributes()
543 return attributes;
546 public Document getDocument()
548 return AbstractDocument.this;
551 public abstract Element getElement(int index);
553 public String getName()
555 return (String) getAttribute(NameAttribute);
558 public Element getParentElement()
560 return element_parent;
563 public abstract int getEndOffset();
565 public abstract int getElementCount();
567 public abstract int getElementIndex(int offset);
569 public abstract int getStartOffset();
571 private void dumpElement(PrintStream stream, String indent, Element element)
573 System.out.println(indent + "<" + element.getName() +">");
575 if (element.isLeaf())
577 int start = element.getStartOffset();
578 int end = element.getEndOffset();
579 String text = "";
582 text = getContent().getString(start, end - start);
584 catch (BadLocationException e)
587 System.out.println(indent + " ["
588 + start + ","
589 + end + "]["
590 + text + "]");
592 else
594 for (int i = 0; i < element.getElementCount(); ++i)
595 dumpElement(stream, indent + " ", element.getElement(i));
599 public void dump(PrintStream stream, int indent)
601 String indentStr = "";
602 for (int i = 0; i < indent; ++i)
603 indentStr += " ";
604 dumpElement(stream, indentStr, this);
608 public class BranchElement extends AbstractElement
610 private static final long serialVersionUID = -8595176318868717313L;
612 private Vector children = new Vector();
614 public BranchElement(Element parent, AttributeSet attributes)
616 super(parent, attributes);
619 public Enumeration children()
621 return children.elements();
624 public boolean getAllowsChildren()
626 return true;
629 public Element getElement(int index)
631 if (index < 0 || index >= children.size())
632 return null;
634 return (Element) children.get(index);
637 public int getElementCount()
639 return children.size();
642 public int getElementIndex(int offset)
644 if (children.size() == 0)
645 return 0;
647 Element element = positionToElement(offset);
649 if (element == null)
650 return 0;
652 return children.indexOf(element);
655 public int getEndOffset()
657 return ((Element) children.lastElement()).getEndOffset();
660 public String getName()
662 return ParagraphElementName;
665 public int getStartOffset()
667 return ((Element) children.firstElement()).getStartOffset();
670 public boolean isLeaf()
672 return false;
675 public Element positionToElement(int position)
677 // XXX: There is surely a better algorithm
678 // as beginning from first element each time.
679 for (int index = 0; index < children.size(); ++index)
681 Element elem = (Element) children.get(index);
683 if ((elem.getStartOffset() <= position)
684 && (position < elem.getEndOffset()))
685 return elem;
688 return null;
691 public void replace(int offset, int length, Element[] elems)
693 for (int index = 0; index < length; ++index)
694 children.removeElementAt(offset);
696 for (int index = 0; index < elems.length; ++index)
697 children.add(offset + index, elems[index]);
700 public String toString()
702 return ("BranchElement(" + getName() + ") "
703 + getStartOffset() + "," + getEndOffset() + "\n");
707 public class DefaultDocumentEvent extends CompoundEdit
708 implements DocumentEvent
710 private static final long serialVersionUID = -7406103236022413522L;
712 private int offset;
713 private int length;
714 private DocumentEvent.EventType type;
716 public DefaultDocumentEvent(int offset, int length,
717 DocumentEvent.EventType type)
719 this.offset = offset;
720 this.length = length;
721 this.type = type;
724 public Document getDocument()
726 return AbstractDocument.this;
729 public int getLength()
731 return length;
734 public int getOffset()
736 return offset;
739 public DocumentEvent.EventType getType()
741 return type;
744 public DocumentEvent.ElementChange getChange(Element elem)
746 return null;
750 public static class ElementEdit extends AbstractUndoableEdit
751 implements DocumentEvent.ElementChange
753 private static final long serialVersionUID = -1216620962142928304L;
755 private Element elem;
756 private int index;
757 private Element[] removed;
758 private Element[] added;
760 public ElementEdit(Element elem, int index,
761 Element[] removed, Element[] added)
763 this.elem = elem;
764 this.index = index;
765 this.removed = removed;
766 this.added = added;
769 public Element[] getChildrenAdded()
771 return added;
774 public Element[] getChildrenRemoved()
776 return removed;
779 public Element getElement()
781 return elem;
784 public int getIndex()
786 return index;
790 public class LeafElement extends AbstractElement
792 private static final long serialVersionUID = 5115368706941283802L;
793 private int start;
794 private int end;
796 public LeafElement(Element parent, AttributeSet attributes, int start,
797 int end)
799 super(parent, attributes);
800 this.start = start;
801 this.end = end;
804 public Enumeration children()
806 return null;
809 public boolean getAllowsChildren()
811 return false;
814 public Element getElement(int index)
816 return null;
819 public int getElementCount()
821 return 0;
824 public int getElementIndex(int offset)
826 return -1;
829 public int getEndOffset()
831 return end;
834 public String getName()
836 return ContentElementName;
839 public int getStartOffset()
841 return start;
844 public boolean isLeaf()
846 return true;
849 public String toString()
851 return ("LeafElement(" + getName() + ") "
852 + getStartOffset() + "," + getEndOffset() + "\n");