我正在开发一个涉及大量课程的Swing应用程序,而且大多数时候它都有效,而有时它会与NullPointerException
崩溃。在控制台中查看时,堆栈跟踪不包含任何类。因此,我无法弄清楚问题的根源在哪里。
这是stacktrace:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.GroupLayout$ComponentInfo.setBounds(GroupLayout.java:3657)
at javax.swing.GroupLayout.layoutContainer(GroupLayout.java:928)
at java.awt.Container.layout(Container.java:1508)
at java.awt.Container.doLayout(Container.java:1497)
at java.awt.Container.validateTree(Container.java:1693)
at java.awt.Container.validateTree(Container.java:1702)
at java.awt.Container.validateTree(Container.java:1702)
at java.awt.Container.validateTree(Container.java:1702)
at java.awt.Container.validateTree(Container.java:1702)
at java.awt.Container.validateTree(Container.java:1702)
at java.awt.Container.validateTree(Container.java:1702)
at java.awt.Container.validateTree(Container.java:1702)
at java.awt.Container.validateTree(Container.java:1702)
at java.awt.Container.validateTree(Container.java:1702)
at java.awt.Container.validate(Container.java:1628)
at javax.swing.RepaintManager$2.run(RepaintManager.java:691)
at javax.swing.RepaintManager$2.run(RepaintManager.java:689)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at javax.swing.RepaintManager.validateInvalidComponents(RepaintManager.java:688)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1679)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
基于堆栈跟踪,我只想知道可能是什么问题。我需要能够指出正确方向的想法。 感谢。
答案 0 :(得分:3)
当发生这种情况时,这是一项艰巨的工作,但有两个地方可以开始:
GroupLayout
的源代码,这表明相关的行可能是int x = horizontalSpring.getOrigin();
(这可能取决于您的JDK版本)。这不是非常有用,但它是一个开始。如果您查看设置horizontalSpring
的位置,有一件事会立即脱颖而出:它在null
方法中设置为dispose()
。因此,您的组件可能已经处理掉了,这就是您收到错误的原因。进一步的线索是,你说大部分时间都可以使用。在绝大多数情况下,这意味着某种线程/同步问题,也许您正在从不属于Event Dispatcher
的线程更新组件层次结构。
答案 1 :(得分:3)
javax.swing.GroupLayout.ComponentInfo.setBounds
方法的代码如下:
public void setBounds(Insets insets, int parentWidth, boolean ltr) {
int x = horizontalSpring.getOrigin();
int w = horizontalSpring.getSize();
int y = verticalSpring.getOrigin();
int h = verticalSpring.getSize();
if (!ltr) {
x = parentWidth - x - w;
}
component.setBounds(x + insets.left, y + insets.top, w, h);
}
如果该方法抛出了NPE,那么insets
,horizontalSpring
,verticalSpring
或component
中的一个(或多个)是{{1} }。 (如果我们知道正好抛出异常的哪一行,就有可能将其缩小到一两种可能性。)
如果没有看到您的代码,那么比这更难做,但我怀疑构建null
的方式存在错误。
@ biziclop关于更新的理论也是合理的。 Swing的组件数据结构不是线程安全的,不应该被swing事件线程以外的任何线程更新。