public abstract class AbstractDocument extends Objectimplements Document , Serializable
This class implements a locking mechanism for the document. It allows multiple readers or one writer, and writers must wait until all observers of the document have been notified of a previous change before beginning another mutation to the document. The read lock is acquired and released using the render method. A write lock is acquired by the methods that mutate the document, and are held for the duration of the method call. Notification is done on the thread that produced the mutation, and the thread has full read access to the document for the duration of the notification, but other readers are kept out until the notification has finished. The notification is a beans event notification which does not allow any further mutations until all listeners have been notified.
Any models subclassed from this class and used in conjunction with a text component that has a look and feel implementation that is derived from BasicTextUI may be safely updated asynchronously, because all access to the View hierarchy is serialized by BasicTextUI if the document is of type AbstractDocument. The locking assumes that an independent thread will access the View hierarchy only from the DocumentListener methods, and that there will be only one event thread active at a time.
If concurrency support is desired, there are the following additional implications. The code path for any DocumentListener implementation and any UndoListener implementation must be threadsafe, and not access the component lock if trying to be safe from deadlocks. The repaint and revalidate methods on JComponent are safe.
AbstractDocument models an implied break at the end of the document. Among other things this allows you to position the caret after the last character. As a result of this, getLength returns one less than the length of the Content. If you create your own Content, be sure and initialize it to have an additional character. Refer to StringContent and GapContent for examples of this. Another implication of this is that Elements that model the implied end character will have an endOffset == (getLength() + 1). For example, in DefaultStyledDocument getParagraphElement(getLength()).getEndOffset() == getLength() + 1 .
Warning: Serialized objects of this class will not be compatible with future Swing releases. The current serialization support is appropriate for short term storage or RMI between applications running the same version of Swing. As of 1.4, support for long term storage of all JavaBeans™ has been added to the java.beans package. Please see XMLEncoder.
| Modifier and Type | Class and Description |
|---|---|
class |
AbstractDocument
Implements the abstract part of an element.
|
static interface |
AbstractDocument
An interface that can be used to allow MutableAttributeSet implementations to use pluggable attribute compression techniques.
|
class |
AbstractDocument
Implements a composite element that contains other elements.
|
static interface |
AbstractDocument
Interface to describe a sequence of character content that can be edited.
|
class |
AbstractDocument
Stores document changes as the document is being modified.
|
static class |
AbstractDocument
An implementation of ElementChange that can be added to the document event.
|
class |
AbstractDocument
Implements an element that directly represents content of some kind.
|
| Modifier and Type | Field and Description |
|---|---|
protected static String |
BAD_LOCATION
Error message to indicate a bad location.
|
static String |
BidiElementName
Name of elements used to hold a unidirectional run
|
static String |
ContentElementName
Name of elements used to represent content
|
static String |
ElementNameAttribute
Name of the attribute used to specify element names.
|
protected EventListenerList |
listenerList
The event listener list for the document.
|
static String |
ParagraphElementName
Name of elements used to represent paragraphs
|
static String |
SectionElementName
Name of elements used to hold sections (lines/paragraphs).
|
StreamDescriptionProperty, TitleProperty| Modifier | Constructor and Description |
|---|---|
protected |
AbstractDocument(AbstractDocument
Constructs a new
AbstractDocument, wrapped around some specified content storage mechanism.
|
protected |
AbstractDocument(AbstractDocument
Constructs a new
AbstractDocument, wrapped around some specified content storage mechanism.
|
| Modifier and Type | Method and Description |
|---|---|
void |
addDocumentListener(DocumentListener
Adds a document listener for notification of any changes.
|
void |
addUndoableEditListener(UndoableEditListener
Adds an undo listener for notification of any changes.
|
protected Element |
createBranchElement(Element
Creates a document branch element, that can contain other elements.
|
protected Element |
createLeafElement(Element
Creates a document leaf element.
|
Position |
createPosition(int offs)
Returns a position that will track change as the document is altered.
|
void |
dump(PrintStream
Gives a diagnostic dump.
|
protected void |
fireChangedUpdate(DocumentEvent
Notifies all listeners that have registered interest for notification on this event type.
|
protected void |
fireInsertUpdate(DocumentEvent
Notifies all listeners that have registered interest for notification on this event type.
|
protected void |
fireRemoveUpdate(DocumentEvent
Notifies all listeners that have registered interest for notification on this event type.
|
protected void |
fireUndoableEditUpdate(UndoableEditEvent
Notifies all listeners that have registered interest for notification on this event type.
|
int |
getAsynchronousLoadPriority()
Gets the asynchronous loading priority.
|
protected AbstractDocument |
getAttributeContext()
Fetches the context for managing attributes.
|
Element |
getBidiRootElement()
Returns the root element of the bidirectional structure for this document.
|
protected AbstractDocument |
getContent()
Gets the content for the document.
|
protected Thread |
getCurrentWriter()
Fetches the current writing thread if there is one.
|
abstract Element |
getDefaultRootElement()
Returns the root element that views should be based upon unless some other mechanism for assigning views to element structures is provided.
|
DocumentFilter |
getDocumentFilter()
Returns the
DocumentFilter that is responsible for filtering of insertion/removal.
|
DocumentListener |
getDocumentListeners()
Returns an array of all the document listeners registered on this document.
|
Dictionary |
getDocumentProperties()
Supports managing a set of properties.
|
Position |
getEndPosition()
Returns a position that represents the end of the document.
|
int |
getLength()
Returns the length of the data.
|
<T extends EventListener |
getListeners(Class
Returns an array of all the objects currently registered as
FooListeners upon this document.
|
abstract Element |
getParagraphElement(int pos)
Get the paragraph element containing the given position.
|
Object |
getProperty(Object
A convenience method for looking up a property value.
|
Element |
getRootElements()
Gets all root elements defined.
|
Position |
getStartPosition()
Returns a position that represents the start of the document.
|
String |
getText(int offset, int length)
Gets a sequence of text from the document.
|
void |
getText(int offset, int length, Segment
Fetches the text contained within the given portion of the document.
|
UndoableEditListener |
getUndoableEditListeners()
Returns an array of all the undoable edit listeners registered on this document.
|
void |
insertString(int offs, String
Inserts some content into the document.
|
protected void |
insertUpdate(AbstractDocument
Updates document structure as a result of text insertion.
|
protected void |
postRemoveUpdate(AbstractDocument
Updates any document structure as a result of text removal.
|
void |
putProperty(Object
A convenience method for storing up a property value.
|
void |
readLock()
Acquires a lock to begin reading some state from the document.
|
void |
readUnlock()
Does a read unlock.
|
void |
remove(int offs, int len)
Removes some content from the document.
|
void |
removeDocumentListener(DocumentListener
Removes a document listener.
|
void |
removeUndoableEditListener(UndoableEditListener
Removes an undo listener.
|
protected void |
removeUpdate(AbstractDocument
Updates any document structure as a result of text removal.
|
void |
render(Runnable
This allows the model to be safely rendered in the presence of currency, if the model supports being updated asynchronously.
|
void |
replace(int offset, int length, String
Deletes the region of text from
offset to
offset + length, and replaces it with
text.
|
void |
setAsynchronousLoadPriority(int p)
Sets the asynchronous loading priority.
|
void |
setDocumentFilter(DocumentFilter
Sets the
DocumentFilter.
|
void |
setDocumentProperties(Dictionary
Replaces the document properties dictionary for this document.
|
protected void |
writeLock()
Acquires a lock to begin mutating the document this lock protects.
|
protected void |
writeUnlock()
Releases a write lock previously obtained via
writeLock.
|
protected EventListenerListlistenerList
protected static final StringBAD_LOCATION
public static final StringParagraphElementName
public static final StringContentElementName
public static final StringSectionElementName
public static final StringBidiElementName
public static final StringElementNameAttribute
protected AbstractDocument(AbstractDocument.Content data)
AbstractDocument, wrapped around some specified content storage mechanism.
data - the content
protected AbstractDocument(AbstractDocument.Content data, AbstractDocument .AttributeContext context)
AbstractDocument, wrapped around some specified content storage mechanism.
data - the content
context - the attribute context
public Dictionary<Object ,Object > getDocumentProperties()
documentProperties dictionary to annotate the document with document-wide properties.
null
Dictionary
setDocumentProperties(java.util.Dictionary<java.lang.Object, java.lang.Object>)
public void setDocumentProperties(Dictionary<Object ,Object > x)
x - the new dictionary
getDocumentProperties()
protected void fireInsertUpdate(DocumentEvente)
e - the event
EventListenerList
protected void fireChangedUpdate(DocumentEvente)
e - the event
EventListenerList
protected void fireRemoveUpdate(DocumentEvente)
e - the event
EventListenerList
protected void fireUndoableEditUpdate(UndoableEditEvente)
e - the event
EventListenerList
public <T extends EventListener> T[] getListeners(Class <T> listenerType)
FooListeners upon this document.
FooListeners are registered using the
addFooListener method.
You can specify the listenerType argument with a class literal, such as FooListener.class. For example, you can query a document d for its document listeners with the following code:
DocumentListener[] mls = (DocumentListener[])(d.getListeners(DocumentListener.class));If no such listeners exist, this method returns an empty array.
listenerType - the type of listeners requested; this parameter should specify an interface that descends from
java.util.EventListener
FooListeners on this component, or an empty array if no such listeners have been added
ClassCastException - if
listenerType doesn't specify a class or interface that implements
java.util.EventListener
getDocumentListeners(),
getUndoableEditListeners()
public int getAsynchronousLoadPriority()
-1 if the document should not be loaded asynchronously
public void setAsynchronousLoadPriority(int p)
p - the new asynchronous loading priority; a value less than zero indicates that the document should not be loaded asynchronously
public void setDocumentFilter(DocumentFilterfilter)
DocumentFilter. The
DocumentFilter is passed
insert and
remove to conditionally allow inserting/deleting of the text. A
null value indicates that no filtering will occur.
filter - the
DocumentFilter used to constrain text
getDocumentFilter()
public DocumentFiltergetDocumentFilter()
DocumentFilter that is responsible for filtering of insertion/removal. A
null return value implies no filtering is to occur.
setDocumentFilter(javax.swing.text.DocumentFilter)
public void render(Runnabler)
This is implemented to acquire a read lock for the duration of the runnables execution. There may be multiple runnables executing at the same time, and all writers will be blocked while there are active rendering runnables. If the runnable throws an exception, its lock will be safely released. There is no protection against a runnable that never exits, which will effectively leave the document locked for it's lifetime.
If the given runnable attempts to make any mutations in this implementation, a deadlock will occur. There is no tracking of individual rendering threads to enable detecting this situation, but a subclass could incur the overhead of tracking them and throwing an error.
This method is thread safe, although most Swing methods are not. Please see Concurrency in Swing for more information.
public int getLength()
getLength in interface
Document
Document.getLength()
public void addDocumentListener(DocumentListenerlistener)
addDocumentListener in interface
Document
listener - the
DocumentListener to add
Document.addDocumentListener(javax.swing.event.DocumentListener)
public void removeDocumentListener(DocumentListenerlistener)
removeDocumentListener in interface
Document
listener - the
DocumentListener to remove
Document.removeDocumentListener(javax.swing.event.DocumentListener)
public DocumentListener[] getDocumentListeners()
DocumentListeners or an empty array if no document listeners are currently registered
addDocumentListener(javax.swing.event.DocumentListener),
removeDocumentListener(javax.swing.event.DocumentListener)
public void addUndoableEditListener(UndoableEditListenerlistener)
UndoableEdit will cause the appropriate DocumentEvent to be fired to keep the view(s) in sync with the model.
addUndoableEditListener in interface
Document
listener - the
UndoableEditListener to add
Document.addUndoableEditListener(javax.swing.event.UndoableEditListener)
public void removeUndoableEditListener(UndoableEditListenerlistener)
removeUndoableEditListener in interface
Document
listener - the
UndoableEditListener to remove
Document.removeDocumentListener(javax.swing.event.DocumentListener)
public UndoableEditListener[] getUndoableEditListeners()
UndoableEditListeners or an empty array if no undoable edit listeners are currently registered
addUndoableEditListener(javax.swing.event.UndoableEditListener),
removeUndoableEditListener(javax.swing.event.UndoableEditListener)
public final ObjectgetProperty(Object key)
getDocumentProperties().get(key);
getProperty in interface
Document
key - the non-
null property key
null
getDocumentProperties()
public final void putProperty(Objectkey, Object value)
getDocumentProperties().put(key, value);If
value is
null this method will remove the property.
putProperty in interface
Document
key - the non-
null key
value - the property value
getDocumentProperties()
public void remove(int offs,
int len)
throws BadLocationException
This method is thread safe, although most Swing methods are not. Please see Concurrency in Swing for more information.
remove in interface
Document
offs - the starting offset >= 0
len - the number of characters to remove >= 0
BadLocationException - the given remove position is not a valid position within the document
Document.remove(int, int)
public void replace(int offset,
int length,
String text,
AttributeSet attrs)
throws BadLocationException
offset to
offset + length, and replaces it with
text. It is up to the implementation as to how this is implemented, some implementations may treat this as two distinct operations: a remove followed by an insert, others may treat the replace as one atomic operation.
offset - index of child element
length - length of text to delete, may be 0 indicating don't delete anything
text - text to insert,
null indicates no text to insert
attrs - AttributeSet indicating attributes of inserted text,
null is legal, and typically treated as an empty attributeset, but exact interpretation is left to the subclass
BadLocationException - the given position is not a valid position within the document
public void insertString(int offs,
String str,
AttributeSet a)
throws BadLocationException
This method is thread safe, although most Swing methods are not. Please see Concurrency in Swing for more information.
insertString in interface
Document
offs - the starting offset >= 0
str - the string to insert; does nothing with null/empty strings
a - the attributes for the inserted content
BadLocationException - the given insert position is not a valid position within the document
Document.insertString(int, java.lang.String, javax.swing.text.AttributeSet)
public StringgetText(int offset, int length) throws BadLocationException
getText in interface
Document
offset - the starting offset >= 0
length - the number of characters to retrieve >= 0
BadLocationException - the range given includes a position that is not a valid position within the document
Document.getText(int, int)
public void getText(int offset,
int length,
Segment txt)
throws BadLocationException
If the partialReturn property on the txt parameter is false, the data returned in the Segment will be the entire length requested and may or may not be a copy depending upon how the data was stored. If the partialReturn property is true, only the amount of text that can be returned without creating a copy is returned. Using partial returns will give better performance for situations where large parts of the document are being scanned. The following is an example of using the partial return to access the entire document:
int nleft = doc.getDocumentLength();
Segment text = new Segment();
int offs = 0;
text.setPartialReturn(true);
while (nleft > 0) {
doc.getText(offs, nleft, text);
// do something with text
nleft -= text.count;
offs += text.count;
}
getText in interface
Document
offset - the starting offset >= 0
length - the number of characters to retrieve >= 0
txt - the Segment object to retrieve the text into
BadLocationException - the range given includes a position that is not a valid position within the document
public PositioncreatePosition(int offs) throws BadLocationException
This method is thread safe, although most Swing methods are not. Please see Concurrency in Swing for more information.
createPosition in interface
Document
offs - the position in the model >= 0
BadLocationException - if the given position does not represent a valid location in the associated document
Document.createPosition(int)
public final PositiongetStartPosition()
getStartPosition in interface
Document
public final PositiongetEndPosition()
getEndPosition in interface
Document
public Element[] getRootElements()
getRootElements in interface
Document
public abstract ElementgetDefaultRootElement()
getDefaultRootElement in interface
Document
Document.getDefaultRootElement()
public ElementgetBidiRootElement()
public abstract ElementgetParagraphElement(int pos)
pos - the starting offset >= 0
protected final AbstractDocument.AttributeContext getAttributeContext()
protected void insertUpdate(AbstractDocument.DefaultDocumentEvent chng, AttributeSet attr)
chng - a description of the change
attr - the attributes for the change
protected void removeUpdate(AbstractDocument.DefaultDocumentEvent chng)
chng - a description of the change
protected void postRemoveUpdate(AbstractDocument.DefaultDocumentEvent chng)
chng - a description of the change
public void dump(PrintStreamout)
out - the output stream
protected final AbstractDocument.Content getContent()
protected ElementcreateLeafElement(Element parent, AttributeSet a, int p0, int p1)
parent - the parent element
a - the attributes for the element
p0 - the beginning of the range >= 0
p1 - the end of the range >= p0
protected ElementcreateBranchElement(Element parent, AttributeSet a)
parent - the parent element
a - the attributes
protected final ThreadgetCurrentWriter()
null if there are no modifications in progress
protected final void writeLock()
writeLock, as long as it doesn't attempt to gain additional
writeLocks from within document notification. Attempting to gain a
writeLock from within a DocumentListener notification will result in an
IllegalStateException. The ability to obtain more than one
writeLock per thread allows subclasses to gain a writeLock, perform a number of operations, then release the lock.
Calls to writeLock must be balanced with calls to writeUnlock, else the Document will be left in a locked state so that no reading or writing can be done.
IllegalStateException - thrown on illegal lock attempt. If the document is implemented properly, this can only happen if a document listener attempts to mutate the document. This situation violates the bean event model where order of delivery is not guaranteed and all listeners should be notified before further mutations are allowed.
protected final void writeUnlock()
writeLock. After decrementing the lock count if there are no outstanding locks this will allow a new writer, or readers.
writeLock()
public final void readLock()
readUnlock.
readUnlock()
public final void readUnlock()
readLock();
try {
// do something
} finally {
readUnlock();
}
readLock()