Ultima riga sempre rimossa da DefaultTableModel, indipendentemente dall’indice

Devo affrontare alcuni problemi quando sto cercando di rimuovere le righe da una tabella in java. In particolare, utilizzo DefaultTableModel e, quando sto cercando di rimuovere una riga, utilizzando il removeRow(int row) , l’ultima riga viene rimossa, indipendentemente da quale sia la row . Ad esempio, diciamo che abbiamo sei righe. Quando viene removeRow(0) o removeRow(2) o removeRow(5) , l’ultima riga viene sempre rimossa. Qualche idea, perché questo sta accadendo?

Grazie

—aggiornare

Quando viene premuta una determinata cella del grafico, la riga corrispondente deve essere rimossa.

  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 Ecco un codice con il mio problema. Ho rimosso alcune cose che sono irrilevanti.

 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 ottenuta da columnAtPoint() è nelle coordinate di visualizzazione , mentre removeRow() assume le coordinate del modello . Citando dalla relativa sezione del tutorial :

Questa distinzione non ha importanza a meno che i dati visualizzati non siano stati riorganizzati dall’ordinamento, dal filtraggio o dalla manipolazione utente delle colonne.

In tal caso, sarà necessario utilizzare convertRowIndexToModel() , descritto vicino alla fine di Ordinamento e filtraggio , che consiglia:

Quando usi un sorter, ricorda sempre di tradurre le coordinate della cella.

Inoltre, considerare l’utilizzo di ListSelectionListener anziché di MouseAdapter .

Addendum: l’implementazione di getValueAt() continuato ad accedere all’array fornito al costruttore, mentre i dati del modello sono stati effettivamente memorizzati nell’implementazione principale. Se hai davvero bisogno di un maggiore controllo sulla struttura dei dati del modello, estendi AbstractTableModel , come mostrato qui .

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

Osservando il codice del metodo removeRow(int) di DefaultTableModel , è chiaro che rimuoverà l’array di righe all’indice corrispondente del Vector supporto:

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

(da Java 6).

Posso pensare a due possibilità:

  1. hai esteso il DefaultTableModel e hai cambiato l’implementazione di questo metodo. (dubito che questo sia il caso – probabilmente lo avresti ammesso nel tuo post)

  2. hai un renderizzatore personalizzato per la tabella, che dipinge i dati della cella in base all’indice di riga della cella.