Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6600648

Deleting the last row in a table causes getValueAt() to be called for all rows

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P3 P3
    • None
    • 6
    • client-libs

      FULL PRODUCT VERSION :
      java version "1.6.0"
      Java(TM) SE Runtime Environment (build 1.6.0-b105)
      Java HotSpot(TM) 64-Bit Server VM (build 1.6.0-b105, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux primus 2.6.16.27-0.9-default #1 Tue Feb 13 09:35:18 UTC 2007 x86_64 x86_64 x86_64 GNU/Linux


      A DESCRIPTION OF THE PROBLEM :
      When deleting the last row of a table, the redraw/validate causes the entire table to be redrawn, not just the visible part. For tables with many rows, read from a DB or other persistent storage, this results in long UI delays (e.g. 15 secs for a 3'000 row table).

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the code. It will print "getValueAt(n,0)" for the first twenty rows or so. Scroll to the end of table. This will print "getValueAt(n,0)" for the remaining ~980 rows.
      Now press the delete button.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      After deleting the last row, getValueAt() should only be called for one or two rows, or maybe twenty if there is no backing image store to scroll.
      ACTUAL -
      After deleting the last row, getValueAt() is called for all 1000 rows.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.awt.*;
      import java.awt.event.*;
      import javax.swing.*;
      import javax.swing.table.*;

      public class RowDeleteBug extends JFrame {
        private RowDeleteTableModel tableModel;

        public RowDeleteBug() {
          super("RowDeleteBug");
          setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
          JTable table = new JTable(tableModel = new RowDeleteTableModel(1000));
          getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
          JButton button = new JButton("Delete");
          button.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                tableModel.deleteRow();
              }
            });
          getContentPane().add(button, BorderLayout.SOUTH);
          setSize(400, 400);
        }

        public static void main(String[] args) {
          new RowDeleteBug().setVisible(true);
        }
      }

      class RowDeleteTableModel extends AbstractTableModel {
        private int rowCount;

        RowDeleteTableModel(int initialRowCount) { rowCount = initialRowCount; }

        public int getRowCount() { return rowCount; }

        public int getColumnCount() { return 1; }

        public Object getValueAt(int row, int col) {
          System.out.println("getValueAt(" + row + "," + col + ")");
          return "Item #" + row;
        }

        void deleteRow() {
          rowCount--; fireTableRowsDeleted(rowCount, rowCount);
        }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Overriding the table's getRowAtPoint() method to not return -1, but getRowCount() - 1 if the y coordinate exceeds the real table height, causes the bug to disappear.

            peterz Peter Zhelezniakov
            igor Igor Nekrestyanov (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: