Class SafeDocument

java.lang.Object
org.bzdev.swing.text.SafeDocument
All Implemented Interfaces:
Document
Direct Known Subclasses:
SafeStyledDocument

public class SafeDocument extends Object implements Document
A Document class that is thread safe. Operations are performed on the event-dispatch thread. An existing document is encapsulated, with access to it controlled so as to be thread safe.

This class makes use of the static method SwingUtilities.invokeLater(Runnable). One should avoid the use of synchronized methods that call methods in this class when those synchronized methods might be called from tasks waiting on the AWT event dispatch queue, as there is a possibility of deadlock: If for some class methods m1 and m2 are synchronized and call one of the methods in this class, and m1 is called, a call to SwingUtilities.invokeLater(Runnable) may process other entries on its event queue first, causing m2 to be called, but m2 will wait until m1 returns, which cannot occur until m2 returns.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    class 
    SafeDocument runtime exception class for interrupted exceptions.
    class 
    SafeDocument runtime-exception class.
    class 
    Class to run a thread while logging any BadLocationException that occurs.
  • Field Summary

    Fields inherited from interface javax.swing.text.Document

    StreamDescriptionProperty, TitleProperty
  • Constructor Summary

    Constructors
    Constructor
    Description
    Constructor.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Registers the given observer to begin receiving notifications when changes are made to the document.
    void
    Registers the given observer to begin receiving notifications when undoable edits are made to the document.
    createPosition(int offs)
    This method allows an application to mark a place in a sequence of character content.
    protected Element
    doitElement(org.bzdev.swing.text.SafeDocument.RunnableWithElement r)
    Execute a task on the event dispatch thread, returning a Element.
    protected Element[]
    doitElements(org.bzdev.swing.text.SafeDocument.RunnableWithElements r)
    Execute a task on the event dispatch thread, returning an array of Element.
    protected int
    doitInt(org.bzdev.swing.text.SafeDocument.RunnableWithInt r)
    Perform an operation on the event dispatch thread and return an int.
    protected Object
    doitObject(org.bzdev.swing.text.SafeDocument.RunnableWithObj r)
    Perform an operation on the event dispatch thread and return an object.
    protected Position
    doitPosition(org.bzdev.swing.text.SafeDocument.RunnableWithPosition r)
    Execute an operation on the event dispatch thread and return a Position.
    protected Position
    doitPositionBLE(org.bzdev.swing.text.SafeDocument.RunnableWithPositionBLE r)
    Execute a task on the event dispatch thread, returning a position, throwing any BadLocationException that occurs.
    protected String
    doitStringBLE(org.bzdev.swing.text.SafeDocument.RunnableWithString r)
    Perform an operation on the event dispatch thread returning a String, possibly throwing a BadLocationException.
    protected void
    doitVoid(org.bzdev.swing.text.SafeDocument.RunnableWithRE r)
    Perform an operation on the event dispatch thread with no return value.
    protected void
    Perform an operation on the event dispatch thread, possibly throwing a BadLocationException.
    Returns the root element that views should be based upon, unless some other mechanism for assigning views to element structures is provided.
    Get the encapsulated document.
    Returns a position that represents the end of the document.
    int
    Returns number of characters of content currently in the document.
    Gets the properties associated with the document.
    Returns all of the root elements that are defined.
    Returns a position that represents the start of the document.
    getText(int offset, int length)
    Fetches the text contained within the given portion of the document.
    void
    getText(int offset, int length, Segment txt)
    Fetches the text contained within the given portion of the document.
    void
    insertString(int offset, String str, AttributeSet a)
    Inserts a string of content.
    void
    putProperty(Object key, Object value)
    Associates a property with the document.
    void
    remove(int offs, int len)
    Removes a portion of the content of the document.
    void
    Unregisters the given observer from the notification list so it will no longer receive change updates.
    void
    Unregisters the given observer from the notification list so it will no longer receive updates.
    void
    render(Runnable runnable)
    Allows the model to be safely rendered in the presence of concurrency, if the model supports being updated asynchronously.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • SafeDocument

      public SafeDocument(Document doc)
      Constructor.
      Parameters:
      doc - a document to encapsulate
  • Method Details

    • getEncapsulatedDocument

      public Document getEncapsulatedDocument()
      Get the encapsulated document.
      Returns:
      the encapsulated document
    • doitInt

      protected int doitInt(org.bzdev.swing.text.SafeDocument.RunnableWithInt r)
      Perform an operation on the event dispatch thread and return an int.
      Parameters:
      r - an object providing the code to execute in a method named doit()
      Returns:
      an integer value
    • getLength

      public int getLength()
      Returns number of characters of content currently in the document.
      Specified by:
      getLength in interface Document
      Returns:
      number of characters >= 0
    • doitVoid

      protected void doitVoid(org.bzdev.swing.text.SafeDocument.RunnableWithRE r)
      Perform an operation on the event dispatch thread with no return value.
      Parameters:
      r - an object providing the code to execute in a method named doit()
    • addDocumentListener

      public void addDocumentListener(DocumentListener listener)
      Registers the given observer to begin receiving notifications when changes are made to the document.
      Specified by:
      addDocumentListener in interface Document
      Parameters:
      listener - the observer to register
      See Also:
    • removeDocumentListener

      public void removeDocumentListener(DocumentListener listener)
      Unregisters the given observer from the notification list so it will no longer receive change updates.
      Specified by:
      removeDocumentListener in interface Document
      Parameters:
      listener - the observer to register
      See Also:
    • addUndoableEditListener

      public void addUndoableEditListener(UndoableEditListener listener)
      Registers the given observer to begin receiving notifications when undoable edits are made to the document.
      Specified by:
      addUndoableEditListener in interface Document
      Parameters:
      listener - the observer to register
      See Also:
    • removeUndoableEditListener

      public void removeUndoableEditListener(UndoableEditListener listener)
      Unregisters the given observer from the notification list so it will no longer receive updates.
      Specified by:
      removeUndoableEditListener in interface Document
      Parameters:
      listener - the observer to register
      See Also:
    • doitObject

      protected Object doitObject(org.bzdev.swing.text.SafeDocument.RunnableWithObj r)
      Perform an operation on the event dispatch thread and return an object.
      Parameters:
      r - an object providing the code to execute in a method named doit() that will store its return value in r.obj
      Returns:
      an object
    • getProperty

      public Object getProperty(Object key)
      Gets the properties associated with the document.
      Specified by:
      getProperty in interface Document
      Parameters:
      key - a non-null property key
      Returns:
      the properties
      See Also:
    • putProperty

      public void putProperty(Object key, Object value)
      Associates a property with the document. Two standard property keys provided are: StreamDescriptionProperty and TitleProperty. Other properties, such as author, may also be defined.
      Specified by:
      putProperty in interface Document
      Parameters:
      key - the non-null property key
      value - the property value
      See Also:
    • doitVoidBLE

      protected void doitVoidBLE(SafeDocument.RunnableWithBadLocException r) throws BadLocationException
      Perform an operation on the event dispatch thread, possibly throwing a BadLocationException.
      Parameters:
      r - an object whose doitBLE() method provides the code to execute
      Throws:
      BadLocationException - a BadLocationException occurred
    • remove

      public void remove(int offs, int len) throws BadLocationException
      Removes a portion of the content of the document. This will cause a DocumentEvent of type DocumentEvent.EventType.REMOVE to be sent to the registered DocumentListeners, unless an exception is thrown. The notification will be sent to the listeners by calling the removeUpdate method on the DocumentListeners.

      To ensure reasonable behavior in the face of concurrency, the event is dispatched after the mutation has occurred. This means that by the time a notification of removal is dispatched, the document has already been updated and any marks created by createPosition have already changed. For a removal, the end of the removal range is collapsed down to the start of the range, and any marks in the removal range are collapsed down to the start of the range.

      Diagram shows removal of 'quick' from 'The quick brown fox.'

      If the Document structure changed as result of the removal, the details of what Elements were inserted and removed in response to the change will also be contained in the generated DocumentEvent. It is up to the implementation of a Document to decide how the structure should change in response to a remove.

      If the Document supports undo/redo, an UndoableEditEvent will also be generated.

      Specified by:
      remove in interface Document
      Parameters:
      offs - the offset from the beginning >= 0
      len - the number of characters to remove >= 0
      Throws:
      BadLocationException - some portion of the removal range was not a valid part of the document. The location in the exception is the first bad position encountered.
      See Also:
    • insertString

      public void insertString(int offset, String str, AttributeSet a) throws BadLocationException
      Inserts a string of content. This will cause a DocumentEvent of type DocumentEvent.EventType.INSERT to be sent to the registered DocumentListeners, unless an exception is thrown. The DocumentEvent will be delivered by calling the insertUpdate method on the DocumentListener. The offset and length of the generated DocumentEvent will indicate what change was actually made to the Document.

      Diagram shows insertion of 'quick' in 'The quick brown fox'

      If the Document structure changed as result of the insertion, the details of what Elements were inserted and removed in response to the change will also be contained in the generated DocumentEvent. It is up to the implementation of a Document to decide how the structure should change in response to an insertion.

      If the Document supports undo/redo, an UndoableEditEvent will also be generated.

      Specified by:
      insertString in interface Document
      Parameters:
      offset - the offset into the document to insert the content >= 0 . All positions that track change at or after the given location will move.
      str - the string to insert
      a - the attributes to associate with the inserted content. This may be null if there are no attributes.
      Throws:
      BadLocationException - the given insert position is not a valid position within the document
      See Also:
    • doitStringBLE

      protected String doitStringBLE(org.bzdev.swing.text.SafeDocument.RunnableWithString r) throws BadLocationException
      Perform an operation on the event dispatch thread returning a String, possibly throwing a BadLocationException.
      Parameters:
      r - an object whose doitBLE() method provides the code to execute with the return value stored in r.string
      Returns:
      a string
      Throws:
      BadLocationException - a BadLocationException occurred
    • getText

      public String getText(int offset, int length) throws BadLocationException
      Fetches the text contained within the given portion of the document.
      Specified by:
      getText in interface Document
      Parameters:
      offset - the offset into the document representing the desired start of the text >= 0
      length - the length of the desired string >= 0
      Returns:
      the text, in a String of length >= 0
      Throws:
      BadLocationException - some portion of the given range was not a valid part of the document. The location in the exception is the first bad position encountered.
    • getText

      public void getText(int offset, int length, Segment txt) throws BadLocationException
      Fetches the text contained within the given portion of the document.

      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 someting with text
             nleft -= text.count;
             offs += text.count;
         }
      
       
      Specified by:
      getText in interface Document
      Parameters:
      offset - the offset into the document representing the desired start of the text >= 0
      length - the length of the desired string >= 0
      txt - the Segment object to return the text in
      Throws:
      BadLocationException - Some portion of the given range was not a valid part of the document. The location in the exception is the first bad position encountered.
    • doitPosition

      protected Position doitPosition(org.bzdev.swing.text.SafeDocument.RunnableWithPosition r)
      Execute an operation on the event dispatch thread and return a Position.
      Parameters:
      r - an object whose doitBLE() method provides the code to execute and that will store a return value in r.position
      Returns:
      the position
    • getStartPosition

      public Position getStartPosition()
      Returns a position that represents the start of the document. The position returned can be counted on to track change and stay located at the beginning of the document.
      Specified by:
      getStartPosition in interface Document
      Returns:
      the position
    • getEndPosition

      public Position getEndPosition()
      Returns a position that represents the end of the document. The position returned can be counted on to track change and stay located at the end of the document.
      Specified by:
      getEndPosition in interface Document
      Returns:
      the position
    • doitPositionBLE

      protected Position doitPositionBLE(org.bzdev.swing.text.SafeDocument.RunnableWithPositionBLE r) throws BadLocationException
      Execute a task on the event dispatch thread, returning a position, throwing any BadLocationException that occurs.
      Parameters:
      r - an object whose doitBLE() method provides the code to execute and that will store its return value in r.position
      Returns:
      the position
      Throws:
      BadLocationException - a BadLocationException occurred
    • createPosition

      public Position createPosition(int offs) throws BadLocationException
      This method allows an application to mark a place in a sequence of character content. This mark can then be used to tracks change as insertions and removals are made in the content. The policy is that insertions always occur prior to the current position (the most common case) unless the insertion location is zero, in which case the insertion is forced to a position that follows the original position.
      Specified by:
      createPosition in interface Document
      Parameters:
      offs - the offset from the start of the document >= 0
      Returns:
      the position
      Throws:
      BadLocationException - if the given position does not represent a valid location in the associated document
    • doitElements

      protected Element[] doitElements(org.bzdev.swing.text.SafeDocument.RunnableWithElements r)
      Execute a task on the event dispatch thread, returning an array of Element.
      Parameters:
      r - an object whose doit() method provides the code to execute and that will store the element array it computes in r.elements
      Returns:
      the elements computed
    • getRootElements

      public Element[] getRootElements()
      Returns all of the root elements that are defined.

      Typically there will be only one document structure, but the interface supports building an arbitrary number of structural projections over the text data. The document can have multiple root elements to support multiple document structures. Some examples might be:

      • Text direction.
      • Lexical token streams.
      • Parse trees.
      • Conversions to formats other than the native format.
      • Modification specifications.
      • Annotations.
      Specified by:
      getRootElements in interface Document
      Returns:
      the root element
    • doitElement

      protected Element doitElement(org.bzdev.swing.text.SafeDocument.RunnableWithElement r)
      Execute a task on the event dispatch thread, returning a Element.
      Parameters:
      r - an object whose doit() method provides the code to execute and that will store the element it computes in r.element
      Returns:
      the element computed
    • getDefaultRootElement

      public Element getDefaultRootElement()
      Returns the root element that views should be based upon, unless some other mechanism for assigning views to element structures is provided.
      Specified by:
      getDefaultRootElement in interface Document
      Returns:
      the root element
    • render

      public void render(Runnable runnable)
      Allows the model to be safely rendered in the presence of concurrency, if the model supports being updated asynchronously. The given runnable will be executed in a way that allows it to safely read the model with no changes while the runnable is being executed. The runnable itself may not make any mutations.
      Specified by:
      render in interface Document
      Parameters:
      runnable - a Runnable used to render the model