Java 在布尔类单元格上选择JTable单元格会导致奇怪的异常
所以,我甚至不知道从哪里开始追查这件事的原因。。。我尝试读取异常(它实际上抛出了两个异常!),但只有一行代码引用了我的代码中的任何内容(在第二个异常的一部分)。我将发布最后抛出的实际异常,因为它们相当长 无论如何,我有一个Java 在布尔类单元格上选择JTable单元格会导致奇怪的异常,java,swing,exception,jtable,indexoutofboundsexception,Java,Swing,Exception,Jtable,Indexoutofboundsexception,所以,我甚至不知道从哪里开始追查这件事的原因。。。我尝试读取异常(它实际上抛出了两个异常!),但只有一行代码引用了我的代码中的任何内容(在第二个异常的一部分)。我将发布最后抛出的实际异常,因为它们相当长 无论如何,我有一个JTable,其中每行显示部分对象的一些字段。其中三个字段的类型为Boolean,并显示为复选框。我有一个方法可以监听单元格选择,每当选择单元格时,它都会选择行(需要,因为每一行都与ArrayList中的Part对象相对应)(它还不处理此信息)。当选择任何非布尔值单元格时,已确
JTable
,其中每行显示部分
对象的一些字段。其中三个字段的类型为Boolean
,并显示为复选框。我有一个方法可以监听单元格选择,每当选择单元格时,它都会选择行(需要,因为每一行都与ArrayList
中的Part
对象相对应)(它还不处理此信息)。当选择任何非布尔值单元格时,已确认该方法的行为符合预期
我已将此问题与实际单击复选框(更改状态)隔离开来。当切换Boolean
类型的单元格时会引发异常,而不是在任何其他类型的单元格上。此外,注释掉valueChanged()
方法的主体时不会发生此问题
如果您需要任何其他信息,我很乐意提供。我非常感谢您的帮助;我甚至不知道从哪里开始。
public class SelectionListener implements ListSelectionListener
{
JTable table;
Integer row;
Part selectedPart;
SelectionListener(JTable table)
{
this.table = table;
}
@Override
public void valueChanged(ListSelectionEvent e)
{
row = e.getFirstIndex();
selectedPart = Data.parts.get(row);
}
}
下面是巨大的例外之墙!
编辑:添加其他类。
其他课程如下:
数据类:
public class Data implements Serializable
{
private static final long serialVersionUID = 1L;
// Fields that will be saved:
protected static ArrayList<Part> parts;
// Fields that won't be saved:
private transient ObjectOutputStream outputStream;
private transient ObjectInputStream inputStream;
private transient FileOutputStream fileOut;
private transient FileInputStream fileIn;
private transient File saveFileObject;
private transient Integer retryCount = 0;
protected Data()
{
parts = new ArrayList<>();
loadData(); // I DEALT WITH THAT BITCH
}
protected void saveData()
{
// Attempt to serialize...
try
{
// Second param is false; this causes overwrite of existing file.
fileOut = new FileOutputStream(saveFileObject, false);
outputStream = new ObjectOutputStream(fileOut);
outputStream.writeObject(parts);
outputStream.flush();
outputStream.close();
}
catch(FileNotFoundException e)
{
saveFileObject = new File("savedata.ser");
if(retryCount < 1)
{
retryCount++;
saveData(); // Recursive retry
}
}
catch(IOException e)
{
System.out.println("Caught IOException when saving!"
+ " " + "Attempting to recover!");
retryCount++;
if (retryCount < 1)
{
saveData(); // Recursive retry
}
}
}
@SuppressWarnings("unchecked")
private void loadData()
{
// CLEAN UP TRY CATCH BLOCKS; USE MULTICATCH!!!
// Gets/creates file object.
saveFileObject = new File("savedata.ser");
if(!saveFileObject.exists())
{
try
{
saveFileObject.createNewFile();
}
catch(IOException e)
{
System.out.println("Uh oh...");
System.out.println("");
System.out.println("What? You want an explanation?");
System.out.println("Fine... IOException caught when creating"
+ " new save file!");
}
}
// Create file input stream
try
{
fileIn = new FileInputStream(saveFileObject);
}
catch (FileNotFoundException e)
{
System.out.println("Caught FileNotFoundException!");
}
// Create object input stream
try
{
inputStream = new ObjectInputStream(fileIn);
}
catch(IOException e)
{
System.out.println("Caught IOException when creating object"
+ " input stream! Attempting to recover by returning!");
return;
}
// Try to deserialize
try
{
parts = (ArrayList<Part>)inputStream.readObject();
}
catch(EOFException e)
{
System.out.println("EOFException caught! Attempting to recover!");
return;
}
catch(ClassNotFoundException e)
{
System.out.println("ClassNotFoundException caught");
}
catch(IOException e)
{
System.out.println("IOException caught when deserializing!");
return;
}
// close input stream
try
{
inputStream.close();
}
catch(IOException e)
{
System.out.println("IOException caught when closing input stream!");
return;
}
}
// Accessor Methods;
protected static ArrayList<Part> getParts()
{
return parts;
}
protected Part getPart(int index)
{
return parts.get(index - 1);
}
}
公共类数据实现可序列化
{
私有静态最终长serialVersionUID=1L;
//将保存的字段:
受保护的静态阵列列表部件;
//将不保存的字段:
私有瞬态ObjectOutputStream outputStream;
私有瞬态对象inputStream inputStream;
私有瞬态文件输出流文件输出;
私有瞬态文件输入流文件输入;
私有瞬态文件saveFileObject;
私有瞬态整数retryCount=0;
受保护数据()
{
零件=新的ArrayList();
loadData();//我对付了那个婊子
}
受保护的void saveData()
{
//尝试序列化。。。
尝试
{
//第二个参数为false;这会导致覆盖现有文件。
fileOut=newfileoutputstream(saveFileObject,false);
outputStream=新对象outputStream(文件输出);
outputStream.writeObject(部件);
outputStream.flush();
outputStream.close();
}
catch(filenotfounde异常)
{
saveFileObject=新文件(“savedata.ser”);
如果(retryCount<1)
{
retryCount++;
saveData();//递归重试
}
}
捕获(IOE异常)
{
System.out.println(“保存时捕获IOException!”
+“+”正在尝试恢复!”;
retryCount++;
如果(retryCount<1)
{
saveData();//递归重试
}
}
}
@抑制警告(“未选中”)
私有void loadData()
{
//清理试捕块;使用MULTICATCH!!!
//获取/创建文件对象。
saveFileObject=新文件(“savedata.ser”);
如果(!saveFileObject.exists())
{
尝试
{
saveFileObject.createNewFile();
}
捕获(IOE异常)
{
系统输出打印(“哦…”);
System.out.println(“”);
System.out.println(“什么?需要解释吗?”);
System.out.println(“很好…创建时捕获IOException”
+“新建保存文件!”);
}
}
//创建文件输入流
尝试
{
fileIn=newfileinputstream(saveFileObject);
}
catch(filenotfounde异常)
{
System.out.println(“捕获的FileNotFoundException!”);
}
//创建对象输入流
尝试
{
inputStream=新对象inputStream(fileIn);
}
捕获(IOE异常)
{
System.out.println(“创建对象时捕获IOException”
+“输入流!试图通过返回来恢复!”);
返回;
}
//尝试反序列化
尝试
{
parts=(ArrayList)inputStream.readObject();
}
捕获(EOFEException e)
{
System.out.println(“捕获到EOFEException!正在尝试恢复!”);
返回;
}
catch(classnotfounde异常)
{
System.out.println(“ClassNotFoundException捕获”);
}
捕获(IOE异常)
{
System.out.println(“反序列化时捕获IOException!”);
返回;
}
//关闭输入流
尝试
{
inputStream.close();
}
捕获(IOE异常)
{
System.out.println(“关闭输入流时捕获IOException!”);
返回;
}
}
//存取方法;
受保护的静态ArrayList getParts()
{
返回部件;
}
受保护部分getPart(int索引)
{
返回零件.get(索引-1);
}
}
表格型号:
public class MyTableModel extends RowTableModel<Part>
{
// Declarations:
private static String [] COLUMN_NAMES =
{
"Name",
"Make",
"Part #",
"Alt. part #",
"Price",
"Qty.",
"Auto?",
"Marine?",
"Indust?"
};
private int iterator;
public MyTableModel()
{
super(Arrays.asList(COLUMN_NAMES));
// Set the class of data used by the rows...
setRowClass(Part.class);
// Assigning a class type to each column...
setColumnClass(0, String.class);
setColumnClass(1, String.class);
setColumnClass(2, String.class);
setColumnClass(3, String.class);
setColumnClass(4, Double.class);
setColumnClass(5, Integer.class);
setColumnClass(6, Boolean.class);
setColumnClass(7, Boolean.class);
setColumnClass(8, Boolean.class);
// Add parts from parts ArrayList to table rows...
initialAddParts();
}
@Override
public Object getValueAt(int row, int column)
{
Part part = getRow(row); // Gets the part in question
switch(column)
{
case 0:
return part.getPartName(part);
case 1:
return part.getMake(part);
case 2:
return part.getPartNumber(part);
case 3:
return part.getAltPartNumber(part);
case 4:
return part.getPrice(part);
case 5:
return part.getQuantity(part);
case 6:
return part.isAutomotive(part);
case 7:
return part.isMarine(part);
case 8:
return part.isIndustrial(part);
default:
return null; // This shouldn't ever be called.
}
}
@Override
public void setValueAt(Object newValue, int row, int column)
{
Part part = getRow(row); // Get's the part to modify
switch(column)
{
// Standard cases:
case 0:
part.setName((String) newValue);
break;
case 1:
part.setMake((String) newValue);
break;
case 2:
part.setPartNumber((String) newValue);
break;
case 3:
part.setAltPartNumber((String) newValue);
break;
case 4:
part.setPrice((Double) newValue);
break;
case 5:
part.setQuantity((Integer) newValue);
break;
// Flagging cases:
case 6:
part.toggleAutomotive();
break;
case 7:
part.toggleMarine();
break;
case 8:
part.toggleIndustrial();
break;
// Default: (Should never be reached)
default:
System.out.println("Wait, what?");
return;
}
// Now we can notify the table we messed with it's data
fireTableCellUpdated(row, column);
}
// Initialization Methods:
private void initialAddParts()
{
iterator = 0;
try
{
while (iterator < Data.getParts().size())
{
addRow(Data.getParts().get(iterator));
iterator++;
}
}
catch(NullPointerException e)
{
System.out.println("Caught NullPointerException during "
+ "initialAddParts. Attemting to recover by"
+ " returning...");
return;
}
}
}
公共类MyTableModel扩展了RowTableModel
{
//声明:
私有静态字符串[]列名称=
{
“姓名”,
“制造”,
“第#部分”,
“备选部分#”,
“价格”,
“数量”,
“自动?”,
“海军陆战队?”,
“工业?”
};
私有整数迭代器;
公共MyTableModel()
{
super(Arrays.asList(COLUMN_NAMES));
//设置行使用的数据类别。。。
setRowClass(Part.class);
//将类类型分配给每个
public class MyTableModel extends RowTableModel<Part>
{
// Declarations:
private static String [] COLUMN_NAMES =
{
"Name",
"Make",
"Part #",
"Alt. part #",
"Price",
"Qty.",
"Auto?",
"Marine?",
"Indust?"
};
private int iterator;
public MyTableModel()
{
super(Arrays.asList(COLUMN_NAMES));
// Set the class of data used by the rows...
setRowClass(Part.class);
// Assigning a class type to each column...
setColumnClass(0, String.class);
setColumnClass(1, String.class);
setColumnClass(2, String.class);
setColumnClass(3, String.class);
setColumnClass(4, Double.class);
setColumnClass(5, Integer.class);
setColumnClass(6, Boolean.class);
setColumnClass(7, Boolean.class);
setColumnClass(8, Boolean.class);
// Add parts from parts ArrayList to table rows...
initialAddParts();
}
@Override
public Object getValueAt(int row, int column)
{
Part part = getRow(row); // Gets the part in question
switch(column)
{
case 0:
return part.getPartName(part);
case 1:
return part.getMake(part);
case 2:
return part.getPartNumber(part);
case 3:
return part.getAltPartNumber(part);
case 4:
return part.getPrice(part);
case 5:
return part.getQuantity(part);
case 6:
return part.isAutomotive(part);
case 7:
return part.isMarine(part);
case 8:
return part.isIndustrial(part);
default:
return null; // This shouldn't ever be called.
}
}
@Override
public void setValueAt(Object newValue, int row, int column)
{
Part part = getRow(row); // Get's the part to modify
switch(column)
{
// Standard cases:
case 0:
part.setName((String) newValue);
break;
case 1:
part.setMake((String) newValue);
break;
case 2:
part.setPartNumber((String) newValue);
break;
case 3:
part.setAltPartNumber((String) newValue);
break;
case 4:
part.setPrice((Double) newValue);
break;
case 5:
part.setQuantity((Integer) newValue);
break;
// Flagging cases:
case 6:
part.toggleAutomotive();
break;
case 7:
part.toggleMarine();
break;
case 8:
part.toggleIndustrial();
break;
// Default: (Should never be reached)
default:
System.out.println("Wait, what?");
return;
}
// Now we can notify the table we messed with it's data
fireTableCellUpdated(row, column);
}
// Initialization Methods:
private void initialAddParts()
{
iterator = 0;
try
{
while (iterator < Data.getParts().size())
{
addRow(Data.getParts().get(iterator));
iterator++;
}
}
catch(NullPointerException e)
{
System.out.println("Caught NullPointerException during "
+ "initialAddParts. Attemting to recover by"
+ " returning...");
return;
}
}
}
isAutomotive ^= isAutomotive // the ^= is an XOR operator