0
我有一個可排序的JTable;當添加一行時,我想知道它的視圖-index。我嘗試使用這樣的表模型監聽器:將modelRowIndex轉換爲viewRowIndex以進行排序的JTable
@Override
public void tableChanged(TableModelEvent event)
{
if (event.getType() == TableModelEvent.INSERT)
{
int modelRowIndex = event.getFirstRow();
int viewRowIndex = table.convertRowIndexToView(modelRowIndex);
System.out.println("viewRowIndex: " + viewRowIndex);
}
}
如果表未被排序,這將起作用。不幸的是,如果對錶格進行排序,則轉換方法導致ArrayIndexOutOfBoundsException
由DefaultRowSorter.java:503
引起。
我想這是因爲表模型在通知行分類器之前通知我的監聽器。有任何想法嗎?謝謝!
這裏是一個SSCCE:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
public class RowIndexSSCCE extends JFrame
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
new RowIndexSSCCE().setVisible(true);
}
});
}
private final JTable table;
public RowIndexSSCCE()
{
JButton button = new JButton("Add");
button.addActionListener(new ButtonListener());
table = new JTable(new Model());
table.setAutoCreateRowSorter(true);
table.getModel().addTableModelListener(new ModelListener());
JScrollPane scrollPane = new JScrollPane(table);
JPanel panel = new JPanel();
panel.add(button);
panel.add(scrollPane);
add(panel);
pack();
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private class ButtonListener implements ActionListener
{
@Override
public void actionPerformed(ActionEvent event)
{
((Model) table.getModel()).addRow("asdf" + table.getRowCount());
}
}
private class ModelListener implements TableModelListener
{
@Override
public void tableChanged(TableModelEvent event)
{
if (event.getType() == TableModelEvent.INSERT)
{
int modelRowIndex = event.getFirstRow();
int viewRowIndex = table.convertRowIndexToView(modelRowIndex);
System.out.println("viewRowIndex: " + viewRowIndex);
}
}
}
private class Model extends AbstractTableModel
{
private final List<String> data = new ArrayList<String>();
public void addRow(String string)
{
int oldSize = data.size();
data.add(string);
fireTableRowsInserted(oldSize, oldSize);
}
@Override
public int getRowCount()
{
return data.size();
}
@Override
public int getColumnCount()
{
return 1;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex)
{
return data.get(rowIndex);
}
}
}
編輯:
我想通了自己...用SwingUtilities.invokeLater
確保行排序更新後的行索引轉換完成:
@Override
public void tableChanged(final TableModelEvent event)
{
if (event.getType() == TableModelEvent.INSERT)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
int modelRowIndex = event.getFirstRow();
int viewRowIndex = table.convertRowIndexToView(modelRowIndex);
System.out.println("viewRowIndex: " + viewRowIndex);
}
});
}
}
雖然這有效,但我認爲依靠聽衆通知的順序通常是一個壞主意。看到我自己的問題的編輯爲解決方案,避免這一點。儘管如此,謝謝你的回答! – thofou76