So I am trying to write a UI in swing. In short, I have a JTable where I listen for selection events, and after a user selects an item, the code takes a bit of a path through the program’s code, after which it invokes a table “redraw”; it empties the table, and adds the rows again.
This process seems to work fine for clicking on rows 2-4 (see code bit below), but when I click on the first row, I get a stack overflow I can not explain.
I know it isn’t exactly the best solution, as the table practically does not require a redraw, but I would first of all like to keep my code clean and logically structured (which is what causes the redraw), and second I have been trying to get what causes this so long that I would really just like to know what happens.
Here is a runnable class that reproduces the problem:
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
public class Tester implements ListSelectionListener {
private DefaultTableModel model;
public Tester(DefaultTableModel model) {
this.model = model;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(200, 200);
frame.setVisible(true);
JTable table = new JTable();
DefaultTableModel model = new DefaultTableModel();
table.setModel(model);
table.getSelectionModel().addListSelectionListener(new Tester(model));
model.setColumnCount(3);
model.setColumnIdentifiers(new String[]{"col1", "col2", "col3"});
frame.add(table);
model.addRow(new Object[]{"1", "2", "3"});
model.addRow(new Object[]{"4", "2", "3"});
model.addRow(new Object[]{"3", "2", "3"});
model.addRow(new Object[]{"2", "2", "3"});
}
public void valueChanged(ListSelectionEvent event) {
model.setRowCount(0);
model.addRow(new Object[]{"1", "2", "3"});
model.addRow(new Object[]{"4", "2", "3"});
model.addRow(new Object[]{"3", "2", "3"});
model.addRow(new Object[]{"2", "2", "3"});
}
}
The reason for the stackoverflow is that when you remove all rows and start adding rows you trigger the listener again. I am not a big fan of changing the model in a selection listener (think of the situation where another selection listener is attached to the table … it will receive completely screwed up events. Possible solution for this is to at least use an
invokeLatercall).But to avoid your stackoverflow exception, use