Java堆栈跟踪解析困难

3

我有一个堆栈跟踪,需要一些帮助解释:

java.lang.ArrayIndexOutOfBoundsException: 36 >= 36
    at java.util.Vector.elementAt(Vector.java:427)
    at javax.swing.tree.VariableHeightLayoutCache.getNode(VariableHeightLayoutCache.java:976)
    at javax.swing.tree.VariableHeightLayoutCache.getPreferredHeight(VariableHeightLayoutCache.java:274)
    at javax.swing.plaf.basic.BasicTreeUI.updateCachedPreferredSize(BasicTreeUI.java:1823)
    at javax.swing.plaf.basic.BasicTreeUI.getPreferredSize(BasicTreeUI.java:1924)
    at javax.swing.plaf.basic.BasicTreeUI.getPreferredSize(BasicTreeUI.java:1912)
    at javax.swing.JComponent.getPreferredSize(JComponent.java:1642)
    at javax.swing.ScrollPaneLayout.layoutContainer(ScrollPaneLayout.java:769)
    at java.awt.Container.layout(Container.java:1420)
    at java.awt.Container.doLayout(Container.java:1409)
    at java.awt.Container.validateTree(Container.java:1506)
    at java.awt.Container.validate(Container.java:1479)
    at javax.swing.RepaintManager$2.run(RepaintManager.java:698)
    at javax.swing.RepaintManager$2.run(RepaintManager.java:696)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
    at javax.swing.RepaintManager.validateInvalidComponents(RepaintManager.java:695)
    at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1679)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:715)
    at java.awt.EventQueue.access$400(EventQueue.java:82)
    at java.awt.EventQueue$2.run(EventQueue.java:676)
    at java.awt.EventQueue$2.run(EventQueue.java:674)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:685)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

栈中的文件或函数都与我的程序无关,因此我认为它必须是Swing内部的问题。这并不意味着可能不是我的程序出了问题。

我基本上可以理解JVM在做什么 - 看起来它正在重新绘制我的一个位于滚动窗格中的JTree组件(我有几个,所以我不知道它可能是哪个)。

我猜测可能会导致这个错误的原因是树的内容(因此其中的节点数)在重绘期间某个时刻发生了变化,因此存储子节点的向量在计算组件大小时发生了大小变化。

听起来合理吗?

如果是这种情况,我该如何解决?我想要在更新进行时阻止重绘,或者在重绘进行时阻止更新。


只是简单地说,我认为你的假设听起来是有道理的。很抱歉,我无法提供任何规范解决方案。 - NPE
可能需要一些时间,但你应该使用调试器逐步执行代码,找出它失败的确切位置。然后根据这些信息采取行动。 - user1231232141214124
@redFIVE 我很想这样做,但不幸的是这是客户的报告 :( - Majenko
@Majenko,噢,那太糟糕了。你是否拥有与他们相同的源代码,能否重现? - user1231232141214124
这个程序是我的,但是我似乎没有遇到错误(至少目前还没有)。我有另一个想法:树从多个不同的来源更新,可能存在两个线程同时更新导致冲突的情况吗? - Majenko
我觉得Exception的信息很有趣。忍不住要为这个问题点赞。 - Mena
1个回答

1
Swing的正常方式“在更新正在进行时阻止重绘”是将UI的任何更改限制为事件分发线程;如果您不知道(或程序作者不知道),那么这表明它是问题的一部分。错误消息(顺便说一下,我对此毫不滑稽)是说有一个向量(当Swing编写时,通用集合还没有出现)其中有36个元素,在索引0-35;代码试图访问该向量的索引36,因此出现异常。我会查找在发生这种情况的任何条件下正在更改的UI部分-是数据更改,窗口调整大小,还是什么?向量具有36个元素的事实应该给您一些线索-您是否有一个具有那么多按钮或其他类型的地方?我想这也可能是一个具有36个组件的窗口;UI是否有一个组件从窗口中消失的地方?在同一区域,我会查找一些调用诸如paint或repaint之类的代码,这些代码在事件分发线程之外完成-所有这些代码都必须在该线程中完成。如果需要,可以查看SwingUtilities.invokeAndWait()以使用现有代码进行大量操作的方法。

我猜测这是我的树之一。它们很容易有36个以上的元素。我没有进行任何绘制或重新绘制调用,但我确实有一些nodeStructureChanged()调用。有许多节点添加/删除从多个线程中发生,包括计时器线程、从EDT生成的线程和其他地方。 - Majenko
天啊!这刚刚发生在我身上了!至少有帮助,我现在可以复制它。这是一个“随机”的事情,它会在它感觉到时发生(程序没有用户交互)。 - Majenko
实际上,它只是把问题转移到了其他地方。现在我有更多的数据,因为它提供的跟踪信息更有用。它现在是由javax.swing.tree.DefaultTreeModel.nodeStructureChanged()调用触发的。 - Majenko
然而,现在我有了invokeLater,似乎不需要nodeStructureChanged调用了。 - Majenko
1
很高兴能提供帮助。如果你还没有接触过,另一个调试这种问题的工具是SwingUtilities.isEventDispatchThread(),它可以告诉你当前运行该调用的线程是否为(UI)事件派发线程。祝你好运。 - arcy
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接