createImage的问题(int width,int height)

时间:2009-10-09 04:45:24

标签: java image nullpointerexception image.createimage

我有以下代码,它作为游戏的一部分每10毫秒运行一次:

private void gameRender()
{
    if(dbImage == null)
    {
        //createImage() returns null if GraphicsEnvironment.isHeadless()
        //returns true. (java.awt.GraphicsEnvironment)
        dbImage = createImage(PWIDTH, PHEIGHT);
        if(dbImage == null)
        {
            System.out.println("dbImage is null"); //Error recieved
            return;
        }
        else
        dbg = dbImage.getGraphics();
    }

    //clear the background
    dbg.setColor(Color.white);
    dbg.fillRect(0, 0, PWIDTH, PHEIGHT);

    //draw game elements...

    if(gameOver)
    {
        gameOverMessage(dbg);
    }
}

问题是,即使在我尝试定义图像之后,它也会进入if语句,该语句检查Image是否为null。我环顾四周,如果GraphicsEnvironment.isHeadless()返回true,似乎createImage()将返回null。

我不明白isHeadless()方法的目的是什么,但我认为它可能与编译器或IDE有关,所以我尝试了两个,这两个都得到了同样的错误(Eclipse,和BlueJ的)。任何人都知道错误的来源是什么,以及我如何解决它?

提前致谢

乔纳森

............................................... ....................

编辑: 我正在使用java.awt.Component.createImage(int width,int height)。此方法的目的是确保创建和编辑将包含游戏玩家视图的图像,稍后将通过JPanel将其绘制到屏幕上。 如果这有用,可以使用以下代码:

public class Sim2D extends JPanel implements Runnable
{

private static final int PWIDTH = 500;
private static final int PHEIGHT = 400;
private volatile boolean running = true;
private volatile boolean gameOver = false;

private Thread animator;

//gameRender()
private Graphics dbg;
private Image dbImage = null;


public Sim2D()
{   
    setBackground(Color.white);
    setPreferredSize(new Dimension(PWIDTH, PHEIGHT));

    setFocusable(true);
    requestFocus(); //Sim2D now recieves key events
    readyForTermination();

    addMouseListener( new MouseAdapter() {
        public void mousePressed(MouseEvent e)
        { testPress(e.getX(), e.getY()); }
    });
} //end of constructor

private void testPress(int x, int y)
{
    if(!gameOver)
    {
        gameOver = true; //end game at mousepress
    }
} //end of testPress()


private void readyForTermination()
{
    addKeyListener( new KeyAdapter() {
        public void keyPressed(KeyEvent e)
        { int keyCode = e.getKeyCode();
            if((keyCode == KeyEvent.VK_ESCAPE) ||
               (keyCode == KeyEvent.VK_Q) ||
               (keyCode == KeyEvent.VK_END) ||
               ((keyCode == KeyEvent.VK_C) && e.isControlDown()) )
            {
                running = false; //end process on above list of keypresses
            }
        }
    });
} //end of readyForTermination()

public void addNotify()
{
    super.addNotify(); //creates the peer
    startGame();       //start the thread
} //end of addNotify()

public void startGame()
{
    if(animator == null || !running)
    {
        animator = new Thread(this);
        animator.start();
    }
} //end of startGame()


//run method for world
public void run()
{
    while(running)
    {
        long beforeTime, timeDiff, sleepTime;

        beforeTime = System.nanoTime();

        gameUpdate(); //updates objects in game (step event in game)
        gameRender(); //renders image
        paintScreen(); //paints rendered image to screen

        timeDiff = (System.nanoTime() - beforeTime) / 1000000;
        sleepTime = 10 - timeDiff;

        if(sleepTime <= 0) //if took longer than 10ms
        {
            sleepTime = 5; //sleep a bit anyways
        }

        try{
            Thread.sleep(sleepTime); //sleep by allotted time (attempts to keep this loop to about 10ms)
        }
        catch(InterruptedException ex){}

        beforeTime = System.nanoTime();
    }

    System.exit(0);
} //end of run()

private void gameRender()
{
    if(dbImage == null)
    {
        dbImage = createImage(PWIDTH, PHEIGHT);
        if(dbImage == null)
        {
            System.out.println("dbImage is null");
            return;
        }
        else
        dbg = dbImage.getGraphics();
    }

    //clear the background
    dbg.setColor(Color.white);
    dbg.fillRect(0, 0, PWIDTH, PHEIGHT);

    //draw game elements...

    if(gameOver)
    {
        gameOverMessage(dbg);
    }
} //end of gameRender()

} //end of class Sim2D

希望这有助于清理一些事情, 乔纳森

7 个答案:

答案 0 :(得分:3)

我通常使用BufferedImage。而不是createImage(...)。

答案 1 :(得分:3)

在我尝试为分形生成器实现Doublebuffering之后,我遇到了完全相同的问题。我的解决方案 我从一本书中拿了这个例子但是改变了它(不知道结果)我在构造函数中运行createImage INSIDE的方式。这产生了nullpointer。然后我把这个

if (_dbImage == null) {
_dbImage = createImage(getSize().width, getSize().height);
_dbGraphics = (Graphics2D)_dbImage.getGraphics();
}

在update-method中,它工作了!!因为在构造对象之后调用更新。

答案 2 :(得分:2)

根据java.awt.Component的文档,如果组件不可显示,createImage也可以返回null,这很可能是正在发生的事情。

对于您要执行的操作,您应该查看BufferedImage类,因为它与组件无关。

答案 3 :(得分:2)

尝试覆盖正在扩展的JPanel中的addNotify()方法。这是一个“启动”动画的好地方,而不是构造函数。确保包含super.addNotify();

public void addNotify() {       super.addNotify();      开始游戏(); }

祝你好运

答案 4 :(得分:1)

看起来线程的启动时间早于组件实际显示在屏幕上。为了确保不会发生这种情况,您可以覆盖JPanel的paint(Graphics g)方法,并将代码放在paint方法中的线程run()方法中。在你的线程的run()方法中,只需调用repaint()。

e.g:

public void paint(Graphics g){
        **gameUpdate(); //updates objects in game (step event in game)
        gameRender(); //renders image
        paintScreen(); //paints rendered image to screen**
}

并在你的run()方法中:

public void run(){
 while(running)
    {
        long beforeTime, timeDiff, sleepTime;

        beforeTime = System.nanoTime();

        **repaint();**

        timeDiff = (System.nanoTime() - beforeTime) / 1000000;
        sleepTime = 10 - timeDiff;

        if(sleepTime <= 0) //if took longer than 10ms
        {
            sleepTime = 5; //sleep a bit anyways
        }

        try{
            Thread.sleep(sleepTime); //sleep by allotted time (attempts to keep this loop to about 10ms)
        }
        catch(InterruptedException ex){}

        beforeTime = System.nanoTime();
    }
}

答案 5 :(得分:0)

如果您在非GUI环境中运行(例如,在服务器或servlet容器中),isHeadless将仅返回true。

我相信你的问题在你的createImage方法本身。你能给我们更多的背景吗?正在调用哪个createImage方法以及它的实现是什么?

答案 6 :(得分:-1)

package javagame;

import java.awt.BorderLayout;
import javax.swing.JFrame;

/**
 *
 * @author stuart
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        JFrame frame= new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(100, 100, 500, 400);

        frame.add(new GamePanel(), BorderLayout.CENTER);
        frame.setVisible(true);
    }

}