gpt4 book ai didi

java - 从 JTable 中删除对象时出现 ArrayOutOfBoundsException

转载 作者:行者123 更新时间:2023-12-01 12:02:29 28 4
gpt4 key购买 nike

我是 Java 的新手。我现在才学半年。现在我正在为学校做一个项目,但我遇到了障碍:

我基本上正在制作一个程序来管理您自己的书籍。我有一个类“Books”,它保存书籍对象的数据。然后是“Library”类,它包含书籍的ArrayList。对于 TableModel,我使用扩展 AbstractTableModel 的类(“LibraryTableModel”)。然后我有一个 GUI 类来显示该表。

该表实际上可以工作,但有两个实例导致程序崩溃:

当我将一本书添加到空图书馆时,表格不会更新。但是,当我重新启动程序时,这本书被添加了(我将 Library 类保存为 .ser 文件)。

然后是我要询问的实例:我有一个按钮可以从表中删除书籍。按钮本身工作正常,但是当我删除一本书时,程序会抛出 ArrayOutOfBoundsException。当我重新创建表时,它会更新并且书籍会被删除。这里有什么问题,为什么程序崩溃而不是更新表?

TableModel 代码:

public class LibraryTableModel extends AbstractTableModel
{
private String[] columnNames = {"Titel", "Autor", "Status", "Genre", "Verlag", "Seitenzahl", "ISBN", "Sprache", "Bewertung"};
private Object[][] data = {};
ArrayList<Book> lib;

public LibraryTableModel(Library l)
{
//This Method returns the ArrayList in the Library class
lib = l.getList();

int libSize = lib.size();
data = new Object[bib.size()][];

for (Book b : lib)
{
int index = bib.indexOf(b);
//(...)
//CODE HERE gets all the data that is supposed to be displayed
//from each book in the ArrayList
Object[] oA = {tit, aut, sta, gen, ver, sei, isb, spr, bew};

data[index] = oA;
}
}

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];
//When I try to remove a Book, the ArrayOutOfBounds Exception comes from here
}

public Class getColumnClass(int c)
{
return getValueAt(0, c).getClass();
}

public void setValueAt(Object value, int row, int col)
{
data[row][col] = value;
fireTableCellUpdated(row, col);
}

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

GUI类中围绕表和表模型的代码:

public class GUI implements ActionListener
{
JTable table;
LibraryTableModel model;
TableRowSorter<BibliothekTableModel> sorter;
Library lib;
JMenuItem deleteBook;

(...) 库通过 .ser 文件加载

public void showTable() //This method is envoked in the GUI constructor through pressing a button
{
model = new LibraryTableModel(lib);
table.setModel(model);

deleteBook.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int row = table.getSelectedRow();
model.removeRow(row);

//Code that saves the library at this point

table.setModel(new LibraryTableModel(lib));
}
});

popupMenu.add(deleteBook);
table.setComponentPopupMenu(popupMenu);

sorter = new TableRowSorter<BibliothekTableModel>(model);
table.setRowSorter(sorter);
JScrollPane scrollTable = new JScrollPane(table);

//Next is code, that adds this ScrollPane to my Frame
}

最佳答案

When I add a Book to an empty Library, the table doesn't update. However, the Book IS added when I start the program anew (I save the Library class as a .ser file).

没有提供任何信息来演示其工作原理...什么是 .ser 文件?

Then the instance which I am asking about: I have a button that removes Books from the table. the Button itself works fine, but when I remove a book, the program throws an ArrayOutOfBoundsException. When I create the table anew, it updates and the book is removed. What is the problem here, why does the program crash instead of update the table?

有两个问题...

首先,因为您在表上使用 RowSorter,所以 JTable#getSelectedRow 返回的可视行索引和模型中的物理行索引将不会被同样,您需要使用JTable#convertRowIndexToModel

int row = table.getSelectedRow();
row = table.convertRowIndexToModel(row);
model.removeRow(row);

//Code that saves the library at this point

其次,您将从 lib 中删除该书,但不更新内部缓存...

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

模型未使用 lib 作为数据源,而是使用 data 数组,而您尚未更新该数组。

虽然您可以简单地重建 data 数组,但更好的解决方案是摆脱它并直接使用 lib,例如...

public class LibraryTableModel extends AbstractTableModel {

private String[] columnNames = {"Titel", "Autor", "Status", "Genre", "Verlag", "Seitenzahl", "ISBN", "Sprache", "Bewertung"};
private Object[][] data = {};

private Library lib;

public LibraryTableModel(Library l) {
lib = l;
}

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

public int getRowCount() {
return lib.getList().size();
}

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

public Object getValueAt(int row, int col) {
Book book = lib.getList().get(row);
Object value = null;
switch (col) {
case 0:
value = ...;
break;
case 1:
value = ...;
break;
case 2:
value = ...;
break;
case 3:
value = ...;
break;
case 4:
value = ...;
break;
case 5:
value = ...;
break;
case 6:
value = ...;
break;
case 7:
value = ...;
break;
case 8:
value = ...;
break;
}
return value;
//When I try to remove a Book, the ArrayOutOfBounds Exception comes from here
}

public Class getColumnClass(int c) {
// Don't do this, know the actualy value and return it
// Otherwise you could end up with a NullPointerException
return getValueAt(0, c).getClass();
}

public void setValueAt(Object value, int row, int col) {
// Use a simular technquie to getValueAt to extract the Book for the give
// row and update the Book's attributes
fireTableCellUpdated(row, col);
}

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

}

关于java - 从 JTable 中删除对象时出现 ArrayOutOfBoundsException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27893055/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com