1

我有一个简单的JFrame和一个JTable框架。用户可以将数据提供到表的行中。要求之一是关闭框架后可以保存或丢弃新数据。我认为完成此行为的最简单方法如下:

  1. 覆盖setVisible()框架的方法并克隆DefaultTableModel的数据向量。

  2. 将 a 添加WindowListener到框架并对WindowClosing事件做出反应。这样,窗口侦听器可以决定是否应该将模型重置为之前保存的模型。

这是相关的代码片段:

@Override
public void setVisible(boolean b) {
  //save the original models only if setVisible invoked with true (do not save the model when hiding the frame)
  if (b) {
    Vector cloned = (Vector) userTableModel.getDataVector().clone();
    Vector headerNames = new Vector();
    originalModel = new CustomTableModel(cloned, headerNames);
  }
  super.setVisible(b);
}

事实上,奇怪的事情正在发生。克隆数据向量后,无法呈现表,这导致以下异常:

线程“AWT-EventQueue-0”中的异常 java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
    在 java.util.Vector.elementAt(Vector.java:470)
    在 javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:650)
    在 asc.model.CustomTableModel.getValueAt(CustomTableModel.java:74)
    在 javax.swing.JTable.getValueAt(JTable.java:2720)

该表与该表没有originalModel任何关系。这对我来说是一个惊喜,因为理论上,克隆不应该影响表的模型。originalModel 的目的是保存对新创建的表模型副本的引用。在我注释掉 的创建后originalModel,一切正常。

String另一个有趣的事情是,当我向向量添加一个空时headerNames,表格渲染器会抛出几乎相同的ArrayIndexOutOfBounds异常,但以这个结尾:

线程“AWT-EventQueue-0”中的异常 java.lang.ArrayIndexOutOfBoundsException: 1 >= 1

在这种情况下,第一行的第一列完美呈现。

MyCustomTableModel是从 扩展而来的DefaultTableModel,它没有使用任何特殊的方法。构造函数只是将数据向量和标头向量传递给超类。

我希望有人可以帮助解决问题。提前致谢。

4

3 回答 3

1

我认为你有一个错误Vector cloned,因为你试图返回平原Vector,但JTable是基于Vector<Vector>你的情况

于 2012-04-07T23:57:47.857 回答
1

headerNames 向量的长度必须与您拥有的列数相匹配。这很令人困惑,因为 Vector 被转换为 CustomTableModel 类中的标题名称数组,这就是它显示为 AIOOBE 的原因。

因此,首先通过它在 headerNames 向量/数组中查找第一列(索引 0 处的列)并失败,发送 0 >= 0 版本的错误。一旦你添加了一个列名字符串(尽管它可能是空的),它会成功呈现整个第一列,然后去寻找第二列(索引 1 处的列)。它失败了,因为 headerNames 向量中没有第二个元素,并给出 1 >= 1 版本的错误。

确保 headerNames 向量具有正确数量的值(与数据向量中的列数匹配),您应该一切顺利。

注意 - clone() 方法正在制作数据的 SHALLOW 副本,因此用户对单元格中的数据所做的更改仍会更改原始对象。本文可能对此有所帮助:http: //javatechniques.com/blog/faster-deep-copies-of-java-objects/

于 2012-04-08T00:04:07.687 回答
1

的实现AbstractTableModel将使您可以直接控制数据结构。这个例子说明了Map<String, String>,但选择是任意的。

于 2012-04-08T01:52:57.287 回答