The current BasicTableUI.java.paint is written such as if the cells may have arbitrary dimensions and occupy arbitrary place on the table. During painting, this assumption forces to call the JTable.getCellRect for every cell. As JTable.getCellRect contains the loop inside, this finally slows painting significantly.

This can be done much faster supposing that all cells have the same height and that all cells belonging to the same column have the same width. Then the location of the adjacent cell is obvious and there is no need to obtain it via JTable.getCellRect.

2006-02-17  Audrius Meskauskas  <[EMAIL PROTECTED]>

   * javax/swing/JTable.java (getCellRect): return +rowMargin if spacing
   is included. (moveToCellBeingEdited): Adjusted to start editing at the
   same location where was the initial text.
   * javax/swing/plaf/basic/BasicTableUI.java (paint): Rewritten.
Index: javax/swing/JTable.java
===================================================================
RCS file: /sources/classpath/classpath/javax/swing/JTable.java,v
retrieving revision 1.80
diff -u -r1.80 JTable.java
--- javax/swing/JTable.java	17 Feb 2006 12:02:37 -0000	1.80
+++ javax/swing/JTable.java	17 Feb 2006 15:38:33 -0000
@@ -1255,7 +1255,7 @@
       {
         setBorder(null);
       }
-      
+    
       /**
        * Scroll the table, making the given rectangle of this component
        * visible. Mind the component position with relate to the table. 
@@ -2022,9 +2022,9 @@
       x += columnModel.getColumn(i).getWidth();
 
     if (includeSpacing)
-      rectCache.setBounds(x, y, width, height);
+      rectCache.setBounds(x, y, width, height +y_gap);
     else
-      rectCache.setBounds(x, y, width - x_gap, height - y_gap);
+      rectCache.setBounds(x, y, width - x_gap, height);
     return rectCache;
   }
 
@@ -3660,9 +3660,14 @@
      Rectangle r = getCellRect(editingRow, editingColumn, true);
      // Place the text field so that it would not touch the table
      // border.
-     r.width--;
-     r.height--;
-
+     
+     // TODO Figure out while 5 and which constant should here be.
+     int xOffset = 5;
+     r.x+=xOffset;
+     r.y++;
+     r.width -=xOffset;
+     r.height --;
+     
      // Clone rectangle as getCellRect returns the cached value.
      component.setBounds(new Rectangle(r));
   }
Index: javax/swing/plaf/basic/BasicTableUI.java
===================================================================
RCS file: /sources/classpath/classpath/javax/swing/plaf/basic/BasicTableUI.java,v
retrieving revision 1.43
diff -u -r1.43 BasicTableUI.java
--- javax/swing/plaf/basic/BasicTableUI.java	15 Feb 2006 10:27:01 -0000	1.43
+++ javax/swing/plaf/basic/BasicTableUI.java	17 Feb 2006 15:38:38 -0000
@@ -76,6 +76,7 @@
 import javax.swing.plaf.TableUI;
 import javax.swing.table.TableCellEditor;
 import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumnModel;
 import javax.swing.table.TableModel;
 
 public class BasicTableUI extends TableUI
@@ -1218,6 +1219,9 @@
     rendererPane.paintComponent(g, comp, table, bounds);
   }
   
+  /**
+   * Paint the associated table.
+   */
   public void paint(Graphics gfx, JComponent ignored) 
   {
     int ncols = table.getColumnCount();
@@ -1243,28 +1247,55 @@
     if (rn == -1)
       rn = table.getRowCount() - 1;
 
-    Rectangle bounds;
+    TableColumnModel cmodel = table.getColumnModel();
+    int [] widths = new int[cn+1];
+    for (int i = c0; i <=cn ; i++)
+      {
+        widths[i] = cmodel.getColumn(i).getWidth();
+      }
+    
+    Rectangle bounds = table.getCellRect(r0, c0, false);
+    bounds.height = table.getRowHeight()+table.getRowMargin();
+    
+    // The left boundary of the area being repainted.
+    int left = bounds.x;
+    
+    // The top boundary of the area being repainted.
+    int top = bounds.y;
+    
+    // The bottom boundary of the area being repainted.
+    int bottom;
+    
+    // The cell height.
+    int height = bounds.height;
+    
     // paint the cell contents
     Color grid = table.getGridColor();    
-    for (int c = c0; c <= cn; ++c)
+    for (int r = r0; r <= rn; ++r)
       {
-        for (int r = r0; r <= rn; ++r)
+        for (int c = c0; c <= cn; ++c)
           {
-            bounds = table.getCellRect(r, c, false);
+            bounds.width = widths[c];
             paintCell(gfx, r, c, bounds, table.getCellRenderer(r, c));
+            bounds.x += widths[c];
           }
+        bounds.y += height;
+        bounds.x = left;
       }
+    
+    bottom = bounds.y;
 
     // paint vertical grid lines
     if (grid != null && table.getShowVerticalLines())
       {    
         Color save = gfx.getColor();
         gfx.setColor(grid);
-        for (int c = c0; c < cn; ++c)
+        int x = left;
+        
+        for (int c = c0; c <= cn; ++c)
           {
-            bounds = table.getCellRect(0, c, true);
-            gfx.drawLine(bounds.x + bounds.width - 1, p1.y,
-                         bounds.x + bounds.width - 1, p2.y);
+            gfx.drawLine(x, top, x, bottom);
+            x += widths[c];
           }
         gfx.setColor(save);
       }
@@ -1274,11 +1305,11 @@
       {    
         Color save = gfx.getColor();
         gfx.setColor(grid);
-        for (int r = r0; r < rn; ++r)
+        int y = top;
+        for (int r = r0; r <= rn; ++r)
           {
-            bounds = table.getCellRect(r, 0, true);
-            gfx.drawLine(p1.x, bounds.y + bounds.height - 1,
-                         p2.x, bounds.y + bounds.height - 1);
+            gfx.drawLine(left, y, p2.x, y);
+            y += height;
           }
         gfx.setColor(save);
       }

Reply via email to