Java - MouseMotionListener导致双缓冲图像返回null

时间:2014-06-25 11:28:34

标签: java nullpointerexception doublebuffered mousemotionlistener

通过我的这个小项目,我创建了一个底部有更大插槽的网格。我想添加鼠标的当前坐标,所以在GridPanel构造函数中我做了: addMouseMotionListener(new MouseMotionAdapter(){ ... mouseMoved and mouseDragged methods ... });

但是,这样做会导致在我的renderGrid()方法中抛出nullpointer异常。 dbg = dbi.getGraphics();上出现错误,我之前遇到错误,dbi = createImage(1000,1000);返回null。在改变了一些东西之后,然后将其恢复到最初的状态它开始工作。我不知道是什么导致了这种变化。这是我的完整代码:

主:

package tileWorld;

import javax.swing.JFrame;

public class Main extends JFrame
{

private GridPanel grid;

public Main()
{
    setVisible(true);
    setResizable(false);
    setSize(1000, 1000);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    grid = new GridPanel();
    add(grid);
}

public static void main(String[] args)
{
    Main m = new Main();
}
}

的GridPanel:

package tileWorld;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.JPanel;

public class GridPanel extends JPanel implements Runnable{

public static final int GRID_WIDTH = 1000, GRID_HEIGHT = 900, PANEL_WIDTH = 1000, PANEL_HEIGHT = 1000;
Dimension panelDim = new Dimension(PANEL_WIDTH, PANEL_HEIGHT);
private Image dbi;
private Graphics dbg;
private boolean running = false;
private Thread gridThread;
private Grid grid;



public GridPanel()
{
    grid = new Grid();


    setPreferredSize(panelDim);
    setVisible(true);
    startGrid();

    // ========= USER INPUTS ===============
    addMouseMotionListener(new MouseMotionAdapter(){

        public void mouseMoved(MouseEvent e)
        {
            System.out.println("Moving!!");
        }
        public void mouseDragged(MouseEvent e)
        {
            System.out.println("Dragging!!");
        }

    }); 
}


private void paintScreen()
{
    Graphics g;

    try
    {
        g = this.getGraphics();

        if(dbg != null && g != null)
        {
            g.drawImage(dbi, 0, 0, null);
        }
        Toolkit.getDefaultToolkit().sync();
        g.dispose();
    }catch(Exception e)
    {
        e.printStackTrace();
    }
}

private void draw(Graphics g)
{
    requestFocus();
    grid.draw(g);
}

private void updateGrid()
{

}

private void renderGrid()
{
    if(dbi == null)
    {
        dbi = createImage(1000,1000);
        dbg = dbi.getGraphics();
        dbg.setColor(Color.GRAY);
        dbg.fillRect(0,0,1000,1000);
    }
    draw(dbg);
}

@Override
public void run() 
{
    while(running)
    {
        updateGrid();
        renderGrid();
        paintScreen();
    }

}

private void startGrid()
{
    if(gridThread == null)
    {
        gridThread = new Thread(this);
        running = true;
        gridThread.start();
    }
}

}

网格:

package tileWorld;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;

public class Grid 
{
private final int GRID_NUM = (GridPanel.GRID_WIDTH / 10)*(GridPanel.GRID_HEIGHT / 10); // the number of "blocks" in the grid.
    // Grid is 100 x 90 blocks (1000x900 px)                    //  ((height/10) x (width/10)) for 10 x 10 px blocks
private Rectangle gridRects[];
private final int BLOCK_WIDTH = 10, BLOCK_HEIGHT = 10;
private int rectX, rectY, actionX1 = 50, actionX2 = 50;
// private final int MOUSE_COORDS_X = 5, MOUSE_COORDS_Y = 950;

public Grid()
{
    gridRects = new Rectangle[GRID_NUM];

    createGrid();
}

private void createGrid()
{
    for (int i =0; i<GRID_NUM; i++)
    {
        if(rectX >= 1000)
        {
            rectX = 0;
            rectY += 10;
        }
        gridRects[i] = new Rectangle(rectX, rectY, BLOCK_WIDTH, BLOCK_HEIGHT);
        rectX += 10;
    }
}

public void draw(Graphics g)
{
    // ======= Draw the lines for the gride
    g.setColor(Color.BLACK);
    for (int i =0; i<GRID_NUM; i++)
    {
        g.drawRect(gridRects[i].x, gridRects[i].y, 10, 10);
    }
    // ====== Draw the action bar slots
    for(int i=0; i < 9; i++) // 9 lines creates 10 slots.. buffer 50 px on each side. 900 px wide, 100 px tall. 90px x 100 px.
    {
        g.drawLine(actionX1, 900, actionX2, 1000);
        actionX1 += 90;
        actionX2 = actionX1;
    }
    // ======= Draw coordinates of mouse current location


}

}

错误讯息:     Exception in thread "Thread-2" java.lang.NullPointerException at tileWorld.GridPanel.renderGrid(GridPanel.java:86) at tileWorld.GridPanel.run(GridPanel.java:99) at java.lang.Thread.run(Unknown Source)

感谢您的时间和建议!我可能只是将它复制并粘贴到一个新项目中吗?有时在我使用C ++ Visual Studios时就是这种情况。 (目前我正在使用Eclipse)。再次感谢你!我正在研究这个问题,如果发现任何问题,我会回复。

1 个答案:

答案 0 :(得分:0)

createImage()的Javadoc说


返回屏幕外可绘制图像,可用于双缓冲。如果组件不可显示,则返回值可以为null。如果GraphicsEnvironment.isHeadless()返回true

,则总会发生这种情况

检查GraphicsEnvironment.isHeadless()以返回true。