Java2D高级绘图【教学目标】在本讲中希望您能掌握和了解如下知识点:Graphics类,如何获取Graphics类,文本字串的显示,图形编程,图像编程以及Java2D高级编程技术等。1.1.利用Graphics类的绘图技术1、AWT图形、文本、图像绘制编程(1)有关的类:主要涉及java.awt包中的Graphics类。(2)Graphics类对象:它代表当前组件如窗口的绘图环境。(3)绘制函数调用Graphics类中的相应的绘制图形、绘制文本、绘制图像等函数以实现在图形窗口下输出图形、文本、图像等。图4--1(4)编程方法在组件的paint()函数内或在组件的其它函数内如事件响应函数内获得java.awt包中的Graphics类的对象,然后调用Graphics类中相应的绘制函数来实现输出。(5)paint()函数它是在java.awt.Component类(所有窗口对象的基类)所提供的一个方法,当系统需要重新绘制组件时,将调用该方法。paint()方法只有一个参数,该参数是Graphics类的实例。下面给出一个实例。publicvoidpaint(Graphicsg){ColormyColor=newColor(255,0,0);g.setColor(myColor);g.drawString(这是Java中的带颜色的文字串,100,100);g.drawRect(10,10,100,100);}2、组件绘制的时机(1)组件外形发生变化时:如窗口的大小、位置、图标化等显示区域更新时,AWT自动从高层直到叶结点组件相应地调用各组件的paint()方法,但这可能有一个迟后感。(2)程序员也可直接调用某一个组件的repaint()或paint(),以立即更新外观(如在添加新的显示内容后)。注意:如果要求保留上次的输出结果时可以调用paint(),而不要求保留上次的输出结果只希望用户能看到最新的输出结果时可以调用repaint()。(3)AWT响应外部的事件时,如首先显示于屏幕或需刷新时,AWT也会直接调用repaint()函数。3、坐标系统(1)Java2DAPI有两种坐标系统用户空间是一种与设备无关的逻辑坐标系统。应用程序独占使用此坐标系统。所有传入Java2D绘制例程中的几何图形均在用户空间中定义。设备空间是一种与设备有关的坐标系统,它根据目标绘制设备的不同而变化。注意:Java2D系统自动在用户空间和目标绘制设备的设备空间之间执行必要的转换。虽然显示器的坐标系统和打印机的坐标系统有很大的差别,但这些差别对应用程序并无影响。(2)用户空间用户空间的原点位于空间左上角,x值向右递增,y值向下递增。用户空间是对所有可能的设备坐标系统的一种抽象。某一设备的设备空间与用户空间的原点和方向可能相同,也可能不同。无论怎样,当绘制图形对象时,用户空间坐标将自动变换为相应的设备空间。通常由内部平台设备驱动程序执行这项转换。4、如何获取Graphics类对象并绘制(1)原理绘制之前,必须先获取Graphics类对象。因为它包含有当前组件的绘图环境,从而实现在当前组件(如图形窗口)内输出。(2)方法一在paint()内则可通过其形参(它代表当前组件的绘图环境),从而调用Graphics类中的相关的绘制成员函数。publicvoidpaint(Graphicsg){g.setColor(Color.LIGHT_GRAY);g.fillRect(1,1,100-2,100-2);g.draw3DRect(0,0,100-1,100-1,true);g.setColor(this.getForeground());g.drawRect(2,2,100-4,100-4);}(3)方法二先在组件类(如Applet、Frame或其它组件的成员函数)中调用getGraphics()(它返回当前组件的Graphics类对象)来获取当前组件的绘图环境,再强制绘制输出。从而可在paint()函数之外(如事件响应函数内)产生绘制动作。publicbooleanmouseDrag(Eventevt,intx,inty){Graphicsg=getGraphics();//在鼠标的mouseDrag事件中画出鼠标的当前位置的点g.setColor(Color.red);g.drawLine(x,y,x,y);returntrue;}5、AWT中文本字串的显示(1)方法应调用Graphics类中相应的输出函数:g.drawString(“待输出的文字串”,x,y);注意:其中的X,Y是指定文本的左下角的坐标值。程序例如下:publicvoidpaint(Graphicsg){FontmyFont=newFont(Dialog,Font.BOLD,20);g.setFont(myFont);g.drawString(这是Java中的Dialog字体的文字串,100,100);}(2)文字的颜色和字体编程颜色:利用Color类创建出一Color类对象并设置颜色特征参数(r、g、b三基色的分量);调用Graphics类中的setColor()将用户的颜色加入到系统中;再调用绘制函数输出图形、文字等。字体:利用Font类创建出一Font类对象并设置字体特性参数;调用Graphics类中的setFont()将用户字体加入到系统中;再调用绘制函数输出文字(也可以设置按钮等基本控件的字体,如:OK.setFont())实例程序publicvoidpaint(Graphicsg){ColormyColor=newColor(255,0,0);g.setColor(myColor);FontmyFont=newFont(Dialog,Font.BOLD,20);g.setFont(myFont);g.drawString(这是Java中的Dialog字体的文字串,100,100);}6、AWT中的图形编程(1)图形函数Graphics类中的图形函数主要可以分为如下几种:跟踪形状轮廓的绘制方法(点、线和面),填充形状轮廓的绘制方法,其它杂项方法。(2)应用实例实例一:设计一个画直方图的JavaApplet程序importjava.applet.*;importjava.awt.*;publicclassLifeCycleextendsApplet{publicvoidpaint(Graphicsg){g.drawLine(20,200,300,200);//画出X坐标轴g.drawLine(20,200,20,20);//画出Y坐标轴g.drawLine(20,170,15,170);g.drawLine(20,140,15,140);//画出Y坐标轴上的数据的各个刻度线,共5条g.drawLine(20,110,15,110);g.drawLine(20,80,15,80);g.drawLine(20,50,15,50);g.drawString(Init(),25,213);//在X坐标轴上显示出各个名称的文字g.drawString(Start(),75,213);g.drawString(Stop(),125,213);g.drawString(Destroy(),175,213);g.drawString(Paint(),235,213);g.fillRect(25,200-InitCnt*30,40,InitCnt*30);//画填充矩形作为直方条,但放大30倍g.fillRect(75,200-StartCnt*30,40,StartCnt*30);g.fillRect(125,200-StopCnt*30,40,StopCnt*30);g.fillRect(175,200-DestroyCnt*30,40,DestroyCnt*30);g.fillRect(235,200-PaintCnt*30,40,PaintCnt*30);}}实例二:设计一个自由笔(铅笔)以产生手画线的程序。publicbooleanmouseDrag(Eventevt,intx,inty){Graphicsg=getGraphics();//在鼠标的mouseDrag事件中画出鼠标的当前位置的点g.setColor(Color.red);g.drawLine(x,y,x,y);returntrue;}实例三:自定义出一个按纽效果的图形publicvoidpaint(Graphicsg){g.setColor(Color.LIGHT_GRAY);g.fillRect(1,1,100-2,100-2);g.draw3DRect(0,0,100-1,100-1,true);g.setColor(this.getForeground());g.drawRect(2,2,100-4,100-4);}实例四:画各种形式的圆弧publicvoidpaint(Graphicsg){//在原点为(10,40),半径为70,起始角度为0度,逆时针转90度的圆弧g.drawArc(10,40,70,70,0,90);//在原点为(100,40),半径为70,起始角度为0度,逆时针转90度的圆弧g.fillArc(100,40,70,70,0,90);//在原点为(10,100),长轴为80,短轴为70,起始角度为0度,顺时针转90度的弧g.drawArc(10,100,70,80,0,-90);//在原点为(100,100),长轴为80,短轴为70,起始角度为0度,顺时针转90度的填充弧g.fillArc(100,100,70,80,0,-90);}实例五:画多边形publicvoidpaint(Graphicsg){intxArr[]={78,188,194,284,106,116,52};intyArr[]={66,148,72,140,216,160,212};intnumPoints=xArr.length;//获得x,y坐标对数组的长度g.drawPolygon(xArr,yArr,numPoints);}7、AWT中的图像编程(1)文件格式:支持*.gif、*.jpeg、*.Png等(2)加载图像的方法Applet中加载图像:直接调用getImage(),如:ImagemyImage=getImage(URLaddress,imageFileName);Application中加载图像:利用Toolkit类中的getImage(),如:ImagemyImage=Toolkit.getDefaultToolkit().getImage(imageFileName);(3)应用程序例程序例一:实现拖放图像和回弹图像(产生手画线的效果,同时在鼠标释放后地球将自动回弹到原来的地方)importjava.awt.*;importjava.awt.event.MouseListener;importjava.awt.event.MouseEvent;importjava.awt.event.MouseMotionListener;publicclassAWTDrawextendsFrameimplementsMouseListener,MouseMotionListener{ImageearthImage=null;intX,Y;intstartX,startY,endX,endY;publicAWTDraw(StringwindowTitle){super(windowTitle);this.setSize(Toolkit.getDefaultToolkit().getScreenSize().width,Toolkit.getDefaultToolkit().getScreenSize().height-25);this.addMouseListener(this);this.addMouseMotionListener(this);earthImage=Toolkit.getDefaultToolk