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

发布于 2024-09-05 17:23:30 字数 1333 浏览 3 评论 0原文

我正在使用 2 个表 (JTable) 及其 DefaultTableModel。 第一个表已填充。 第二个表是为第一个表的每一行填充的(使用 SQL 查询)。 我的目的是将第一个表的每一行及其第二个表的相应行导出到 Excel 文件中。

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

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

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

一些异常行是:

Exception in thread "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的事情。所以我发布了它。

I am using 2 Tables (JTable) with their DefaultTableModels.
The first table is already populated.
The second table is populated for each row of the first table (using an SQL Query).
My purpose is to export every line of the first table with it's respective lines of the second in an Excel File.

I am doing it with a for (for each line of 1st table), in which I write a line of the 1st table in the Excel File, then I populate the 2nd table (for this line of 1st Table), I get every line from the Table (from it's Model actually) and put it in the Excel File under the current line of 1st table.
This means that if I have n lines in first table I will clear and populate again the second table n times.

All this code is called in a seperate thread.

THE PROBLEM IS:
Everything works perfectly fine ecxept that I am getting some exceptions.
The strange thing is that I'm not getting anything false in my result.
The Excel file is perfect.

Some of the lines of the exceptions are:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
at java.util.Vector.elementAt(Vector.java:427)
at javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:632)
at javax.swing.JComponent.paint(JComponent.java:1017)
at javax.swing.RepaintManager.paint(RepaintManager.java:1220)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:803)

I am assuming that the problem lies in the fact that the second table needs some more time to be populated before I try to get any data from it. That's why I see RepaintManager and paintDirtyRegions in my exceptions.
Another thing I did is that I ran my program in debug mode and I put a breakpoint after each population of the 2nd table. Then I pressed F5 to continue for each population of 2nd table and no exception appeared. The program came to it's end without any exceptions.
This is another important fact that tells me that maybe in this case I gave the table enough time to be populated.

Of course you will ask me:

  • If your program works fine, why do you care about the exceptions?
    I care for avoiding any future problems and I care to have a better understanding of Java and Java GUI and threads.

  • Why do you depend on a GUI component (and it's model) to get your information and why don't you recreate the resultset that populates your tables using an SQL Query and get your info from the resultset?
    That would be the best and the right way. The fact is that I have the tables code ready and it was easier for me to just get the info from them. But the right way would be to get everything direct from database. Anyway what I did brought out my question, and answering it would help me understand more things about java. So I posted it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

゛清羽墨安 2024-09-12 17:23:30

Swing API 不是线程安全的,除了一些方法调用:repaintrevalidateinvalidate。除非针对特定类另有说明,否则所有其他调用必须在事件调度线程上进行。

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

javax.swing 包摘要 javadocs。两者都不是线程安全的,因此从它们访问数据的任何调用都必须在事件调度线程上执行。

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

The Swing API is not thread-safe except for a few method calls: repaint, revalidate, and invalidate. All other calls unless otherwise noted for a specific class must be made on the Event Dispatch Thread.

Transferring such call processing from a spawned background/worker thread can be done via SwingUtilities.invokeLater() or SwingUtilities.invokeAndWait().

There is also some specific discussion regarding both JTable and any TableModel that has been attached to an instance of it in the javax.swing package summary javadocs. Neither is thread-safe, so any calls accessing data from them must be performed on the Event Dispatch Thread.

This is the most probable cause of the exceptions you are encountering, and the different behavior that you experience when running in a debugger is a classic sign of a race condition. There is also no reliable way to hack around this via introducing your own locks, etc. Such practices invariably lead to trouble (such as deadlocks with the Event Dispatch Queue lock deep inside the Swing library) in the long run since Swing really, truly was not designed to be thread-safe.

淡淡の花香 2024-09-12 17:23:30

发生异常的原因是表模型之一为 getValueAt(int row,int column) 调用返回 null。其原因可能是 swing 或数据模型的内部问题,因为您正在使用辅助线程来访问数据模型。 swing api 特别声明您不能按照您描述的方式使用辅助线程。

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

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

The exception is happening because one of the table models is returning null for a getValueAt(int row,int column) call. The reason for this is probably an internal issue in swing or the data model due to the fact that you are using a secondary thread to access the data models. The swing api specifically states that you can not use a secondary thread in the way you described.

The following article provides further details on the single thread rule in swing.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文