簡體   English   中英

從擴展AbstractTableModel的自定義模型中刪除Jtable行

[英]Deleting a Jtable row from a custom model extending 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);
    }
}

當我運行該程序時,它顯示的是預期的表格。 我在運行時使用ProductTableModeladdEmptyRow()在表中添加了一些行。 當我突出顯示/選擇表中的一行並單擊刪除按鈕時,它向我顯示以下錯誤:

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。

我們該如何解決?可能是什么原因?

可能在這行代碼中

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

rowIndex返回null或零值,因為我的朋友檢查並調試此行

我發布的代碼可以正常工作。 問題是由於陰影引用-也就是說我有兩個表實例,這回答了為什么我在調用getSelectedRow()時得到-1的原因-這可能是我有這個值但我正在添加的原因簡單來說-我正在向myTable1OnTheScreen添加行並在myTable2ThatHasNoRowsAddedToIt上調用deleteSelectedRow() ,因此getSelectedRow()將返回-1,因為它myTable2ThatHasNoRowsAddedToItmyTable2ThatHasNoRowsAddedToIt

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM