我是Java的新手。我现在只学了半年了。现在我正在为一所学校项目工作,我已经完成了一个完整的墙:
我基本上是制作一个程序来管理自己的书籍。我有一个类“Books”,它保存book对象的数据。然后是“库”类,其中包含一个ArrayList of Books。对于TableModel,我使用扩展AbstractTableModel的类(“LibraryTableModel”)。然后我有一个显示表格的GUI类。
该表实际上有效,但有两个程序崩溃的情况:
当我将书籍添加到空库时,表格不会更新。但是,当我重新启动程序时添加了Book IS(我将Library类保存为.ser文件)。
然后我问的实例:我有一个从表中删除Books的按钮。 Button本身工作正常,但是当我删除一本书时,程序会抛出一个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);
}
围绕表和tablemodel旋转的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
}
答案 0 :(得分:1)
当我将书籍添加到空库时,表格不会更新。但是,当我重新启动程序时添加了Book IS(我将Library类保存为.ser文件)。
没有提供任何信息来说明这是如何工作的...以及.ser
文件是什么?
然后我问的实例:我有一个按钮 从表中删除书籍。按钮本身工作正常,但是当我 删除一本书,该程序抛出一个ArrayOutOfBoundsException。当我 重新创建表,它会更新并删除书。是什么 问题在这里,为什么程序崩溃而不是更新表?
有两个问题......
首先,因为您在表上使用RowSorter
,JTable#getSelectedRow
返回的可视行索引和模型中的物理行索引将不相同,您需要使用{ {3}}
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);
}
}