ソート可能な 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);
}
});
}
}