练习 paintComponent 方法

practicing paintComponent method

我想练习paintComponent方法。我的程序由不同文件中的两个 类(test 和 paintClass) 组成。我想通过使用 paintComponent 方法垂直和水平绘制线将区域划分为 25 个正方形。我的构造函数现在只有 paintComponent。我知道它不是很有效,但我以后会添加按钮、标签和其他东西,所以我需要像这样使用这个程序。当我 运行 程序出现 nullpointerexception error.Can 你帮忙吗?

编辑:我将页面更改为 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);
        }

    }   
}

在您的 class "paintClass" 中,您应该实例化页面 var :

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

您正在使用尚未实例化的 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 的父 class)定义的 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/

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

在 Swing 中绘制的第一条规则,您不控制绘制过程。 Swing 将在需要时进行绘制。您能做的最好的事情就是向系统提供您想要更新内容的提示。

  • 永远不要维护对 Graphics 的引用,或者对不是您自己创建的引用
  • 切勿直接或间接从任何绘制方法内部调用 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);
        }

    }   
}