无论索引如何,最后一行总是从DefaultTableModel中删除

当我试图从java表中删除行时遇到一些问题。 特别是,我使用DefaultTableModel ,当我试图删除一行,使用removeRow(int row)方法,最后一行被删除,无论该row是什么。 例如,假设我们有六行。 当调用removeRow(0)removeRow(2)removeRow(5) ,最后一行总是被删除。 任何想法,为什么发生这种情况?

谢谢

—更新

当jtable的特定单元格被按下时,相应的行应该被删除。

  class TagsTableMA extends MouseAdapter { @Override public void mousePressed(MouseEvent e){ Point p = e.getPoint(); int row = tagsJT.rowAtPoint(p); int column = tagsJT.columnAtPoint(p); if (column == COLUMN_DELETE_TAG){ DocDialog docDialog = new DocDialog(parentMainJF, true, null, "Please confirm...", "Are you sure you want to delete the \"" + tagsJT.getValueAt(row, COLUMN_TAG_NAME) + "\" tag?", DocDialog.TYPE_YES_NO); docDialog.show(); int answer = docDialog.getAnswer(); if (answer == DocDialog.YES) model.removeRow(row); } } } 

—更新no2这是我的问题一些代码。 我已经删除了一些不相关的东西。

 import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JFrame; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; public class MainJF extends JFrame { public MainJF(){ this.add(createTagsTable()); setMinimumSize(new java.awt.Dimension(200,400)); } private JTable createTagsTable(){ String[] columnNames = {"", "Tag", "", "", ""}; Object[][] data = new Object[10][columnNames.length]; for (int i=0; i<data.length; i++){ data[i][COLUMN_CHECK] = false; data[i][COLUMN_TAG_NAME] = "Tag " + i; data[i][COLUMN_TAG_ID] = i; data[i][COLUMN_EDIT_TAG] = "edit"; data[i][COLUMN_DELETE_TAG] = "delete"; } model = new TagsSelectionTableModel(columnNames, data); tagsJT = new JTable(model); tagsJT.setRowSelectionAllowed(true); tagsJT.addMouseListener(new TagsTableMA()); return tagsJT; } class TagsSelectionTableModel extends DefaultTableModel{ public TagsSelectionTableModel(String[] columnNames, Object[][] data){ super(data, columnNames); this.columnNames = columnNames; this.data = data; } private String[] columnNames; private Object[][] data; @Override public Object getValueAt(int row, int col) { return data[row][col]; } } class TagsTableMA extends MouseAdapter{ @Override public void mousePressed(MouseEvent e){ Point p = e.getPoint(); int row = tagsJT.rowAtPoint(p); int column = tagsJT.columnAtPoint(p); if (column == COLUMN_DELETE_TAG){ int irow = tagsJT.convertRowIndexToView(row); model.removeRow(irow); } } } private JTable tagsJT; private TagsSelectionTableModel model; private static int COLUMN_CHECK = 0; private static int COLUMN_TAG_NAME = 1; private static int COLUMN_TAG_ID = 2; private static int COLUMN_EDIT_TAG = 3; private static int COLUMN_DELETE_TAG = 4; public static void main(String args[]) { new MainJF().setVisible(true); } } 

columnAtPoint()获得的columnAtPoint() 视图坐标中,而removeRow()假定模型坐标。 从相关教程部分引用:

除非您的查看数据已经通过sorting,筛选或用户对列的操作进行了重新排列,否则这种区别并不重要。

如果是这样,您将需要使用convertRowIndexToModel() ,在Sorting和Filtering结尾附近描述,build议:

使用分拣机时,请务必记住翻译单元格坐标。

另外,考虑使用ListSelectionListener而不是MouseAdapter

附录:您的getValueAt()继续访问提供给构造函数的数组,而模型的数据实际上存储在父实现中。 如果您确实需要更多地控制模型的数据结构,请扩展AbstractTableModel ,如下所示。

 import java.awt.EventQueue; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; /** @see https://stackoverflow.com/a/11237205/230513 */ public class MainJF extends JFrame { private JTable tagsJT; private TagsSelectionTableModel model; private static int COLUMN_CHECK = 0; private static int COLUMN_TAG_NAME = 1; private static int COLUMN_TAG_ID = 2; private static int COLUMN_EDIT_TAG = 3; private static int COLUMN_DELETE_TAG = 4; public MainJF() { this.add(new JScrollPane(createTagsTable())); pack(); setLocationRelativeTo(null); setDefaultCloseOperation(EXIT_ON_CLOSE); } private JTable createTagsTable() { String[] columnNames = {"0", "Tag", "2", "3", "4"}; Object[][] data = new Object[10][columnNames.length]; for (int i = 0; i < data.length; i++) { data[i][COLUMN_CHECK] = false; data[i][COLUMN_TAG_NAME] = "Tag " + i; data[i][COLUMN_TAG_ID] = i; data[i][COLUMN_EDIT_TAG] = "edit"; data[i][COLUMN_DELETE_TAG] = "delete"; } model = new TagsSelectionTableModel(columnNames, data); tagsJT = new JTable(model); tagsJT.setRowSelectionAllowed(true); tagsJT.addMouseListener(new TagsTableMA()); return tagsJT; } class TagsSelectionTableModel extends DefaultTableModel { public TagsSelectionTableModel(String[] columnNames, Object[][] data) { super(data, columnNames); } } class TagsTableMA extends MouseAdapter { @Override public void mousePressed(MouseEvent e) { Point p = e.getPoint(); int row = tagsJT.rowAtPoint(p); int col = tagsJT.columnAtPoint(p); if (col == COLUMN_DELETE_TAG) { model.removeRow(row); } } } public static void main(String args[]) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new MainJF().setVisible(true); } }); } } 

查看DefaultTableModelremoveRow(int)方法的代码,很明显它将删除相应索引的行数组Vector

  public void removeRow(int row) { dataVector.removeElementAt(row); fireTableRowsDeleted(row, row); } 

(来自Java 6)。

我可以想到两种可能性:

  1. 你已经扩展了DefaultTableModel并改变了这个方法的实现。 (我怀疑是这样的 – 你可能会在你的文章中承认这一点)

  2. 您有一个表的自定义渲染器,根据单元格的行索引绘制单元格数据。