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

时间:2012-06-27 09:56:02

标签: java swing jtable row 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);
}
}

2 个答案:

答案 0 :(得分:5)

row获取的columnAtPoint()位于视图坐标中,而removeRow()则采用模型坐标。引自相关的tutorial section

  

除非您通过对列进行排序,过滤或用户操作重新排列了所查看的数据,否则此区别无关紧要。

如果是这样,您需要使用convertRowIndexToModel()附近描述的MouseAdapter,其中建议:

  

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

另外,请考虑使用Sorting and Filtering代替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); } }); } } ,如图所示ListSelectionListener

{{1}}

答案 1 :(得分:3)

查看removeRow(int)的{​​{1}}方法的代码,很明显它会删除支持DefaultTableModel的相应索引处的行数组:

Vector

(来自java 6)。

我可以想到两种可能性:

  1. 您已扩展 public void removeRow(int row) { dataVector.removeElementAt(row); fireTableRowsDeleted(row, row); } 并更改了此方法的实现。 (我怀疑是这种情况 - 你可能会在你的帖子中承认这一点)

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