Java 使用自定义表模型从JTable中删除行

Java 使用自定义表模型从JTable中删除行,java,swing,jtable,hashmap,abstracttablemodel,Java,Swing,Jtable,Hashmap,Abstracttablemodel,我有一个JTable的子类,它使用自定义表模型(AbstractTableModel的实现)来管理数据 当我尝试使用方法deleteRow删除一行时,就会出现问题。“我的表”中的行将替换为空字符串,但不会删除该行 代码如下: public class LiveSearchTableModel extends AbstractTableModel { private List<String> columnNames = new ArrayList<String>()

我有一个
JTable
的子类,它使用自定义表模型(
AbstractTableModel
的实现)来管理数据

当我尝试使用方法
deleteRow
删除一行时,就会出现问题。“我的表”中的行将替换为空字符串,但不会删除该行

代码如下:

public class LiveSearchTableModel extends AbstractTableModel 
{

  private List<String> columnNames = new ArrayList<String>();
  private Map<Point, Object> displayData = new HashMap<Point, Object>();
  private Map<Point, Object> originalData = new HashMap<Point, Object>();

  public LiveSearchTableModel(List<String> columnNames, 
      Map<Point, Object> tableData) 
  {
    this.columnNames = columnNames;
    this.displayData = tableData;
    this.originalData.putAll(tableData); 
  }

  @Override
  public int getColumnCount() {
    return columnNames.size();
  }

  @Override
  public int getRowCount() {
    return displayData.size() / columnNames.size();
  }

  @Override
  public Object getValueAt(int rowIndex, int columnIndex) {
    return displayData.get(new Point(rowIndex, columnIndex));
  }

  public void deleteRow (int row)
  {
    for (int cont = 0; cont < columnNames.size();cont++)
    {   
      displayData.remove(new Point (row,cont)); 
    }

    this.fireTableRowsDeleted(row, row);
  }

  @Override
  public void setValueAt(Object value, int rowIndex, int columnIndex) 
  {
    this.displayData.put(new Point(rowIndex, columnIndex), value);
    this.fireTableDataChanged();
  }
}
公共类LiveSearchTableModel扩展了AbstractTableModel
{
private List columnNames=new ArrayList();
私有映射displayData=newhashmap();
private Map originalData=new HashMap();
公共LiveSearchTableModel(列出列名称,
地图表格(数据)
{
this.columnNames=columnNames;
this.displayData=tableData;
this.originalData.putAll(tableData);
}
@凌驾
public int getColumnCount(){
返回columnNames.size();
}
@凌驾
public int getRowCount(){
返回displayData.size()/columnNames.size();
}
@凌驾
公共对象getValueAt(int行索引、int列索引){
返回displayData.get(新点(行索引、列索引));
}
公共void deleteRow(int行)
{
对于(int cont=0;cont下面说明了一个潜在的问题:映射的键没有排序,而表的行没有排序。在所示的方法中,密钥数组必须随数据的每次更改而更新。另见本节相关内容。如果需要,您可以扩展
以实现
可比
,如
所示

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

/**
* @see https://stackoverflow.com/q/12330167/230513
*/
public class TableModelTest extends JPanel {

    public TableModelTest() {
        super(new BorderLayout());
        final MyModel model = new MyModel();
        JTable table = new JTable(model);
        this.add(new JScrollPane(table));
        this.add(new JButton(new AbstractAction("Delete") {

            @Override
            public void actionPerformed(ActionEvent e) {
                model.remove(0);
            }
        }), BorderLayout.SOUTH);
    }

    public class MyModel extends AbstractTableModel {

        private List<String> names = new ArrayList<String>();
        private Map<Point, Object> data = new HashMap<Point, Object>();
        private Point[] keys;

        public MyModel() {
            this.names = Arrays.asList("Point", "Name");
            data.put(new Point(1, 1), "One");
            data.put(new Point(2, 2), "Two");
            data.put(new Point(3, 3), "Three");
            this.keys = data.keySet().toArray(new Point[data.size()]);
        }

        public void remove(int row) {
            data.remove(keys[row]);
            keys = data.keySet().toArray(new Point[data.size()]);
            this.fireTableRowsDeleted(row, row);
        }

        @Override
        public int getColumnCount() {
            return names.size();
        }

        @Override
        public String getColumnName(int col) {
            return names.get(col);
        }

        @Override
        public int getRowCount() {
            return data.size();
        }

        @Override
        public Object getValueAt(int row, int col) {
            if (col == 0) {
                return keys[row];
            } else {
                return data.get(keys[row]);
            }
        }
    }

    private void display() {
        JFrame f = new JFrame("TableModelTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TableModelTest().display();
            }
        });
    }
}
导入java.awt.BorderLayout;
导入java.awt.EventQueue;
导入java.awt.Point;
导入java.awt.event.ActionEvent;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入javax.swing.AbstractAction;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.table.AbstractTableModel;
/**
*@见https://stackoverflow.com/q/12330167/230513
*/
公共类TableModelTest扩展了JPanel{
公共TableModelTest(){
超级(新边框布局());
最终MyModel模型=新的MyModel();
JTable table=新的JTable(模型);
添加(新的JScrollPane(表));
add(新的JButton(新的抽象操作(“删除”){
@凌驾
已执行的公共无效操作(操作事件e){
模型。移除(0);
}
}),边界布局(南部);
}
公共类MyModel扩展了AbstractTableModel{
私有列表名称=新的ArrayList();
私有映射数据=新HashMap();
私有点[]密钥;
公共MyModel(){
this.names=Arrays.asList(“点”、“名称”);
数据。投入(新的点(1,1),“一”);
新的第(2,2),“2”点;
数据。put(新的第(3,3)点,“三”);
this.keys=data.keySet().toArray(新点[data.size()]);
}
公共无效删除(整数行){
删除(键[行]);
keys=data.keySet().toArray(新点[data.size()]);
此.fireTableRowsDeleted(行,行);
}
@凌驾
public int getColumnCount(){
返回names.size();
}
@凌驾
公共字符串getColumnName(int-col){
返回name.get(col);
}
@凌驾
public int getRowCount(){
返回data.size();
}
@凌驾
公共对象getValueAt(整数行,整数列){
如果(列==0){
返回键[行];
}否则{
返回data.get(键[行]);
}
}
}
专用void display(){
JFrame f=新JFrame(“TableModelTest”);
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f、 加上(这个);
f、 包装();
f、 setLocationRelativeTo(空);
f、 setVisible(真);
}
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
新建TableModelTest().display();
}
});
}
}

您能否编辑您的代码示例,以提供一个我们可以执行和实验的示例?它并不是那么简单。我试着这么做!谢谢,这通常比你想象的容易。只是一个小测试框架,有一个表、一个按钮和一些填充的日期。它不必很漂亮。“有时候你会发现答案只是创建了一个SSCCE。”邓肯·琼斯·特拉什戈德发布了SSCCE代码。关于删除后的表中的空白行,您有什么想法吗?我需要了解这一点,然后我将关注垃圾桶指出的排序问题。如果您使用实现了可比较的
,因为,您可以使用
树映射
,而不是
哈希映射
。感谢您的回复。我知道您已经强调了一个事实,即使用HashMap时,顺序可能会有问题。在我的情况下,顺序是可以的,但是你知道为什么我删除时表格中有一个空行吗?谢谢对不起,没有什么突出的;您可以查找
null
键,并检查
put()
remove()
返回的值,以查找意外的结果。@Luca:作为参考,我在示例中添加了一个简单的删除按钮。将范围检查作为练习左移。:-)非常感谢。我现在将致力于修改实现以保留oOrder(我看到DefaultTableModel使用向量类型来存储数据,在我的自定义表模型中使用向量类型是一个很好的解决方案?)