-
Bug
-
Resolution: Unresolved
-
P3
-
None
-
6
-
x86
-
linux
FULL PRODUCT VERSION :
java version "1.6.0_03"
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux, Ubuntu 7.10
A DESCRIPTION OF THE PROBLEM :
JTable is not repainting correctly when using a TableRowSorter that is set to sort on update (invoking setSortsOnUpdates(true)). When the table content is updated / set using the TableModel setValueAt(...) the column that is sorted is repainted on the rows that move (i.e. content for that column appears resorted in the view). However the other columns in these rows are not repainted - displaying old data. Forcing the row to repaint (i.e. making a selection, switching column order), will cause the cells to repaint and they will then display the correct information. It seems the underlying sort has worked correctly, but these changes are not reflected to the JTable properly or are not processed by the JTable properly.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Using the code supplied,
1. Toggle-sort on the value column
2. Click the update table button (loads new random values into table)
3. Force repaint by making a table selection (click on first row and slowly select down)
Note, adding a simple selection and then updating the table causes the JTable to repaint some rows but not others.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
JTable view should sort on update.
Rows that change position should be repainted
JTable painted should be 100% inline with the new view of the data, i.e. up to date.
Toggle sort on the second column (column1 key letter, column2 int value):
A-1
B-2
C-3
Change B to 4 should expect:
A-1
C-3
B-4
ACTUAL -
The column which is toggle-sorted on in the moved rows is repainted correctly.
Other columns in moved rows do not get repainted (display old data)
The painted JTable result is not inline with the view of the data.
Sorting on ascending on the second column (column1 key letter, column2 int value):
A-1
B-2
C-3
Change B to 4, get:
A-1
B-3
C-4
Force table to repaint via selection you get the expected result:
A-1
C-3
B-4
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
/**
* Test class to demonstrate a potential repaint but with a JTable set to sort on update.
* <br>
* Program will create a simple frame with a simple JTable showing key to value data. Keys being
* simple characters / Strings and the values being random integers.
* <br>
* To observe problem:<br><br>
* 1. Toggle sort the Value column ascending or descending<br>
* 2. Click the Update table button<br>
* 3. You should see values change and resort in the Value column, but the keys remain stationary.<br>
* 4. Force a repaint by selecting a row, you should see row repaint with the up to date information<br>
* 5. Select all rows and repaint, the selection is causing the table to repaint everything and
* everything is repainted.<br>
* <br>
* Note selecting a cell and updating causes interesting repaints as some of the rows get repainted
* (you can see duplicated keys when old data exists)
*
* @author Robert Trevethan
*
*/
public class TestClass {
public static void main (String[] args) {
// create some default data
Object[][] data = {
{"A", 0},
{"B", 1},
{"C", 2},
{"D", 3},
{"E", 4},
{"F", 5},
{"G", 6},
{"H", 7},
{"I", 8}
};
// create table
JTable myTable = new JTable(data, new Object[] {"Key", "Value"});
final TableModel tabModel = myTable.getModel();
// create sorter, set to sort on update true and assign to table
final TableRowSorter<TableModel> mySorter = new TableRowSorter<TableModel>(tabModel);
mySorter.setSortsOnUpdates(true);
myTable.setRowSorter(mySorter);
// create a button to randomly add values in the table
JButton updateButton = new JButton("Update table");
updateButton.addActionListener(new ActionListener() {
private Random random = new Random(System.currentTimeMillis());
@Override
public void actionPerformed(ActionEvent e) {
for(int rowIndex = 0; rowIndex < tabModel.getRowCount(); rowIndex++) {
tabModel.setValueAt(random.nextInt(10), rowIndex, 1);
}
}
});
// create gui components
JFrame myFrame = new JFrame();
myFrame.setLayout(new BorderLayout());
JScrollPane scrollpane = new JScrollPane(myTable);
// add components to frame and set visible
myFrame.add(updateButton, BorderLayout.NORTH);
myFrame.add(scrollpane, BorderLayout.CENTER);
// display frame
myFrame.setSize(new Dimension(500,500));
myFrame.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
When sorting on updates, add a "RowSorterListener" to the sorter, catch the sorter changed event and on the RowSorterEvent.SORTED trigger a repaint of the JTable, which is not an efficient workaround.
java version "1.6.0_03"
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux, Ubuntu 7.10
A DESCRIPTION OF THE PROBLEM :
JTable is not repainting correctly when using a TableRowSorter that is set to sort on update (invoking setSortsOnUpdates(true)). When the table content is updated / set using the TableModel setValueAt(...) the column that is sorted is repainted on the rows that move (i.e. content for that column appears resorted in the view). However the other columns in these rows are not repainted - displaying old data. Forcing the row to repaint (i.e. making a selection, switching column order), will cause the cells to repaint and they will then display the correct information. It seems the underlying sort has worked correctly, but these changes are not reflected to the JTable properly or are not processed by the JTable properly.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Using the code supplied,
1. Toggle-sort on the value column
2. Click the update table button (loads new random values into table)
3. Force repaint by making a table selection (click on first row and slowly select down)
Note, adding a simple selection and then updating the table causes the JTable to repaint some rows but not others.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
JTable view should sort on update.
Rows that change position should be repainted
JTable painted should be 100% inline with the new view of the data, i.e. up to date.
Toggle sort on the second column (column1 key letter, column2 int value):
A-1
B-2
C-3
Change B to 4 should expect:
A-1
C-3
B-4
ACTUAL -
The column which is toggle-sorted on in the moved rows is repainted correctly.
Other columns in moved rows do not get repainted (display old data)
The painted JTable result is not inline with the view of the data.
Sorting on ascending on the second column (column1 key letter, column2 int value):
A-1
B-2
C-3
Change B to 4, get:
A-1
B-3
C-4
Force table to repaint via selection you get the expected result:
A-1
C-3
B-4
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
/**
* Test class to demonstrate a potential repaint but with a JTable set to sort on update.
* <br>
* Program will create a simple frame with a simple JTable showing key to value data. Keys being
* simple characters / Strings and the values being random integers.
* <br>
* To observe problem:<br><br>
* 1. Toggle sort the Value column ascending or descending<br>
* 2. Click the Update table button<br>
* 3. You should see values change and resort in the Value column, but the keys remain stationary.<br>
* 4. Force a repaint by selecting a row, you should see row repaint with the up to date information<br>
* 5. Select all rows and repaint, the selection is causing the table to repaint everything and
* everything is repainted.<br>
* <br>
* Note selecting a cell and updating causes interesting repaints as some of the rows get repainted
* (you can see duplicated keys when old data exists)
*
* @author Robert Trevethan
*
*/
public class TestClass {
public static void main (String[] args) {
// create some default data
Object[][] data = {
{"A", 0},
{"B", 1},
{"C", 2},
{"D", 3},
{"E", 4},
{"F", 5},
{"G", 6},
{"H", 7},
{"I", 8}
};
// create table
JTable myTable = new JTable(data, new Object[] {"Key", "Value"});
final TableModel tabModel = myTable.getModel();
// create sorter, set to sort on update true and assign to table
final TableRowSorter<TableModel> mySorter = new TableRowSorter<TableModel>(tabModel);
mySorter.setSortsOnUpdates(true);
myTable.setRowSorter(mySorter);
// create a button to randomly add values in the table
JButton updateButton = new JButton("Update table");
updateButton.addActionListener(new ActionListener() {
private Random random = new Random(System.currentTimeMillis());
@Override
public void actionPerformed(ActionEvent e) {
for(int rowIndex = 0; rowIndex < tabModel.getRowCount(); rowIndex++) {
tabModel.setValueAt(random.nextInt(10), rowIndex, 1);
}
}
});
// create gui components
JFrame myFrame = new JFrame();
myFrame.setLayout(new BorderLayout());
JScrollPane scrollpane = new JScrollPane(myTable);
// add components to frame and set visible
myFrame.add(updateButton, BorderLayout.NORTH);
myFrame.add(scrollpane, BorderLayout.CENTER);
// display frame
myFrame.setSize(new Dimension(500,500));
myFrame.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
When sorting on updates, add a "RowSorterListener" to the sorter, catch the sorter changed event and on the RowSorterEvent.SORTED trigger a repaint of the JTable, which is not an efficient workaround.