javaGUI学习5:AWT-Graphics绘图基本知识

1、图形坐标系

在这里插入图片描述

  • 小圆代表坐标,正方形代表像素,坐标位于像素之间。
  • 对于输出设备来讲,坐标位于像素之间。绘制形状轮廓的操作,例如Graphics .drawRect(),用一支画笔沿着一个坐标路径移动,画笔对坐标路径下方或右方的像素进行绘画。
  • 画笔的尺寸通常是一个像素高和一个像素宽。
2、applet绘图例子
import java.applet.Applet;
import java.awt.*;

public class demo03 extends Applet {
    public void paint(Graphics g) {
        g.drawRect(2,2,4,4);
    }
}

在这里插入图片描述

  • 乍一看该applet 程序,我们可能会认为其显示的是由drawRect (2,2,4,4)中的参数在像素坐标中定义的一个矩形框。实际上,其显示的结果如上所示,参数指定图形笔的坐标路径。当绘制矩形时,坐标路径开始点是(2,2),而后面的两个4则分别代表坐标增长的宽度和高度,所绘制的坐标路径如下所示:
    (2,2)→(6,2)→(6,6)→ (2,6)→(2,2)
  • 图形笔移动的路径,从起点开始,向右移动到第二个点,然后向下移动到第三个点,向左绘制至第四个点,最后回到起点。当画笔沿路径移动时,其像素颜色来自画笔,而画笔所采用的颜色则是通过调用Graphics. setColor ( Color)来指定的。
  • 画笔是沿上面所讲坐标路径绘制矩形的,所以g.drawRect(2,2,4,4)实际上绘制出来的矩形的宽度和高度是5个像素单位,而不是4个像素单位。
3、绘制构件四周边界

因为绘制出的矩形将比构件宽一个像素也高一个像素。结果,右边缘和底边缘边界将被绘制在构件的外面,因此将看不到该部分。
常用的解决方法是,从宽度和高度中都减去一个像素单位,如下所示:

public void paint (Graphics g) {
	Dimension size = getSize();
    g.drawRect(0,0,size.width-1,size.height-1);
}
4、填充形状
import java.applet.Applet;
import java.awt.*;

public class demo03 extends Applet {
    public void paint(Graphics g) {
        g.fillRect(2,2,4,4);
    }
}

在这里插入图片描述

  • 传递给fillRect ()的参数指定的坐标路径与在前面调用drawRect()时指定的坐标路径相同。但是,填充外形的Graphics方法将填充路径的内部,所以填充的矩形是4个像素宽和4个像素高,如上图所示。
  • 注意形状填充和形状轮廓容易引起混淆。另外,传递给drawRect()和 fillRect ()的参数定义的是坐标路径,但是经常被错误地描述为以像素为单位的矩形的边界。所有绘制轮廓和填充形状的Graphics方法的主要差异是尺寸上的差异。
5、Graphics引用

注意:

从Component、Image和 PrintJob中的getGraphics ()方法返回的Graphics 引用并不是一个对Graphics引用的引用,而是返回一个初始Graphics 的副本。

5.1 Graphics 的副本
import java.applet.Applet;
import java.awt.*;

public class demo03 extends Applet {
    public void paint(Graphics g) {
        setForeground(Color.yellow);
        g.drawLine(0,0,getSize().width - 1,getSize().height - 1);
    }
}
  • 画线时使用的是applet默认的前景颜色,该颜色在Windows 95中是黑色。
  • 在 applet初始着色后,紧接着调用paint ()方法,结果得到黄色的线条。
  • 调用Component . setForeground (),改变构件中 Craphics 的当前颜色,该颜色被改变成黄色。
  • SetFroeground ()影响applet的Graphics,但并不影响传递给 paint ()的Graphics的副本。因此,当第一次调用paint ()时,线条的颜色并没有变成黄色。当调用drawLine()时,传递给paint ()的 Grahpics和实际的 Grphics并不同步。
  • 后来调用paint()时,传递给paint ()的是 applet 的Graphics的一个新副本,因此setFore-gound ()的调用结果可以将applet的Graphics的当前颜色改变成黄色。
import java.applet.Applet;
import java.awt.*;

public class demo03 extends Applet {
    public void paint(Graphics g) {
        setForeground(Color.yellow);
        Graphics copy = null;
        try {
            copy = getGraphics();
            copy.drawLine(0,0,getSize().width - 1, getSize().height - 1);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            copy.dispose(); //处置此图形上下文并释放它正在使用的任何系统资源
        }
    }
}
  • 传递给paint ( )的 Graphics将被忽略掉,通过调用getGraphics ()方法得到一个新的Graphics,应用这个新的Graphics绘制直线。
  • 因为在调用setForegroud ()之后获取Grpahics,所以Graphics当前的颜色,也就是线条的颜色,将变成黄色。
  • 注意到在paint ()方法返回之前调用Graphics.dispose ()方法,处理由Component.getGraphics ()返回的Graphics,而传递给paint ()的Graphics却没有被处理。
5.2 Graphics引用的寿命
  • 除了引用副本外,传递给 paint (和update ()等方法的Graphics引用仅仅在方法的执行过程中才有效。一旦方法返回,引用将不再有效。
  • 下面给出的程序范例,在该applet程序中,想重用最初传递给paint ()的Graphics引用。直线将在第一次调用paint ()时画出,但是对paint ()的后续访问将导致直线在一个无效的Graphics内绘制,因此直线不再显示(通过调整窗口大小可以强行重绘该applet)
  • Graphics引用方法调用结束后,自动销毁。所以第一次以后的oldg指向的地址对象已经被销毁,所以变成无效Graphics
import java.applet.Applet;
import java.awt.*;

public class demo03 extends Applet {
    private Graphics oldg;
    private boolean first = true;
    
    public void paint(Graphics g) {
      	if(first) {
        	oldg = g;
            first = false;
        }
        oldg.drawLine(0,0,getSize().width - 1, getSize().height - 1);
        
    }
}
5.3 处理Graphics
public void demo() {
	Graphics g = getGraphics();
    if(g != null) {
    	try {
        	//code
        } cache() {
            //code
        } finally {
        	g.dispose()
        }
    }
}
  • 如果最后不调用dispose(),那么将会导致窗口系统用完图形环境
  • 这里对g做null检测是因为:如果在构件的同位体之前调用getGraphics(),则会返回null

Graphics表示本地图形环境,是一个典型的有限资源,所以一定要使用dispose释放资源。但传递Graphics引用的方法一般不需要手动调用方法处理。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值