JAVA - JTable&的奇怪问题(可能是线程问题)模型

时间:2010-06-16 11:10:17

标签: java swing multithreading jtable exception

我正在使用2个表(JTable)及其DefaultTableModels。 第一个表已经填充。 为第一个表的每一行填充第二个表(使用SQL查询)。 我的目的是导出第一个表的每一行,并在Excel文件中使用它的第二行。

我正在使用for(对于第一个表的每一行),我在Excel文件中写了第一个表的一行,然后我填充第二个表(对于第一个表的这一行),我从表中获取每一行(实际上来自它的模型)并将其放在第一个表的当前行下的Excel文件中。 这意味着如果我在第一个表中有n行,我将清除并再次填充第二个表n次。

所有这些代码都是在一个单独的线程中调用的。

问题是: 一切都工作得很好ecxept我得到一些例外。 奇怪的是,我的结果中没有任何错误。 Excel文件很完美。

例外的一些行是:

线程中的异常“AWT-EventQueue-0”java.lang.ArrayIndexOutOfBoundsException:0> = 0 在java.util.Vector.elementAt(Vector.java:427) 在javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:632) 在javax.swing.JComponent.paint(JComponent.java:1017) 在javax.swing.RepaintManager.paint(RepaintManager.java:1220) 在javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:803)

我假设问题在于,在我尝试从中获取任何数据之前,第二个表需要更多时间来填充。这就是我在异常中看到RepaintManager和paintDirtyRegions的原因。 我做的另一件事是我在调试模式下运行我的程序,并在第二个表的每个填充之后放置一个断点。然后我按F5继续第二个表的每个人口,没有例外。该计划结束时没有任何例外。 这是另一个重要的事实告诉我,在这种情况下,我给了桌子足够的时间来填充。

当然你会问我:

  • 如果您的程序运行正常,为什么还要关注异常? 我关心避免任何未来的问题,我关心更好地理解Java和Java GUI和线程。

  • 为什么依赖GUI组件(及其模型)来获取信息,为什么不重新创建使用SQL查询填充表的结果集并从结果集中获取信息? 那将是最好和最正确的方式。事实上,我已准备好表格代码,而且我更容易从中获取信息。但正确的方法是从数据库直接获取所有内容。无论如何我做了什么提出了我的问题,并回答它将帮助我了解更多关于java的事情。所以我发布了它。

2 个答案:

答案 0 :(得分:2)

除了一些方法调用外,Swing API不是线程安全的:重绘重新验证无效。所有其他电话除非另有说明,否则特定班级必须在事件发送线程上进行。

从生成的后台/工作线程转移此类呼叫处理可以通过 SwingUtilities.invokeLater() SwingUtilities.invokeAndWait()完成。

还有一些关于JTable和任何已附加到javax.swing package summary javadocs中的实例的TableModel的特定讨论。这两者都不是线程安全的,因此任何从它们访问数据的调用都必须在事件调度线程上执行。

这是您遇到的异常的最可能原因,并且在调试器中运行时遇到的不同行为是竞争条件的典型标志。通过引入自己的锁等也没有可靠的方法来解决这个问题。这样的做法总是会导致麻烦(例如Swing库内部的事件调度队列锁定死锁)从长远来看,因为Swing真的,真的是不是设计为线程安全的。

答案 1 :(得分:1)

发生异常是因为其中一个表模型为getValueAt(int row,int column)调用返回null。其原因可能是摆动或数据模型中的内部问题,因为您使用辅助线程来访问数据模型。 swing api明确规定你不能以你描述的方式使用辅助线程。

以下文章提供了有关swing中单线程规则的更多详细信息。

http://java.sun.com/products/jfc/tsc/articles/threads/threads3.html