Última fila siempre eliminada de DefaultTableModel, independientemente del índice

Tengo algunos problemas cuando trato de eliminar filas de una tabla en Java. En particular, uso DefaultTableModel , y cuando bash eliminar una fila, utilizando el removeRow(int row) , se elimina la última fila, independientemente de cuál sea la row . Por ejemplo, digamos que tenemos seis filas. Cuando se removeRow(0) o removeRow(2) o removeRow(5) , la última fila siempre se elimina. Alguna idea, porque esto esta pasando?

Gracias

—actualizar

Cuando se presiona una celda particular de jtable, se debe quitar la fila correspondiente.

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

— actualización no2 Aquí hay un código con mi problema. He eliminado algunas cosas que son irrelevantes.

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

La row obtenida de columnAtPoint() está en coordenadas de vista , mientras que removeRow() asume coordenadas de modelo . Citando de la sección de tutorial relevante:

Esta distinción no importa a menos que los datos vistos se hayan reorganizado clasificando, filtrando o manipulando columnas por parte del usuario.

Si es así, deberá usar convertRowIndexToModel() , que se describe cerca del final de Ordenamiento y filtrado , que informa:

Cuando utilice un clasificador, recuerde siempre traducir las coordenadas de la celda.

Además, considere usar un ListSelectionListener lugar de un MouseAdapter .

Adición: su implementación de getValueAt() continuó accediendo a la matriz suministrada al constructor, mientras que los datos del modelo se almacenaron realmente en la implementación principal. Si realmente necesita más control sobre la estructura de datos del modelo, extienda AbstractTableModel , como se muestra aquí .

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

Al removeRow(int) el código del método removeRow(int) de DefaultTableModel , está claro que eliminará la matriz de filas en el índice correspondiente del Vector respaldo:

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

(de java 6).

Puedo pensar en dos posibilidades:

  1. extendió el DefaultTableModel y cambió la implementación de este método. (Dudo que este sea el caso – probablemente habrías admitido esto en tu publicación)

  2. tiene un procesador personalizado para la tabla, que pinta los datos de la celda en función del índice de fila de la celda.