Java 中关于新手入门使用Graphics画笔工具时指针为空和显示不出来图形的问题。

因为在网上找了很多文章才搞懂这个问题,所以写下这个解决问题后的随笔希望能帮到更多的初学者,如有不对请大佬指正勿喷。

相信肯定有小伙伴代码是这样写的,导致报空指针的错误。

public class Test extends JFrame{
	
	public Test() {
		Graphics gr;
		gr = getGraphics();
		gr.fillOval(50, 50, 50, 50);
		setTitle("画图");
		setBounds(300, 300, 340, 240);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setVisible(true);
	}

这是因为画笔要在设定可使后才能获取,在setVisible(true);之前获取画笔是不能获取到画笔的。

通过调试可以发现gr的值为null,表示并未获取到Graphics对象。

那我们换一下位置,是不是就能显示图像了呢?

public Test() {	
		Graphics gr;
		setTitle("画图");
		setBounds(300, 300, 340, 240);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setVisible(true);
		
		gr = getGraphics();
		gr.fillOval(50, 50, 50, 50);

	}

我们将代码改成这样,然后运行,得到结果:

 可以看到,并没有任何图像在上面,说明程序还是有问题,否则应该是有一个半径为50的圆在图上的。我们现在可以假设两种情况:一、画笔获取到了,但是获取错了,图像画错地方了。二、程序画了,但是又被覆盖了。

我们通过调试得到如下结果:

可以看到画笔gr已经获取到了,图形也画上去了,那就证明程序逻辑是没有问题的,第一种情况可以否定了。那为什么程序正常运行时不报错也没有图形呢?

我们首先了解一下paint函数,这是JFrame和JPanel都有的一个函数,可以手动重写,程序执行时自动调用。

可以看到,这里我们没有在构造函数里面获取画笔也没有再主函数里面调用paint方法,但是程序依旧画出了一个圆形。这是因为paint方法在构造对象后会自动调用,传入paint函数的参数Graphics g 是默认正在创建的对象的画笔。

基于以上知识,我们将代码改成如下情况再执行:

public Test() {
		Graphics gr;
		setTitle("画圆");
		setBounds(300, 300, 340, 240);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setVisible(true);
		gr = getGraphics();
        gr.fillRect(100, 100, 50, 50);	
		System.out.println("draw");
	}
	public void paint(Graphics g) {
		System.out.println("paint");
		g.fillOval(50, 50, 50, 50);
	}

 可以发现,先画了构造函数里面的图形,然后又调用了几遍paint函数,导致之前被画上去的图被覆盖了。所以假设二成立,程序是由于先画了矩形后又调用paint函数导致图形被覆盖。

那么因为paint函数导致覆盖可不可以用其他方式解决呢?比如写一个函数,创建对象后调用。

此时需要将Graphics变量定义为成员变量,以便其他函数调用,测试代码如下:

public class Test extends JFrame{
	Graphics gr;        //成员变量
	public Test() {
		setTitle("画圆");
		setBounds(300, 300, 340, 240);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setVisible(true);
		gr = getGraphics();
	}
	public void paint(Graphics g) {
		System.out.println("paint");
		g.fillOval(50, 50, 50, 50);
	}
	public void Draw() {
		System.out.println("Draw");
		gr.setColor(Color.red);
		gr.fillRect(100, 100, 50, 50);	
	}
	public static void main(String[] args) {
		Test p = new Test();
		p.Draw();
	}

}

测试结果为:

                  

可以看见,函数画的图还是被覆盖了。

因为每次对窗口进行改变时,都会重新调用paint方法实时绘图,所以会导致图像覆盖。因此要想获取稳定的图像需要将绘图代码写在paint里面。

 总结:一、如果Graphics对象是空指针,检查一下是否是由于没有在获取画笔之前设置可见模式(setVisible(true);)。二、画图的代码要写在重写的paint函数里面,写在构造函数或者其他函数里面都有被覆盖而无法显示的可能,(写在主函数里面偶尔不会被覆盖)如:

 

  • 11
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值