Java getGraphics()返回null
我开始学习用Java创建游戏,我使用的方法之一包括BuffereImage。这是我得到的错误:Java getGraphics()返回null,java,swing,Java,Swing,我开始学习用Java创建游戏,我使用的方法之一包括BuffereImage。这是我得到的错误: "Exception in thread "main" java.lang.NullPointerException at tm.Game.init(Game.java:48) at tm.Game.<init>(Game.java:54)" 设置类: package tm; public class Settings { public final int
"Exception in thread "main" java.lang.NullPointerException
at tm.Game.init(Game.java:48)
at tm.Game.<init>(Game.java:54)"
设置类:
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()
的组件文档中:
返回屏幕外可绘制的图像,该图像可用于双击
缓冲如果组件不可用,则返回值可能为空
可显示。如果
GraphicsEnvironment.ishadless()返回true
然后,在offscreenImage上调用
getGraphics()
时,会出现NullPointerException异常,该异常为null。因为createImage仅在组件“可显示”后才能工作,例如,它连接到可见的JFrame上,所以当前代码无法工作
有几种方法可以解决这个问题
- 在调用create组件之前,将JFrame作为参数添加到ctor中,并将游戏添加到JFrame中-只要JFrame.Add不调用部分初始化的游戏实例覆盖的任何方法,这应该可以工作
Game(JFrame jf){ jf.add(this); ... } JFrame mainFrame = new JFrame(); mainFrame.setVisible(true); Game game = new Game(mainFrame);
- 创建一个附加的init方法,在将游戏添加到JFrame后调用该方法。这很难看,因为在调用此方法之前,游戏对象并没有真正完全初始化
Game game = new Game(); JFrame mainFrame = new JFrame(); mainFrame.add(game); mainFrame.setVisible(true); game.init();
- 找出组件何时可显示就是监听HierarchyEvent。您可以修改答案中显示的侦听器以调用createImage,而不是打印“showing”。(该答案提供的类还需要一个
才能工作)扩展层次侦听器
offscreenImage = (BufferedImage) createImage(Settings.GAME`WIDTH, Settings.GAME_HEIGHT);
offscr = offscreenImage.getGraphics();
此代码应位于函数绘制中。为了得到结果,游戏类应该这样定义。另一个技巧是最好将设置类中的变量声明为publicstaticfinal,这样就可以以静态方式访问它们。对游戏类进行如下定义的小改动。我想这应该对你有帮助
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
在哪里定义?@DanWImage java.awt.Component.createImage(int-width,int-height)
您是否尝试过用super()
调用JPanel中的构造函数?为什么您不只是序列化类,而是抑制有关序列化的警告?@DanW您能解释一下如何快速完成吗?我对Java不是很有经验。Kierrow,我真的不知道,我在创建和设置类时很匆忙,我通常会序列化它。GraphicsEnvironment.ishadless()
返回false
,那么解决这个问题的好方法是什么呢?@ThomasMosey您的JPanel没有注册JFrame,创建JFrame,使其可见并将面板添加到其中。+1 josefxGraphicsEnvironment.isHeadless()
应返回false,但请确保isDisplayable()
也返回true。@josefx编辑过的OP,对不起,忘了在我用于JFrame中添加类。您必须从init()
中删除createImage()
,或调用init()
仅当JPanel添加到JFrame而不是其构造函数中时。
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();
}
}