【问题标题】:rows not deleted from JTable未从 JTable 中删除的行
【发布时间】:2014-10-09 21:18:54
【问题描述】:

在我的 JTable 中,我所有的复选框都在第 3 列中。单击按钮后,它将 删除那些被选中的行。

但是在我的 onclick 中实现了这些功能之后。它不会删除行。

按钮监听方法

class DeleteBtnListener implements ActionListener {  
    @Override
    public void actionPerformed(ActionEvent arg0) {
        for(int row = 0; row < table.getRowCount(); ++row) {
            if((Boolean) table.getValueAt(row, 3) == true) {
                myTableModel.removeRow(row);
                table.revalidate();
                table.repaint(); 
            }
        }       
    }
}

这就是我的 AbstractTableModel 类中的内容

@SuppressWarnings("serial")
class MyTableModel extends AbstractTableModel {
    private final boolean DEBUG = true;

    private String[] columnNames = {"Name",
            "Age",
            "Salary",
    "Delete"};

    private Object[][] data = {
            {"Kathy", "20",new Integer(5), new Boolean(false)},
            {"John", "35", new Integer(3), new Boolean(false)},
            {"Sue", "20", new Integer(2), new Boolean(false)},
            {"Jane", "12", new Integer(20), new Boolean(false)},
            {"Mary", "42", new Integer(10), new Boolean(false)}
    };

    public int getColumnCount() {
        return columnNames.length;
    }

    public int getRowCount() {
        return data.length;
    }

    public String getColumnName(int col) {
        return columnNames[col];
    }

    public Object getValueAt(int row, int col) {
        return data[row][col];
    }

    @SuppressWarnings("unchecked")
    public Class<?> getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

    public boolean isCellEditable(int row, int col) {
        return true;
    }

    public void setValueAt(Object value, int row, int col) {
        if (DEBUG) {
            System.out.println("Setting value at " + row + "," + col
                    + " to " + value);

        }
        data[row][col] = value;
        fireTableCellUpdated(row, col);
    }

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

【问题讨论】:

  • 为了尽快获得更好的帮助,请发布MCVE(最小、完整、可验证的示例)。
  • 为什么不使用DefaultTableModel 作为MyTableModel 的基础?它可靠地添加和删除行。
  • 好的,谢谢你的建议

标签: java swing jtable tablemodel


【解决方案1】:

您需要从模型中的实际数据(即数组数据)中删除该行。 fireTableRowsDeleted 还不够。那只是更新ui的东西。但请记住,您使用的是数组。因此,您需要根据数据相应地推进行索引。更好地使用 List 以便于操作。另请记住,您正在尝试在循环中“同时”删除行。所以如果你删除一行,你也需要在循环中递减该行。

正如@AndrewThompson 提到的,只需使用DefaultTableModel。我看不出您的模型有什么特别之处需要定制模型。

这是DefaultTableModel的示例

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;

public class TestTable {


    private DefaultTableModel myTableModel = getModel();
    private JTable table = new JTable(myTableModel);

    public TestTable() {
        JButton button = new JButton("Remove All");
        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                for(int row = 0; row < table.getRowCount(); ++row) {
                    if((Boolean) table.getValueAt(row, 3) == true) {
                        System.out.println("true");
                        myTableModel.removeRow(row);
                        row--;
                    }
                } 
            }
        });

        JFrame frame = new JFrame();
        frame.add(new JScrollPane(table));
        frame.add(button, BorderLayout.PAGE_END);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private DefaultTableModel getModel() {
        String[] columnNames = {"Name",
                "Age",
                "Salary",
        "Delete"};

        Object[][] data = {
                {"Kathy", "20",new Integer(5), new Boolean(false)},
                {"John", "35", new Integer(3), new Boolean(false)},
                {"Sue", "20", new Integer(2), new Boolean(false)},
                {"Jane", "12", new Integer(20), new Boolean(false)},
                {"Mary", "42", new Integer(10), new Boolean(false)}
        };
        return new DefaultTableModel(data, columnNames) {
            @Override
            public Class<?> getColumnClass(int col) {
                switch(col) {
                case 0: 
                case 1: return String.class;
                case 2: return Integer.class;
                case 3: return Boolean.class;
                default: return Object.class;
                }
            }
        };
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                new TestTable();
            }
        });
    }
}

【讨论】:

    【解决方案2】:

    你能用DefaultTableModel 试试,效果很好。如果需要,覆盖 JTable 的其他方法。

    示例代码:

    DefaultTableModel model = new DefaultTableModel(data, columnNames);
    final JTable table = new JTable(model) {
        @Override
        public Class<?> getColumnClass(int column) {
            switch (column) {
                case 2:
                    return Integer.class;
                case 3:
                    return Boolean.class;
                default:
                    return String.class;
            }
        }
    
        @Override
        public boolean isCellEditable(int row, int col) {
            return true;
        }
    };
    

    删除行调用

    ((DefaultTableModel) table.getModel()).removeRow(row);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-28
      • 1970-01-01
      • 2014-08-28
      • 2011-12-22
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 2013-03-07
      相关资源
      最近更新 更多