OSDN Git Service

2006-08-14 Mark Wielaard <mark@klomp.org>
[pf3gnuchains/gcc-fork.git] / libjava / classpath / javax / swing / JTable.java
index 8555308..5c7bff5 100644 (file)
@@ -2922,56 +2922,189 @@ public class JTable
   {
     // update the column model from the table model if the structure has
     // changed and the flag autoCreateColumnsFromModel is set
-    if ((event == null || (event.getFirstRow() == TableModelEvent.HEADER_ROW))
-       && autoCreateColumnsFromModel)
+    if (event == null || (event.getFirstRow() == TableModelEvent.HEADER_ROW))
+      handleCompleteChange(event);
+    else if (event.getType() == TableModelEvent.INSERT)
+      handleInsert(event);
+    else if (event.getType() == TableModelEvent.DELETE)
+      handleDelete(event);
+    else
+      handleUpdate(event);
+  }
+
+  /**
+   * Handles a request for complete relayout. This is the case when
+   * event.getFirstRow() == TableModelEvent.HEADER_ROW.
+   *
+   * @param ev the table model event
+   */
+  private void handleCompleteChange(TableModelEvent ev)
+  {
+    clearSelection();
+    checkSelection();
+    rowHeights = null;
+    if (getAutoCreateColumnsFromModel())
+      createDefaultColumnsFromModel();
+    else
+      resizeAndRepaint();
+  }
+
+  /**
+   * Handles table model insertions.
+   *
+   * @param ev the table model event
+   */
+  private void handleInsert(TableModelEvent ev)
+  {
+    // Sync selection model with data model.
+    int first = ev.getFirstRow();
+    if (first < 0)
+      first = 0;
+    int last = ev.getLastRow();
+    if (last < 0)
+      last = getRowCount() - 1;
+    selectionModel.insertIndexInterval(first, last - first + 1, true);
+    checkSelection();
+
+    // For variable height rows we must update the SizeSequence thing.
+    if (rowHeights != null)
       {
-        rowHeights = null;
-        if (getAutoCreateColumnsFromModel())
-          createDefaultColumnsFromModel();
-        resizeAndRepaint();
-        return;
+        rowHeights.insertEntries(first, last - first + 1, rowHeight);
+        // TODO: We repaint the whole thing when the rows have variable
+        // heights. We might want to handle this better though.
+        repaint();
+      }
+    else
+      {
+        // Repaint the dirty region and revalidate.
+        int rowHeight = getRowHeight();
+        Rectangle dirty = new Rectangle(0, first * rowHeight,
+                                        getColumnModel().getTotalColumnWidth(),
+                                        (getRowCount() - first) * rowHeight);
+        repaint(dirty);
+      }
+    revalidate();
+  }
+
+  /**
+   * Handles table model deletions.
+   *
+   * @param ev the table model event
+   */
+  private void handleDelete(TableModelEvent ev)
+  {
+    // Sync selection model with data model.
+    int first = ev.getFirstRow();
+    if (first < 0)
+      first = 0;
+    int last = ev.getLastRow();
+    if (last < 0)
+      last = getRowCount() - 1;
+
+    selectionModel.removeIndexInterval(first, last);
+
+    checkSelection();
+
+    if (dataModel.getRowCount() == 0)
+      clearSelection();
+
+    // For variable height rows we must update the SizeSequence thing.
+    if (rowHeights != null)
+      {
+        rowHeights.removeEntries(first, last - first + 1);
+        // TODO: We repaint the whole thing when the rows have variable
+        // heights. We might want to handle this better though.
+        repaint();
+      }
+    else
+      {
+        // Repaint the dirty region and revalidate.
+        int rowHeight = getRowHeight();
+        int oldRowCount = getRowCount() + last - first + 1;
+        Rectangle dirty = new Rectangle(0, first * rowHeight,
+                                        getColumnModel().getTotalColumnWidth(),
+                                        (oldRowCount - first) * rowHeight);
+        repaint(dirty);
       }
+    revalidate();
+  }
 
