Java &引用;AWT-EventQueue-0“;NullpointerException不一致错误消息

Java &引用;AWT-EventQueue-0“;NullpointerException不一致错误消息,java,swing,nullpointerexception,paintcomponent,Java,Swing,Nullpointerexception,Paintcomponent,我在启动Java应用程序时收到以下错误消息: Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at engine.Display.GamePanel.paintComponent(GamePanel.java:102) at javax.swing.JComponent.paint(Unknown Source) at javax.swing.JComponent.paintChildren(Unknow

我在启动Java应用程序时收到以下错误消息:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at engine.Display.GamePanel.paintComponent(GamePanel.java:102)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JLayeredPane.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
at java.awt.Container.paint(Unknown Source)
at java.awt.Window.paint(Unknown Source)
at javax.swing.RepaintManager$3.run(Unknown Source)
at javax.swing.RepaintManager$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$1100(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$400(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
该应用程序没有关闭,它让我正常运行,没有视觉缺陷等,但我仍然收到这个错误消息,有时当我启动应用程序

它指向我自己代码的唯一一行是GamePanel类中的第102行,这是我这里的paintComponent方法:

    @Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    //g.drawImage(test, picX, picY, picSizeX, picSizeY, null);
    mao.Draw(picX, picY, g);
}
在mao内部,我们有这样一张图:

    public void Draw(int x, int y, Graphics g){
    Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(characterImage, x, y, null);
        g2d.drawRect(x, y, getWidth(), getHeight());
}

我已经解决了这个问题,但似乎找不到错误。

paintComponent()
方法中,异常是
NullPointerException

所以问题就在这里,而不是在
Draw()
方法中。在
paintComponent()
中,您可以访问
mao
标识符,我假定它是
GamePanel
类的一个属性

Swing中的所有绘制都是在EDT线程上完成的,我假设您初始化并设置此
mao
属性不在EDT线程上=>这是一个同步问题。在EDT线程上指定
mao
属性,或者使其同步,以便多个访问它的线程正确地看到其真实值


只有一次或极少数情况下出现此异常,应用程序才能正常工作,因为只有
paintComponent()
将被中止,但随后绘制组件的尝试可能会成功(如果
mao
最终被EDT线程看到或同时被修改).

错误是由GamePanel.java的第102行引起的,我相信这是错误的

  mao.Draw(picX, picY, g);
因为
mao
尚未初始化,即在调用方法时具有值
null
。可能您的应用程序尚未完全初始化,但游戏面板已经显示

您可以执行以下操作来检查是否存在这种情况:

if (mao != null) {
    mao.Draw(picX, picY, g);
}

mao.Draw(picX,picY,g);是关于糟糕的实践,不要从paintComponent创建、初始化和初始化任何对象,在将所有对象放入数组之前准备这些对象,并在paintComponent内部循环此数组,应通过编程(在EDT上)调用repaint()@mKorbel我真的很难理解您的意思,你能用你的整个信息澄清你的意思吗?你是对的,事实就是这样,在我的paintComponent中像这样保留它是一种不好的做法,还是为了更高效的代码而修改它更好?取决于:如果
mao
中的实例没有被修改,我宁愿在显示GUI之前对其进行初始化;如果更改了(例如,通过用户交互),我更喜欢使用
if
的解决方案。因为它显然是一个游戏面板,所以在我初始化mao=新mao()之前创建它可能更合适;在它被绘制之前,但我不确定为什么它仍然是空的