Java图形上的NullPointerException [英] NullPointerException on Java graphics

查看:163
本文介绍了Java图形上的NullPointerException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现一种方法来绘制网格的特定部分。为此,我重写了paintComponent方法:

I'm trying to implement a method to paint a specific portion of a grid. To do so I overrided the paintComponent method:

public class Frame extends JPanel {
...
@Override
public void paintComponent( Graphics g ) {

    super.paintComponent( g );

    g.clearRect(0, 0, getWidth(), getHeight());
    this.rectWidth = getWidth() / this.NUM_COLUMNS;
    this.rectHeight = getHeight() / this.NUM_ROWS;

    for (int i = 0; i < NUM_ROWS; i++) {

        for (int j = 0; j < NUM_COLUMNS; j++) {

            int x = i * this.rectWidth;
            int y = j * this.rectHeight;
            g.setColor( Color.WHITE );
            g.fillRect( x, y, this.rectWidth, this.rectHeight );

        }
    }

}
}

哪个好,但是我想在函数调用上绘制特定部分,如下所示:

Which is fine but, then I want to paint specific portions on a function call like this:

public void specificPaint( int coordinateX, int coordinateY, Color color ){

    Graphics g = this.getGraphics();

    int x = coordinateX * this.rectWidth;
    int y = coordinateY * this.rectHeight;

    g.setColor( color );
    g.fillRect( x, y, this.rectWidth, this.rectWidth);

}

电话应该像

// TESTING
    this.modelMap.specificPaint( 40,40,Color.RED );
    this.modelMap.specificPaint( 10,10,Color.RED );
    this.modelMap.specificPaint( 20,25,Color.BLUE );

我的Graphics对象出现空指针错误,为什么我无法恢复和使用它?

I'm getting a null pointer error with the Graphics object, why can't I recover and use it?

有更好的方法吗?

推荐答案

永远不要做从组件中获取Graphics对象时:

Never do this when getting a Graphics object from a component:

Graphics g = this.getGraphics();

这样获得的Graphics对象不会长寿,这会导致NPE(如你正在获得)或一个不再重绘的图像。而是在paintComponent方法中进行绘制。请注意,您可以调用 repaint(...)并通过传入Rectangle参数指定要绘制的特定Rectangle。

The Graphics object thus obtained will not be long-lived, and this can result in either NPE (like you're getting) or an image that does not persist on repaints. Instead, do your drawing within the paintComponent method. Note that you can call repaint(...) and specify a particular Rectangle to paint by passing in a Rectangle parameter.

请注意,你可以在BufferedImage上调用 getGraphics()并绘制它,然后在paintComponent方法中绘制BufferedImage,如果你想做点绘图的话不要移动。

Note that you can call getGraphics() on a BufferedImage and draw to it, and then draw the BufferedImage within your paintComponent method if you want to do spot drawing that does not move.

一个不相关的建议:避免调用你的类 Frame ,因为这可能导致名字冲突如果你不小心的话, java.awt.Frame class。

An unrelated recommendation: Avoid calling your class Frame as this can result in a name clash with the java.awt.Frame class if you're not careful.

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.*;

@SuppressWarnings("serial")
public class MyPanel extends JPanel {
    private static final int PREF_W = 400;
    private static final int PREF_H = PREF_W;
    private int cols;
    private int rows;
    private static final Color BG = Color.BLACK;
    private static final int GAP = 1;
    private BufferedImage img;
    private int rectWidth;
    private int rectHeight;

    public MyPanel(int rows, int cols) {
        this.cols = cols;
        this.rows = rows;
        img = createMyImage();
    }

    public void specificPaint(int coordinateX, int coordinateY, Color color) {
        Graphics g = img.getGraphics(); // get img's Graphics object
        int x = coordinateX * this.rectWidth + GAP;
        int y = coordinateY * this.rectHeight + GAP;
        g.setColor(color);
        g.fillRect(x, y, rectWidth - 2 * GAP, rectWidth - 2 * GAP);
        g.dispose();
        repaint();
    }

    private BufferedImage createMyImage() {
        img = new BufferedImage(PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        g2.setBackground(BG);
        g2.clearRect(0, 0, img.getWidth(), img.getHeight());
        this.rectWidth = img.getWidth() / cols;
        this.rectHeight = img.getHeight() / rows;

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                int x = i * this.rectWidth + GAP;
                int y = j * this.rectHeight + GAP;
                g2.setColor(Color.WHITE);
                g2.fillRect(x, y, this.rectWidth - 2 * GAP, this.rectHeight - 2 * GAP);
            }
        }
        g2.dispose();
        return img;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (img != null) {
            g.drawImage(img, 0, 0, this);
        }

        // if you need to draw changing non-static images, do it here
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet() || img == null) {
            return super.getPreferredSize();
        }
        int w = img.getWidth();
        int h = img.getHeight();
        return new Dimension(w, h);
    }

    private static void createAndShowGui() {
        MyPanel modelMap = new MyPanel(50, 50);
        JFrame frame = new JFrame("MyPanel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(modelMap);
        frame.pack();
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        modelMap.specificPaint( 40,40,Color.RED );
        modelMap.specificPaint( 10,10,Color.RED );
        modelMap.specificPaint( 20,25,Color.BLUE );
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

这篇关于Java图形上的NullPointerException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