Die letzte Zeile wurde unabhängig vom Index immer aus DefaultTableModel entfernt

Ich habe einige Probleme, wenn ich versuche, Zeilen von einem Tisch in Java zu entfernen. Insbesondere verwende ich das DefaultTableModel , und wenn ich versuche, eine Zeile mit der Methode removeRow(int row) zu entfernen, wird die letzte Zeile entfernt, unabhängig davon, was die row ist. Nehmen wir zum Beispiel an, dass wir sechs Zeilen haben. Wenn removeRow(0) oder removeRow(2) oder removeRow(5) aufgerufen wird, wird die letzte Zeile immer entfernt. Irgendeine Idee, warum das passiert?

Vielen Dank

—aktualisieren

Wenn eine bestimmte Zelle der J-Tabelle gedrückt wird, sollte die entsprechende Zeile entfernt werden.

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

— update no2 Hier ist ein Code mit meinem Problem. Ich habe einige Dinge entfernt, die irrelevant sind.

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

Die von columnAtPoint() erhaltene columnAtPoint() befindet sich in Ansichtskoordinaten , während removeRow() Modellkoordinaten annimmt. Zitat aus dem entsprechenden Tutorial-Abschnitt :

Diese Unterscheidung spielt keine Rolle, es sei denn, Ihre angezeigten Daten wurden durch Sortieren, Filtern oder Benutzermanipulation von Spalten neu angeordnet.

Wenn dies der convertRowIndexToModel() , müssen Sie convertRowIndexToModel() , das am Ende von Sorting and Filtering beschrieben wird.

Vergessen Sie bei der Verwendung eines Sortierers nicht, die Zellkoordinaten zu übersetzen.

ListSelectionListener auch, einen ListSelectionListener anstelle eines MouseAdapter .

Nachtrag: Ihre Implementierung von getValueAt() weiterhin auf das Array zugegriffen, das dem Konstruktor übergeben wurde, während die Daten des Modells tatsächlich in der übergeordneten Implementierung gespeichert wurden. Wenn Sie mehr Kontrolle über die Datenstruktur des Modells benötigen, erweitern Sie AbstractTableModel , wie hier gezeigt.

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

Wenn Sie den Code der removeRow(int) -Methode von DefaultTableModel , ist es klar, dass das removeRow(int) beim entsprechenden Index des Hintergrundvektors entfernt wird:

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

(aus Java 6).

Ich kann mir zwei Möglichkeiten vorstellen:

  1. Sie haben das DefaultTableModel und die Implementierung dieser Methode geändert. (Ich bezweifle, dass dies der Fall ist – wahrscheinlich hätten Sie dies in Ihrem Beitrag zugegeben)

  2. Sie haben einen benutzerdefinierten Renderer für die Tabelle, der die Zellendaten basierend auf dem Zeilenindex der Zelle zeichnet.