Class MultiChangeBuilder<PS,​SEG,​S>


  • public class MultiChangeBuilder<PS,​SEG,​S>
    extends Object
    Constructs a list of Replacements that are used to update an EditableStyledDocument in one call via commit(). Note: this builder cannot be reused and a new one must be created for each multi-change.

    Relative vs Absolute Changes

    Let's say that a document has the text |(|t|e|x|t||)| where each | represents a position in-between the characters of the text . If one wants to remove the opening and closing parenthesis in two update calls, they would write:

    
     // Text:     |(|t|e|x|t|)|
     // Position: 0 1 2 3 4 5 6
     area.deleteText(0, 1); // delete the first parenthesis
    
     // now the second parenthesis is positioned in a different spot than before
     // Text:     |t|e|x|t|)|
     // Position: 0 1 2 3 4 5
     area.deleteText(4, 5); // delete the second parenthesis
     

    MultiChangeBuilder can do the same thing in one call and works by applying earlier changes before later ones. However, this creates a problem. Later changes' start and end positions must be updated to still point to the correct spot in the text. Wouldn't it be easier to be able to define both changes in the original coordinate system of the document before any changes were applied? Returning to the previous example, wouldn't it be better if one could write:

    
     // Text:     |(|t|e|x|t|)|
     // Position: 0 1 2 3 4 5 6
    
     // start multi change
     area.deleteText(0, 1); // delete the 1st parenthesis
     area.deleteText(5, 6); // delete the 2nd parenthesis
     // end multi change
     

    Fortunately, that is already handled for you. Such changes are known as "relative" changes: their start and end positions are updated to point to where they should point once all the earlier changes before them have been applied. To execute the same code as before, we would write:

    
     area.createMultiChange()
          // deletes the 1st parenthesis
          .deleteText(0, 1)
    
          // internally updates this to delete(4, 5), so that it deletes the 2nd parenthesis
          .deleteText(5, 6)
    
          // executes the call and updates the document
          .commit();
     

    However, a developer may sometimes want an "absolute" change: their start and end positions are exactly what the developer specifies regardless of how changes before them modify the underlying document. For example, the following code would still delete both parenthesis:

    
     area.createMultiChange()
          .deleteText(0, 1) // deletes the 1st parenthesis
          .deleteTextAbsolutely(4, 5) // deletes the 2nd parenthesis
          .commit();
     

    Thus, absolute changes (e.g. replaceAbsolutely(int, int, StyledDocument)) are all the methods which have "absolute" as a suffix and relative changes (e.g. replace(int, int, StyledDocument)) do not. To make things easier for the developer, the methods declared here are similar to those declared in EditActions, minus a few (e.g. EditActions.append(StyledDocument)).

    Other Considerations

    • Warning: relative changes will not be updated if one starts a multi-change and fails to commit those changes before updating the area's underlying document in a GenericStyledArea.replace(int, int, StyledDocument) call.
    • The builder does not optimize performance in cases where the developer adds a later change that makes an earlier change obsolete. For example,
      
       // This code...
       area.createMultiChange(4)
           .replaceText(0, 1, "a")
           .replaceTextAbsolutely(0, 1, "b")
           .replaceTextAbsolutely(0, 1, "c")
           .replaceTextAbsolutely(0, 1, "d")
           .commit();
      
       // ...could be optimized to...
       area.createMultiChange(2)
           .replaceText(0, 1, "a")
           // .replaceTextAbsolutely(0, 1, "b") // superseded by next change
           // .replaceTextAbsolutely(0, 1, "c") // superseded by next change
           .replaceTextAbsolutely(0, 1, "d")
           .commit();
       // ...as it would reduce the number of updates by two and not create all the other objects
       // associated with an update (e.g. RichTextChange, PlainTextChange, etc.).
       
    • Method Detail

      • insertText

        public MultiChangeBuilder<PS,​SEG,​S> insertText​(int position,
                                                                   String text)
        Inserts the given text at the given position.
        Parameters:
        position - The position to insert the text.
        text - The text to insert.
      • insertTextAbsolutely

        public MultiChangeBuilder<PS,​SEG,​S> insertTextAbsolutely​(int position,
                                                                             String text)
        Inserts the given text at the given position.
        Parameters:
        position - The position to insert the text.
        text - The text to insert.
      • insertText

        public MultiChangeBuilder<PS,​SEG,​S> insertText​(int paragraphIndex,
                                                                   int columnPosition,
                                                                   String text)
        Inserts the given text at the position returned from getAbsolutePosition(paragraphIndex, columnPosition).

        Caution: see StyledDocument.getAbsolutePosition(int, int) to know how the column index argument can affect the returned position.

        Parameters:
        text - The text to insert
      • insertTextAbsolutely

        public MultiChangeBuilder<PS,​SEG,​S> insertTextAbsolutely​(int paragraphIndex,
                                                                             int columnPosition,
                                                                             String text)
        Inserts the given text at the position returned from getAbsolutePosition(paragraphIndex, columnPosition).

        Caution: see StyledDocument.getAbsolutePosition(int, int) to know how the column index argument can affect the returned position.

        Parameters:
        text - The text to insert
      • insert

        public MultiChangeBuilder<PS,​SEG,​S> insert​(int position,
                                                               StyledDocument<PS,​SEG,​S> document)
        Inserts the given rich-text content at the given position.
        Parameters:
        position - The position to insert the text.
        document - The rich-text content to insert.
      • insertAbsolutely

        public MultiChangeBuilder<PS,​SEG,​S> insertAbsolutely​(int position,
                                                                         StyledDocument<PS,​SEG,​S> document)
        Inserts the given rich-text content at the given position.
        Parameters:
        position - The position to insert the text.
        document - The rich-text content to insert.
      • insert

        public MultiChangeBuilder<PS,​SEG,​S> insert​(int paragraphIndex,
                                                               int columnPosition,
                                                               StyledDocument<PS,​SEG,​S> document)
        Inserts the given rich-text content at the position returned from getAbsolutePosition(paragraphIndex, columnPosition).

        Caution: see StyledDocument.getAbsolutePosition(int, int) to know how the column index argument can affect the returned position.

        Parameters:
        document - The rich-text content to insert.
      • insertAbsolutely

        public MultiChangeBuilder<PS,​SEG,​S> insertAbsolutely​(int paragraphIndex,
                                                                         int columnPosition,
                                                                         StyledDocument<PS,​SEG,​S> document)
        Inserts the given rich-text content at the position returned from getAbsolutePosition(paragraphIndex, columnPosition).

        Caution: see StyledDocument.getAbsolutePosition(int, int) to know how the column index argument can affect the returned position.

        Parameters:
        document - The rich-text content to insert.
      • deleteText

        public MultiChangeBuilder<PS,​SEG,​S> deleteText​(IndexRange range)
        Removes a range of text.
        Parameters:
        range - The range of text to delete. It must not be null. Its start and end values specify the start and end positions within the area.
        See Also:
        deleteText(int, int)
      • deleteTextAbsolutely

        public MultiChangeBuilder<PS,​SEG,​S> deleteTextAbsolutely​(IndexRange range)
        Removes a range of text.
        Parameters:
        range - The range of text to delete. It must not be null. Its start and end values specify the start and end positions within the area.
        See Also:
        deleteText(int, int)
      • deleteText

        public MultiChangeBuilder<PS,​SEG,​S> deleteText​(int start,
                                                                   int end)
        Removes a range of text. It must hold 0 <= start <= end <= getLength().
        Parameters:
        start - Start position of the range to remove
        end - End position of the range to remove
      • deleteTextAbsolutely

        public MultiChangeBuilder<PS,​SEG,​S> deleteTextAbsolutely​(int start,
                                                                             int end)
        Removes a range of text. It must hold 0 <= start <= end <= getLength().
        Parameters:
        start - Start position of the range to remove
        end - End position of the range to remove
      • deleteText

        public MultiChangeBuilder<PS,​SEG,​S> deleteText​(int startParagraph,
                                                                   int startColumn,
                                                                   int endParagraph,
                                                                   int endColumn)
        Removes a range of text. It must hold 0 <= start <= end <= getLength() where start = getAbsolutePosition(startParagraph, startColumn); and is inclusive, and int end = getAbsolutePosition(endParagraph, endColumn); and is exclusive.

        Caution: see StyledDocument.getAbsolutePosition(int, int) to know how the column index argument can affect the returned position.

      • deleteTextAbsolutely

        public MultiChangeBuilder<PS,​SEG,​S> deleteTextAbsolutely​(int startParagraph,
                                                                             int startColumn,
                                                                             int endParagraph,
                                                                             int endColumn)
        Removes a range of text. It must hold 0 <= start <= end <= getLength() where start = getAbsolutePosition(startParagraph, startColumn); and is inclusive, and int end = getAbsolutePosition(endParagraph, endColumn); and is exclusive.

        Caution: see StyledDocument.getAbsolutePosition(int, int) to know how the column index argument can affect the returned position.

      • replaceText

        public MultiChangeBuilder<PS,​SEG,​S> replaceText​(int start,
                                                                    int end,
                                                                    String text)
        Replaces a range of characters with the given text. It must hold 0 <= start <= end <= getLength().
        Parameters:
        start - Start index of the range to replace, inclusive.
        end - End index of the range to replace, exclusive.
        text - The text to put in place of the deleted range. It must not be null.
      • replaceTextAbsolutely

        public MultiChangeBuilder<PS,​SEG,​S> replaceTextAbsolutely​(int start,
                                                                              int end,
                                                                              String text)
        Replaces a range of characters with the given text. It must hold 0 <= start <= end <= getLength().
        Parameters:
        start - Start index of the range to replace, inclusive.
        end - End index of the range to replace, exclusive.
        text - The text to put in place of the deleted range. It must not be null.
      • commit

        public final void commit()
        Applies all the changes stored in this object to the underlying document of the area. Note: this builder cannot be reused and a new one must be created for each multi-change.
      • hasChanges

        public boolean hasChanges()