练习paintComponent方法

时间:2015-04-08 20:28:23

标签: java nullpointerexception paintcomponent

我想练习paintComponent方法。我的程序由两个类(test和paintClass)组成,位于不同的文件中。我想通过使用paintComponent方法垂直和水平绘制线条将区域划分为25个方块。我的构造函数现在只有paintComponent。我知道它效率不高但我将来会添加按钮,标签和其他东西,所以我需要使用这样的程序。当我运行程序时,我得到一个nullpointerexception错误。你可以帮忙吗?

编辑:我将页面更改为g并在代码中添加了一些行。仍然有同样的错误。

import javax.swing.*;
import java.awt.*;

public class test
{

    public static void main(String[] args) 
    {

        JFrame frame = new JFrame("buttons");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        paintClass paint = new paintClass();//This line has error.
        paint.repaint();//ADDED
        frame.add(paint);
        frame.pack();
        frame.setVisible(true);
    }
}



import javax.swing.*;
import java.awt.*;

public class paintClass extends JPanel
{
    private Graphics g;
    private int interval,side,number;

    public paintClass() 
    {
        this.repaint();//ADDED
        paintComponent(g);//This line has error.
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);//ADDED and has an error.
        this.repaint();//ADDED
        side = 250;
        number = 5;
        interval = side / number;
        g.drawRect(0,0, side, side);

        for(int i = 0; i <= number - 1; i++)
        {
            for(int j = 0; j <= number - 1; j++)
            {
                 g.drawLine(i * interval, 0, i * interval, side);
            }
            g.drawLine(0, i * interval, side, i * interval);
        }

    }   
}

4 个答案:

答案 0 :(得分:2)

您正在使用尚未实例化的Graphics对象在paintClass的构造函数中调用paintComponent。对于简单绘图,您不需要直接调用此方法 - 必要时将由EDT(使用适当的Graphics对象)调用它(换句话说,删除该行并且不保留对Graphics的引用宾语)。

//constructor of Class - note Classnames should start with uppercase
public paintClass(){
    //no need to call paintComponent or repaint here
}

您可以通过调用JComponent(JPanel的父类)定义的repaint()方法来请求重绘。您还应该调用父方法

@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    //do your custom drawing here, and never call repaint from this method
}

如果您还没有,我建议您学习有关自定义绘画的Oracle教程:http://docs.oracle.com/javase/tutorial/uiswing/painting/

答案 1 :(得分:1)

Swing中的第一个绘画规则,你不控制绘画过程。 Swing将在何时以及如果需要时绘制。您可以做的最好的事情是向系统提供您想要更新的提示。

  • 永远不要维护对图形的引用,或者不要自己创建
  • 永远不要直接或间接地从任何绘制方法中调用repaint,这将设置一个递归绘制循环,最终会消耗你的CPU
  • 在屏幕上无法显示的组件上调用repaint毫无意义

例如

public class paintClass extends JPanel
{

    private int interval,side,number;

    public paintClass() 
    {
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(400, 400);
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        side = 250;
        number = 5;
        interval = side / number;
        g.drawRect(0,0, side, side);

        for(int i = 0; i <= number - 1; i++)
        {
            for(int j = 0; j <= number - 1; j++)
            {
                 g.drawLine(i * interval, 0, i * interval, side);
            }
            g.drawLine(0, i * interval, side, i * interval);
        }

    }   
}

答案 2 :(得分:0)

您需要Override paintComponent(Graphics g)不要创建一个。另外,如果您希望执行paintComponent(...),请在该组件上调用repaint(),请勿直接致电paintComponent(...)

答案 3 :(得分:-2)

在您的类“paintClass”中,您应该实例化页面var:

public paintClass() 
{
    page = new Graphics();
    paintComponent(page);
}