This optimizes PlainView to only paint the lines that are necessary, wrt to the current clip and allocation. This makes JTextArea more snappy with scrolling. I tested this by copy+pasting Component.java into a JTextArea (which has around 7000 lines) and once it got around to parse all the (which takes a while naturally) the actual scrolling/painting is pretty damn fast. :-D

2006-08-13  Roman Kennke  <[EMAIL PROTECTED]>

        PR 28028
        * javax/swing/text/PlainView.java
        (paint): Limit painted area to the lines inside the clip
        and allocation.

/Roman
Index: javax/swing/text/PlainView.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/PlainView.java,v
retrieving revision 1.46
diff -u -1 -2 -r1.46 PlainView.java
--- javax/swing/text/PlainView.java	11 Aug 2006 12:06:59 -0000	1.46
+++ javax/swing/text/PlainView.java	13 Aug 2006 15:15:48 -0000
@@ -271,37 +271,45 @@
     selectedColor = textComponent.getSelectedTextColor();
     unselectedColor = textComponent.getForeground();
     disabledColor = textComponent.getDisabledTextColor();
     selectionStart = textComponent.getSelectionStart();
     selectionEnd = textComponent.getSelectionEnd();
 
     Rectangle rect = s instanceof Rectangle ? (Rectangle) s : s.getBounds();
     tabBase = rect.x;
 
     // FIXME: Text may be scrolled.
     Document document = textComponent.getDocument();
     Element root = getElement();
-    int y = rect.y + metrics.getAscent();
     int height = metrics.getHeight();
 
     // For layered highlighters we need to paint the layered highlights
     // before painting any text.
     LayeredHighlighter hl = null;
     Highlighter h = textComponent.getHighlighter();
     if (h instanceof LayeredHighlighter)
       hl = (LayeredHighlighter) h;
 
     int count = root.getElementCount();
 
-    for (int i = 0; i < count; i++)
+    // Determine first and last line inside the clip.
+    Rectangle clip = g.getClipBounds();
+//    SwingUtilities.computeIntersection(rect.x, rect.y, rect.width, rect.height,
+//                                       clip);
+    int line0 = (clip.y - rect.y) / height;
+    line0 = Math.max(0, Math.min(line0, count - 1));
+    int line1 = (clip.y + clip.height - rect.y) / height;
+    line1 = Math.max(0, Math.min(line1, count - 1));
+    int y = rect.y + metrics.getAscent() + height * line0;
+    for (int i = line0; i <= line1; i++)
       {
         if (hl != null)
           {
             Element lineEl = root.getElement(i);
             // Exclude the trailing newline from beeing highlighted.
             if (i == count)
               hl.paintLayeredHighlights(g, lineEl.getStartOffset(),
                                         lineEl.getEndOffset(), s, textComponent,
                                         this);
             else
               hl.paintLayeredHighlights(g, lineEl.getStartOffset(),
                                         lineEl.getEndOffset() - 1, s,

Reply via email to