[英]Java getGraphics() returning null
我开始学习用Java创建游戏,我正在使用的方法之一包括BufferedImage。 这是我得到的错误:
"Exception in thread "main" java.lang.NullPointerException
at tm.Game.init(Game.java:48)
at tm.Game.<init>(Game.java:54)"
从这段代码:
package tm;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class Game extends JPanel implements Runnable {
private Settings Settings;
private Thread t;
private BufferedImage offscreenImage;
private Graphics offscr;
public void run() {
while(true) {
repaint();
try {
Thread.sleep(1000/30);
} catch (InterruptedException e) { }
}
}
public void paint(Graphics g) {
offscr.setColor(Color.blue);
offscr.fillRect(0, 0, Settings.GAME_WIDTH, Settings.GAME_HEIGHT);
offscr.setColor(Color.white);
offscr.drawString("Lolz", 10, 10);
g.drawImage(offscreenImage, 0, 0, this);
}
public void update(Graphics g) {
paint(g);
}
public void init() {
t = new Thread(this);
t.start();
offscreenImage = (BufferedImage) createImage(Settings.GAME_WIDTH, Settings.GAME_HEIGHT);
offscr = offscreenImage.getGraphics();
}
public Game() {
Settings = new Settings();
init();
}
}
设置类:
package tm;
public class Settings {
public final int GAME_WIDTH = 500;
public final int GAME_HEIGHT = 500;
}
屏幕类:
package tm;
import javax.swing.JFrame;
public class Screen extends JFrame {
private static final long serialVersionUID = 1L;
private JFrame mainScreen;
private Game mainGame;
private Settings Settings;
public Screen() {
mainGame = new Game();
Settings = new Settings();
mainScreen = new JFrame();
mainScreen.add(mainGame);
mainScreen.setSize(Settings.GAME_WIDTH, Settings.GAME_HEIGHT);
mainScreen.setTitle("Lolz");
mainScreen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainScreen.setResizable(false);
mainScreen.setVisible(true);
}
public static void main(String[] args) {
new Screen();
}
}
返回null的getGraphics()
不是前一个函数createImage()
。 从createImage()
的组件文档:
返回屏幕外可绘制图像,可用于双缓冲。 如果组件不可显示,则返回值可以为null。 如果GraphicsEnvironment.isHeadless()返回true,则总会发生这种情况。
然后在offscreenImage上调用getGraphics()
时得到NullPointerException,该值为null。
抛出NullPointer异常的原因是您在错误的位置初始化了offScreenImage和offScr。
offscreenImage = (BufferedImage) createImage(Settings.GAME`WIDTH, Settings.GAME_HEIGHT);
offscr = offscreenImage.getGraphics();
这段代码应该在函数paint中。 为了得到结果,Game类应该像这样定义。 另外一个提示最好将变量inn settings类声明为public static final,以便可以以静态方式访问它们。 如下定义,对您的Game类进行少许更改。 我认为这应该对你有帮助。
package tm;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import tm.Screen.Settings;
public class Game extends JPanel implements Runnable {
// private Setting Settings;
private Thread t;
private BufferedImage offscreenImage;
private Graphics offscr;
public void run() {
while (true) {
repaint();
try {
Thread.sleep(1000 / 30);
} catch (InterruptedException e) {
}
}
}
public void paint(Graphics g) {
if (offscreenImage == null) {
offscreenImage = (BufferedImage) createImage(Settings.GAME_WIDTH,
Settings.GAME_HEIGHT);
}
offscr = offscreenImage.getGraphics();
offscr.setColor(Color.black);
offscr.fillRect(0, 0, Settings.GAME_WIDTH, Settings.GAME_HEIGHT);
offscr.setColor(Color.white);
offscr.drawString("Lolz", 10, 10);
g.drawImage(offscreenImage, 0, 0, this);
}
public void update(Graphics g) {
paint(g);
}
public void init() {
t = new Thread(this);
t.start();
}
public Game() {
init();
}
}
由于createImage仅在Component“可显示”之后才起作用,例如它附加到可见的JFrame,您当前的代码将无法工作。
有几种方法可以解决它。
将JFrame作为参数添加到ctor并在调用create component之前将Game添加到JFrame - 只要JFrame.add不调用部分初始化的Game实例覆盖的任何方法,这应该有效。
Game(JFrame jf){ jf.add(this); ... } JFrame mainFrame = new JFrame(); mainFrame.setVisible(true); Game game = new Game(mainFrame);
创建一个额外的init方法,在将游戏添加到JFrame后调用。 这很难看,因为在调用此方法之前,Game对象尚未完全初始化。
Game game = new Game(); JFrame mainFrame = new JFrame(); mainFrame.add(game); mainFrame.setVisible(true); game.init();
找出组件何时可显示的一种方法是侦听HierarchyEvent。 您可以修改答案中显示的监听器来调用createImage而不是打印“显示”。 (该答案提供的类还需要extends HierarchyListener
才能工作)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.