Java:一个没有图形问题的错误

Java:一个没有图形问题的错误,java,graphics,runtime-error,Java,Graphics,Runtime Error,我的代码: package data; import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Toolkit; import java.awt.image.BufferedImage; import javax.swing.JFrame; public c

我的代码:

package data;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

public class Main extends Canvas implements Runnable {
    private static final long serialVersionUID = 0L;

    private JFrame frame;
    private Hikari hikari = new Hikari(this);
    private BufferedImage biHikari;

    private boolean running = false;
    private double fps = 10;
    private double millUpdates = 1000 / fps;
    long lastUpdate;
    long lastTick;
    int count = 0;

    public Main() {
        start();
        frame = new JFrame("Project Darkness");
        frame.setMinimumSize(new Dimension(640, 480));
        frame.setResizable(false);
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
        frame.setLocation(dim.width / 2 - frame.getSize().width / 2, dim.height / 2 - frame.getSize().height / 2);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.add(this, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
        frame.setFocusable(true);
    }

    private void start() {
        running = true;
        new Thread(this).start();
    }

public void run() {
    lastUpdate = (long) (System.currentTimeMillis() / millUpdates);
    lastTick = System.currentTimeMillis() / 1000;
    Graphics g = this.getGraphics();
    while (running) {
        if (toUpdate("Update")) {
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, getWidth(), getHeight());

                biHikari = hikari.getFrame(1);
                g.drawImage(biHikari, hikari.getX(), hikari.getY(), null);

        }
        toUpdate("Tick");
    }
}

private boolean toUpdate(String string) {
    switch (string) {
    case "Update":
        long thisUpdate = (long) (System.currentTimeMillis() / millUpdates);
        if (thisUpdate != lastUpdate) {
            lastUpdate = thisUpdate;
            count++;
            return true;
        }
        break;
    case "Tick":
        long thisTick = System.currentTimeMillis() / 1000;
        if (thisTick != lastTick) {
            lastTick = thisTick;
            System.out.println(count);
            count = 0;
        }
        break;
    }
    return false;
}

public static void main(String[] args0) {
    new Main().start();
}

}
错误来自以下几行:

Graphics g = this.getGraphics();
while (running) {
    if (toUpdate("Update")) {
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, getWidth(), getHeight());

            biHikari = hikari.getFrame(1);
            g.drawImage(biHikari, hikari.getX(), hikari.getY(), null);

    }
错误本身是:

Exception in thread "Thread-1" java.lang.NullPointerException
at data.Main.run(Main.java:57)
at java.lang.Thread.run(Unknown Source)
第57行

g.setColor(Color.BLACK);

它的工作原理是完美的,但是当试图在屏幕上画图时仍然会出现错误,即使它仍然画出它所说的内容,背景是黑色的,然后它画出了biHiakri。为什么会出现此错误?

错误本身会发生,因为在将组件添加到帧之前,您试图从组件生成图形对象。如果组件没有父级,
getGraphics()
将始终返回null。您必须在创建ui之后启动线程但是无论如何都不应该使用这种方式渲染组件。创建自己的组件并替代
paintComponent(Graphics g)
,并在此方法内进行绘制。

在画布可见之前,您似乎开始调用
getGraphics()
,因为在将画布添加到帧之前调用了
run()

您可以看到,在这种情况下,它返回
null


相反,在构造函数末尾调用
start()
(不要在
main()
中调用它,如果您注意到的话,可以调用它两次)。或者从构造函数中完全删除
start()
,并将其全部添加到
main()
。这确保在添加到帧后调用
getGraphics()

如果未显示
组件
,则返回
null
,我没有注意到,删除start();从Main()开始,谢谢你。