Java:与图形无关的错误

Java: An error without an issue concering Graphics

我的代码:

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() 将始终 return 为空。您必须在 创建 ui 之后启动线程 但是无论如何你都不应该使用这种方式来渲染组件。创建一个自己的组件并覆盖 paintComponent(Graphics g) 并在此方法中进行绘制。

您似乎在 canvas 可见之前开始调用 getGraphics(),因为 run() 在添加 [=28] 之前被调用(在 start() 中) =] 到框架。

Here 你可以看到,在这种情况下 returns null

而是在构造函数的末尾调用 start()(不要在 main() 中调用它,而是调用它两次 - 如果您注意到的话)。或者从构造函数中完全删除 start(),并让它一直到 main()。这确保 getGraphics() 在 添加到框架后被称为