JDK-4205145 : Unreliable Row Selection in JTable
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.2.0
  • Priority: P2
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_2.5.1
  • CPU: sparc
  • Submitted: 1999-01-22
  • Updated: 1999-02-11
  • Resolved: 1999-02-11
Related Reports
Duplicate :  
Description
Under both JDK1.2 and JDK1.1.7+Swing1.1 on both Solaris and Window NT, the row
selection is not reliably rendered when it is called from code. Sometime the
selected row is not highlighted and sometime the previously selected row is not
cleared. I included test code below to illustrate the problem. 

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;

public class TestTable extends JPanel implements ActionListener {

  private Model       model;
  private JTable      table;
  private JScrollPane scrollPane;
  private JButton     btest;
  private Random      rand;
  private int         size = 50;

  public TestTable() {
    rand = new Random();

    model = new Model();
    table = new JTable(model);
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    scrollPane = new JScrollPane(table);
    scrollPane.setPreferredSize(new Dimension(500, 200));

    btest = new JButton("Scroll and Select");
    btest.addActionListener(this);

    setLayout(new BorderLayout());
    add("Center", scrollPane);
    add("South", btest);
  }

  public void actionPerformed(ActionEvent evt) {
    JButton b = (JButton)evt.getSource();
    if (b == btest) {
      int select = (int)(size * rand.nextFloat());
      table.setRowSelectionInterval(select, select);
      JScrollBar scrollBar = scrollPane.getVerticalScrollBar();
      scrollBar.setValue(select * scrollBar.getMaximum() / size);
      System.out.println("select row " + select);
    }
  }

  class Model extends AbstractTableModel {
 
    final String[] columnNames = {"0", "1", "2", "3", "4", 
                                  "5", "6", "7", "8", "9"};

    public Model () {
    }

    public void updateTable() {
      fireTableDataChanged();
    }

    public int getColumnCount() {
      return columnNames.length;
    }

    public int getRowCount() {
      return size;
    }

    public String getColumnName(int col) {
      return columnNames[col];
    }

    public Object getValueAt(int row, int col) {
      return new Integer(row * col);
    }
  }

  public static void main(String[] args) {
    JFrame       f = new JFrame("Test TestTable");
    TestTable p = new TestTable();
    f.getContentPane().add("Center", p);
    f.pack();
    f.setVisible(true);
  }
}


Comments
EVALUATION The following is a deterministic equivalent of the test program which produces two selected rows when the button is clicked for the 5th time, and other errors along the way. import javax.swing.event.*; import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.table.*; public class TestTable extends JPanel implements ActionListener { private JTable table; private JScrollPane scrollPane; private JButton btest; private int size = 50; private int select = 1; public TestTable() { table = new JTable(size, 10); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); scrollPane = new JScrollPane(table); scrollPane.setPreferredSize(new Dimension(500, 200)); btest = new JButton("Scroll and Select"); btest.addActionListener(this); setLayout(new BorderLayout()); add("Center", scrollPane); add("South", btest); } public void actionPerformed(ActionEvent evt) { JButton b = (JButton)evt.getSource(); if (b == btest) { select = (int)(1 + select * 3 % size); table.setRowSelectionInterval(select, select); JScrollBar scrollBar = scrollPane.getVerticalScrollBar(); scrollBar.setValue(select * scrollBar.getMaximum() / size); } } public static void main(String[] args) { JFrame f = new JFrame("Test TestTable"); TestTable p = new TestTable(); f.getContentPane().add("Center", p); f.pack(); f.setVisible(true); } } This is due to the JViewport which optimises drawing during scrolling operations. In this case the optimisation is not valid. As a workaround, it is possible to call use invokeLater to ensure that a genuine repaint is performed after the scrollPane has performed its scroll. milne@eng 2.10.99 This is a duplicate of 4200690. Refer to it for more information about this problem. I have updated the work around section for a couple of way to get around this. scott.violet 1999-02-11
11-06-2004

WORK AROUND There are a couple of options: Turn off the backing store: viewport.setBackingStoreEnabled(false); After changing the selection and scrolling do something like: SwingUtilities.invokeLater(new Runnable() { public void run() { table.repaint(); } }); scott.violet 1999-02-11
11-06-2004

PUBLIC COMMENTS This is a duplicate of 4200690. Refer to it for more information about this problem. I have updated the work around section for a couple of way to get around this. scott.violet 1999-02-11
10-06-2004