Why is my re-rendering of the JTable causing a stack overflow when I select the first row?

So I am trying to write an interface in swing. In short, I have a JTable where I listen for selection events and after the user selects an item, the code takes a little path through the code, after which it calls the "redraw" table; it empties the table and adds rows again.

This process seems to be fine for clicking on lines 2-4 (see code below), but when I click on the first line, I get a stack overflow that I cannot explain.

I know this is not exactly the best solution, since the table practically does not require redrawing, but I would first of all want my code to be clean and logically structured (which is what causes the redraw), and second I was trying to get what causes this for so long that I really wanted to know what was going on.

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"});
}
}

      

+3


source to share


1 answer


The reason for stackoverflow is that when you delete all lines and start adding lines, you start the listener again. I'm not a big fan of modifying the model in a select listener (think about a situation where another select listener is added to the table), it will get completely obfuscated events. A possible solution for this is at least using invokeLater

).

But to avoid stackoverflow exception use



  @Override
  public void valueChanged(ListSelectionEvent event) {
    ListSelectionModel listSelectionModel = ( ListSelectionModel ) event.getSource();
    listSelectionModel.removeListSelectionListener( this );
    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"});
    listSelectionModel.addListSelectionListener( this );
  }

      

+1


source







All Articles