从扩展AbstractTableModel的自定义模型中删除Jtable行

时间:2015-01-30 08:30:22

标签: java swing jtable defaulttablemodel abstracttablemodel

我有JTable使用我设计的自定义模型。此模型正在扩展AbstractTableModel,如下所示。我有一个按钮删除,我想要点击它将删除选中/突出显示的行这是我的表模型:

public class ProductTableModel extends AbstractTableModel
{

    private final List<String> columnNames;
    private final List<Product> products;

    public ProductTableModel() {
        String[] header = new String[] {
            "Quantity",
            "Description",
            "Unity Price",
            "Total Price"
        };
        this.columnNames = Arrays.asList(header);
        this.products = new ArrayList<>();
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        switch (columnIndex) {
            case 0: return Integer.class;
            case 1: return String.class;
            case 2: return Double.class;
            case 3: return Double.class;
                default: throw new ArrayIndexOutOfBoundsException(columnIndex);
        }
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Product product = this.getProduct(rowIndex);
        switch (columnIndex) {
           case 0: return product.getProductQuantity();
            case 1: return product.getProductDescription();
            case 2: return product.getProductPrice();
            case 3: return product.getProductTotalAmount();
                default: throw new ArrayIndexOutOfBoundsException(columnIndex);
        }
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return true;
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        if (columnIndex < 0 || columnIndex >= getColumnCount()) {
            throw new ArrayIndexOutOfBoundsException(columnIndex);
        } else {
            Product product = this.getProduct(rowIndex);
            switch (columnIndex) {
                case 0: product.setProductQuantity((Integer)aValue); break;
                case 1: product.setProductDescription((String)aValue); break;
                case 2: product.setProductPrice((Double)aValue); break;
                case 3: product.setProductTotalAmount((Double)aValue); break;
            }
            fireTableCellUpdated(rowIndex, columnIndex);
        }
    }

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

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

    @Override
    public String getColumnName(int columnIndex) {
        return this.columnNames.get(columnIndex);
    }

    public void setColumnNames(List<String> columnNames) {
        if (columnNames != null) {
            this.columnNames.clear();
            this.columnNames.addAll(columnNames);
            fireTableStructureChanged();
        }
    }

    public List<String> getColumnNames() {
        return Collections.unmodifiableList(this.columnNames);
    }

    public void addProducts(Product product) {
        int rowIndex = this.products.size();
        this.products.add(product);
        fireTableRowsInserted(rowIndex, rowIndex);
    }

    public void addProducts(List<Product> productList) {
        if (!productList.isEmpty()) {
            int firstRow = this.products.size();
            this.products.addAll(productList);
            int lastRow = this.products.size() - 1;
            fireTableRowsInserted(firstRow, lastRow);
        }
    }

    public void addEmptyRow() {
       products.add(new Product());
        this.fireTableRowsInserted(products.size()-1, products.size()-1);
    }

    public void insertProduct(Product product, int rowIndex) {
        this.products.add(rowIndex, product);
        fireTableRowsInserted(rowIndex, rowIndex);
    }

    public void deleteProduct(int rowIndex) {
        if (this.products.remove(this.products.get(rowIndex))) {
            fireTableRowsDeleted(rowIndex, rowIndex);
        }
    }

    public Product getProduct(int rowIndex) {
        return this.products.get(rowIndex);
    }

    public List<Product> getProducts() {
        return Collections.unmodifiableList(this.products);
    }

    public void clearTableModelData() {
        if (!this.products.isEmpty()) {
            int lastRow = products.size() - 1;
            this.products.clear();
            fireTableRowsDeleted(0, lastRow);
        }
    }
}

以下是从模型中删除产品的方法:

public void deleteProduct(int rowIndex) {
    if (this.products.remove(this.products.get(rowIndex))) {
        fireTableRowsDeleted(rowIndex, rowIndex);
    }
}

以下是单击删除时要执行的代码:

delete.addActionListener((ActionEvent e) -> {
    if (e.getSource().equals(delete)) {
        int modelRowIndex = table.convertRowIndexToModel(table.getSelectedRow());
        ProductTableModel model=(ProductTableModel)table.getModel();
        model.deleteProduct(modelRowIndex);
    }
}

当我运行这个程序时,它正在显示它应该是的表。我在运行时使用addEmptyRow()中的ProductTableModel在表格中添加了一些行。当我突出显示/选择表格中的一行并单击删除按钮时,它显示以下错误:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:418)
at java.util.ArrayList.get(ArrayList.java:431)
at quotationTable.ProductTableModel.deleteProduct(ProductTableModel.java:119)
at quotationTable.Table$InteractiveTableModelListener.lambda$tableChanged$0(Table.java:152)
at quotationTable.Table$InteractiveTableModelListener$$Lambda$25/930643647.actionPerformed(Unknown Source)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6525)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6290)
at java.awt.Container.processEvent(Container.java:2234)
at java.awt.Component.dispatchEventImpl(Component.java:4881)
at java.awt.Container.dispatchEventImpl(Container.java:2292)
at java.awt.Component.dispatchEvent(Component.java:4703)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
at java.awt.Container.dispatchEventImpl(Container.java:2278)
at java.awt.Window.dispatchEventImpl(Window.java:2739)
at java.awt.Component.dispatchEvent(Component.java:4703)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:719)
at java.awt.EventQueue$4.run(EventQueue.java:717)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

很抱歉有大堆痕迹,但是有一个人建议我把它装满。当我打印table.getSelectedRow()table.convertRowIndexToModel(table.getSelectedRow());他们给我-1时。

我们如何解决这个问题以及可能的原因?

2 个答案:

答案 0 :(得分:0)

可能在这行代码中

this.products.remove(this.products.get(rowIndex)

rowIndex返回null或零值,因为检查并调试此行我的朋友

答案 1 :(得分:0)

我发布的代码如果正常并且有效。这个问题是由于一个影子引用 - 也就是说我有两个我的表格实例。这就是为什么我在调用getSelectedRow()时得到-1的原因 - 这可能是我的问题,为什么我有这个价值但是我我在表格中添加行。简单来说 - 我在myTable1OnTheScreen添加行并在deleteSelectedRow()上调用myTable2ThatHasNoRowsAddedToIt因此,getSelectedRow()将返回-1,因为它引用了myTable2ThatHasNoRowsAddedToIt