-    // If the structure changes, we need to revalidate, since that might
-    // affect the size parameters of the JTable. Otherwise we only need
-    // to perform a repaint to update the view.
-    if (event == null || event.getType() == TableModelEvent.INSERT)
+  /**
+   * Handles table model updates without structural changes.
+   *
+   * @param ev the table model event
+   */
+  private void handleUpdate(TableModelEvent ev)
+  {
+    if (rowHeights == null)
       {
-        // Sync selection model with data model.
-        if (event != null)
+        // Some cells have been changed without changing the structure.
+        // Figure out the dirty rectangle and repaint.
+        int firstRow = ev.getFirstRow();
+        int lastRow = ev.getLastRow();
+        int col = ev.getColumn();
+        Rectangle dirty;
+        if (col == TableModelEvent.ALL_COLUMNS)
           {
-            int first = event.getFirstRow();
-            if (first < 0)
-              first = 0;
-            int last = event.getLastRow();
-            if (last < 0)
-              last = getRowCount() - 1;
-            selectionModel.insertIndexInterval(first, last - first + 1, true);
-            if (rowHeights != null)
-              rowHeights.insertEntries(first, last - first + 1, rowHeight);
+            // All columns changed. 
+            dirty = new Rectangle(0, firstRow * getRowHeight(),
+                                  getColumnModel().getTotalColumnWidth(), 0);
           }
-        revalidate();
+        else
+          {
+            // Only one cell or column of cells changed.
+            // We need to convert to view column first.
+            int column = convertColumnIndexToModel(col);
+            dirty = getCellRect(firstRow, column, false);
+          }
+
+        // Now adjust the height of the dirty region.
+        dirty.height = (lastRow + 1) * getRowHeight();
+        // .. and repaint.
+        repaint(dirty);
       }
-    if (event == null || event.getType() == TableModelEvent.DELETE)
+    else
       {
-        // Sync selection model with data model.
-        if (event != null)
+        // TODO: We repaint the whole thing when the rows have variable
+        // heights. We might want to handle this better though.
+        repaint();
+      }
+  }
+
+  /**
+   * Helper method for adjusting the lead and anchor indices when the
+   * table structure changed. This sets the lead and anchor to -1 if there's
+   * no more rows, or set them to 0 when they were at -1 and there are actually
+   * some rows now.
+   */
+  private void checkSelection()
+  {
+    TableModel m = getModel();
+    ListSelectionModel sm = selectionModel;
+    if (m != null)
+      {
+        int lead = sm.getLeadSelectionIndex();
+        int c = m.getRowCount();
+        if (c == 0 && lead != -1)
+          {
+            // No rows in the model, reset lead and anchor to -1.
+            sm.setValueIsAdjusting(true);
+            sm.setAnchorSelectionIndex(-1);
+            sm.setLeadSelectionIndex(-1);
+            sm.setValueIsAdjusting(false);
+          }
+        else if (c != 0 && lead == -1)
           {
-            int first = event.getFirstRow();
-            if (first < 0)
-              first = 0;
-            int last = event.getLastRow();
-            if (last < 0)
-              last = getRowCount() - 1;
-            selectionModel.removeIndexInterval(first, last);
-            if (rowHeights != null)
-              rowHeights.removeEntries(first, last - first + 1);
+            // We have rows, but no lead/anchor. Set them to 0. We
+            // do a little trick here so that the actual selection is not
+            // touched.
+            if (sm.isSelectedIndex(0))
+              sm.addSelectionInterval(0, 0);
+            else
+              sm.removeSelectionInterval(0, 0);
           }
-        if (dataModel.getRowCount() == 0)
-          clearSelection();
-        revalidate();
+        // Nothing to do in the other cases.
       }
-    repaint();
   }
 
   /**
@@ -3468,6 +3601,8 @@ public class JTable
    * Get the value of the {@link #rowSelectionAllowed} property.
    *
    * @return The current value of the property
+   * 
+   * @see #setRowSelectionAllowed(boolean)
    */
   public boolean getRowSelectionAllowed()
   {
@@ -3621,6 +3756,8 @@ public class JTable
    * Get the value of the <code>columnSelectionAllowed</code> property.
    *
    * @return The current value of the columnSelectionAllowed property
+   * 
+   * @see #setColumnSelectionAllowed(boolean)
    */
   public boolean getColumnSelectionAllowed()
   {
@@ -3874,11 +4011,17 @@ public class JTable
    * Set the value of the {@link #rowSelectionAllowed} property.
    *
    * @param r The new value of the rowSelectionAllowed property
+   * 
+   * @see #getRowSelectionAllowed()
    */ 
   public void setRowSelectionAllowed(boolean r)
   {
-    rowSelectionAllowed = r;
-    repaint();
+    if (rowSelectionAllowed != r) 
+      {
+        rowSelectionAllowed = r;
+        firePropertyChange("rowSelectionAllowed", !r, r);
+        repaint();
+      }
   }
 
   /**
@@ -3988,11 +4131,17 @@ public class JTable
    * Set the value of the <code>columnSelectionAllowed</code> property.
    *
    * @param c The new value of the property
+   * 
+   * @see #getColumnSelectionAllowed()
    */ 
   public void setColumnSelectionAllowed(boolean c)
   {
-    getColumnModel().setColumnSelectionAllowed(c);
-    repaint();
+    if (columnModel.getColumnSelectionAllowed() != c)
+      {
+        columnModel.setColumnSelectionAllowed(c);
+        firePropertyChange("columnSelectionAllowed", !c, c);
+        repaint();
+      }
   }
 
   /**
@@ -4014,6 +4163,7 @@ public class JTable
     if (s != null)
       s.addListSelectionListener(this);
     selectionModel = s;
+    checkSelection();
   }
 
   /**