[英]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);
}
}
當我運行該程序時,它顯示的是預期的表格。 我在運行時使用ProductTableModel
的addEmptyRow()
在表中添加了一些行。 當我突出顯示/選擇表中的一行並單擊刪除按鈕時,它向我顯示以下錯誤:
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,因為它myTable2ThatHasNoRowsAddedToIt
是myTable2ThatHasNoRowsAddedToIt
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.