summaryrefslogtreecommitdiff
path: root/javax/swing/JTable.java
diff options
context:
space:
mode:
Diffstat (limited to 'javax/swing/JTable.java')
-rw-r--r--javax/swing/JTable.java213
1 files changed, 174 insertions, 39 deletions
diff --git a/javax/swing/JTable.java b/javax/swing/JTable.java
index 026d1b899..b8946213b 100644
--- a/javax/swing/JTable.java
+++ b/javax/swing/JTable.java
@@ -2922,56 +2922,190 @@ 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);
+ // Repaint the dirty region and revalidate.
+ int rowHeight = getRowHeight();
+ Rectangle dirty = new Rectangle(0, first * rowHeight,
+ getColumnModel().getTotalColumnWidth(),
+ (getRowCount() - first) * rowHeight);
+ repaint(dirty);
+ }
+ else
+ {
+ // TODO: We repaint the whole thing when the rows have variable
+ // heights. We might want to handle this better though.
+ repaint();
+ }
+ 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);
+
+ // 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);
+ }
+ else
+ {
+ // TODO: We repaint the whole thing when the rows have variable
+ // heights. We might want to handle this better though.
+ repaint();
}
+ 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();
}
/**
@@ -4030,6 +4164,7 @@ public class JTable
if (s != null)
s.addListSelectionListener(this);
selectionModel = s;
+ checkSelection();
}
/**