开发者

JTable row selection after TableModel update

开发者 https://www.devze.com 2023-03-31 01:05 出处:网络
How to preserve table row selecetion after table mode update (fireTableDataChanes)? I know that I should save selection before fire and restore it after (from there). But when I tr开发者_StackOverflow

How to preserve table row selecetion after table mode update (fireTableDataChanes)? I know that I should save selection before fire and restore it after (from there). But when I tr开发者_StackOverflowy to restore selection in TableModelListener it doesn't work. So where should I restore selection?

Update: Now I try to restore selection in this way: table.setModel(model);

    model.addTableModelListener(new TableModelListener() {

      @Override
      public void tableChanged(TableModelEvent e) {
        table.addRowSelectionInterval(1, 1);
      }
    });

but it doesn't work.


This is an updated version of the first answer. You can use a field to store the row as it can be accessed by inner classes. I had some trouble with this solution tough because I used a periodic thread to update the table.

private int selectedRow = -1;

public void mymethod() {
//put code to create the table here...
    JTable tableList = new JTable();


// Save selected row table
    tableList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
        @Override
        public void valueChanged(ListSelectionEvent e) {
            selectedRow = e.getFirstIndex();
        }
    });

// Restore selected raw table
model.addTableModelListener(new TableModelListener() {      
    @Override
    public void tableChanged(TableModelEvent e) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                if (selectedRow >= 0) {
                            tableList.addRowSelectionInterval(index, index);
                }
             }
        });
    }
    });
}


Decision is simple: we should use Swing EventQueue:

final int selectedRow = 0;
// Save selected row table
tableList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
    @Override
    public void valueChanged(ListSelectionEvent e) {
        selectedRow = e.getFirstIndex();
    }
});

// Restore selected raw table
model.addTableModelListener(new TableModelListener() {      
    @Override
    public void tableChanged(TableModelEvent e) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                if (selectedRow >= 0) {
                            tableList.addRowSelectionInterval(index, index);
                }
             }
        });
    }
});


The example from the first answer shows the basic solution but won't work out of the box. It's not possible to change the final "selectedRow". So a mutable integer (e.g. AtomicInteger) should be used. The tamleModelListener dispatches to task to swing, so it gets invoked later - in most cases after the table change has already removed the selection. So selectedRow will in most cases be -1.

I have changed the above example a bit (and added single cell selection but it also works for full rows):

    final AtomicInteger selectedRow=new AtomicInteger(-1);
    final AtomicInteger selectedCol=new AtomicInteger(-1);
    tblZeiten.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
        @Override
        public void valueChanged(ListSelectionEvent e)
        {
            selectedRow.set(tblZeiten.getSelectedRow());
            selectedCol.set(tblZeiten.getSelectedColumn());
        }
    });
    tblZeiten.getModel().addTableModelListener(new TableModelListener() {      
        @Override
        public void tableChanged(TableModelEvent e)
        {
            TableCellEditor editor=tblZeiten.getCellEditor();
            if (editor!=null) editor.cancelCellEditing();

            final int row=selectedRow.get();
            final int col=selectedCol.get();
            if (row<0||col<0) return;

            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    // http://book.javanb.com/the-java-developers-almanac-1-4/egs/javax.swing.table/Sel.html
                    tblZeiten.changeSelection(row,col, false, false);
                 }
            });
        }
    });
0

精彩评论

暂无评论...
验证码 换一张
取 消