Author: rwhitcomb
Date: Tue Sep 24 19:38:26 2013
New Revision: 1525982

URL: http://svn.apache.org/r1525982
Log:
Optimization for TextPane:  only notify the TextPaneCharacterListener once per
bulk operation (like a cut or paste) instead of once per node that changes.
This is nice for auxiliary processing (like syntax colorizing) that really
only needs to know the whole range that has been affected.  And there should
be no downside to the change (since the skins use the lower-level interfaces
anyway, which are not affected).

Modified:
    pivot/trunk/wtk/src/org/apache/pivot/wtk/TextPane.java

Modified: pivot/trunk/wtk/src/org/apache/pivot/wtk/TextPane.java
URL: 
http://svn.apache.org/viewvc/pivot/trunk/wtk/src/org/apache/pivot/wtk/TextPane.java?rev=1525982&r1=1525981&r2=1525982&view=diff
==============================================================================
--- pivot/trunk/wtk/src/org/apache/pivot/wtk/TextPane.java (original)
+++ pivot/trunk/wtk/src/org/apache/pivot/wtk/TextPane.java Tue Sep 24 19:38:26 
2013
@@ -210,6 +210,7 @@ public class TextPane extends Container 
 
     private boolean editable = true;
     private boolean undoingHistory = false;
+    private boolean bulkOperation = false;
 
     private ComponentNodeListener componentNodeListener = new 
ComponentNodeListener() {
         @Override
@@ -235,7 +236,9 @@ public class TextPane extends Container 
                 addHistoryItem(new RangeInsertedEdit(node, offset, 
characterCount));
             }
 
-            textPaneCharacterListeners.charactersInserted(TextPane.this, 
offset, characterCount);
+            if (!bulkOperation) {
+                textPaneCharacterListeners.charactersInserted(TextPane.this, 
offset, characterCount);
+            }
         }
 
         @Override
@@ -283,7 +286,9 @@ public class TextPane extends Container 
                 }
             }
 
-            textPaneCharacterListeners.charactersRemoved(TextPane.this, 
offset, characterCount);
+            if (!bulkOperation) {
+                textPaneCharacterListeners.charactersRemoved(TextPane.this, 
offset, characterCount);
+            }
         }
     };
 
@@ -383,6 +388,20 @@ public class TextPane extends Container 
         return element;
     }
 
+    /**
+     * Helper function to remove a range of characters from the document
+     * and notify the listeners just once (instead of once per node).
+     */
+    private Node removeDocumentRange(int start, int count) {
+        bulkOperation = true;
+        Node node = document.removeRange(start, count);
+        bulkOperation = false;
+
+        textPaneCharacterListeners.charactersRemoved(this, start, count);
+
+        return node;
+    }
+
     public void insert(char character) {
         // TODO Don't make every character undoable; break at word boundaries?
 
@@ -457,7 +476,7 @@ public class TextPane extends Container 
         }
 
         if (selectionLength > 0) {
-            document.removeRange(selectionStart, selectionLength);
+            removeDocumentRange(selectionStart, selectionLength);
         }
 
         // TODO If the caret is placed in the middle of a text node, split it;
@@ -475,7 +494,7 @@ public class TextPane extends Container 
         }
 
         if (selectionLength > 0) {
-            document.removeRange(selectionStart, selectionLength);
+            removeDocumentRange(selectionStart, selectionLength);
         }
 
         // Walk up the tree until we find a paragraph
@@ -550,7 +569,7 @@ public class TextPane extends Container 
                     paragraph.insertRange(nextParagraph, 
paragraph.getCharacterCount() - 1);
                 }
             } else {
-                document.removeRange(offset, characterCount);
+                removeDocumentRange(offset, characterCount);
             }
         }
 
@@ -573,7 +592,7 @@ public class TextPane extends Container 
 
         if (selectionLength > 0) {
             // Copy selection to clipboard
-            Document selection = 
(Document)document.removeRange(selectionStart, selectionLength);
+            Document selection = (Document)removeDocumentRange(selectionStart, 
selectionLength);
 
             String selectedText = null;
             try {
@@ -646,7 +665,12 @@ public class TextPane extends Container 
                     documentLocal = serializer.readObject(reader);
                     n = documentLocal.getCharacterCount();
 
-                    this.document.insertRange(documentLocal, selectionStart);
+                    bulkOperation = true;
+                    int start = selectionStart;
+                    this.document.insertRange(documentLocal, start);
+                    bulkOperation = false;
+
+                    textPaneCharacterListeners.charactersInserted(this, start, 
n);
                 } catch(IOException exception) {
                     throw new RuntimeException(exception);
                 }


Reply via email to