java文字与图形GUI设计

时间:2023-01-27 21:29:26

 

8.1 GUI
设计概述
8.2
绘制文字
8.3 Color

8.4 Graphics

8.1 GUI
设计概述
图形用户界面(Graphics User Interface,简称GUI)就是为应
用程序提供一个图形化的界面。GUI使用图形的方式借助菜单、
按钮等标准界面元素和鼠标操作,帮助用户方便地向计算机系
统发出命令、启动操作,并将系统运行的结果同样以图形的方
式显示给用户,使一个应用程序具有画面生动、操作简便的效
果,省去了字符界面中用户必须记忆各种命令的麻烦,深受广
大用户的喜爱和欢迎,已经成为目前几乎所有应用软件的既成
标准。

为了方便编程人员开发图形用户界面,Java提供了抽象窗
口工具包(Abstract Windowing ToolKit,缩写为AWT)和Swing
包这两个图形用户界面工具包。在这两个工具包中提供了丰
富的类库来支持编程人员创建与平台无关的用户界面。编程
人员可方便地使用这些类库来生成各种标准图形界面元素并
处理图形界面的各种事件。

8.1.1
图形用户界面元素分类
1
.容器
容器是用来组织或容纳其他界面成分和元素的组件。一个容
器可以包含许多组件,同时它本身也可以作为一个组件,放进另
一容器中。一般来说,一个应用程序的图形用户界面首先对应于
一个复杂的容器,例如一个窗口。这个容器内部将包含许多界面
成分和元素,其中某些界面元素本身也可能又是一个容器,这个
容器再进一步包含它的界面成分和元素,依此类推就构成一个复
杂的图形界面系统。
容器是Java中的类,例如框架(JFrame)、面版(JPanel)及滚动
面板(JScrollPanel)等类。容器的引入有利于分解图形用户界面的
复杂性。当界面的功能较多时,使用层层相套的容器是非常必要
的。

2
.控制组件
与容器不同,控制组件是图形用户界面的最小单位之一,
它里面不再包含其他的成分。控制组件的作用是完成与用户的
一次交互,包括接收用户的一个命令(如菜单命令),接收用户输
入的一个文本或选择,向用户显示一段文本或一个图形等等。
从某种程度上来说,控制组件是图形用户界面标准化的结
果,目前常用的控制组件有选择类的单选按钮、复选按钮、下
拉列表,有文字处理类的文本框、文本区域,有命令类的按钮、
菜单等。使用控制组件,通常需要如下的步骤:

(1) 创建某控制组件类的对象,指定其大小等属性。
(2) 使用某种布局策略,将该控制组件对象加入到某个容器
中的指定位置处。
(3) 将该组件对象注册给所能产生的事件对应的事件监听程
序,重载事件处理方法,实现利用该组件对象与用户交互的功
能。

3
.用户自定义成分
除了上述的标准图形界面元素外,编程人员还可以根据用
户的需要,使用各种字型、字体和色彩设计一些几何图形、标
志图案等,它们被称为用户自定义成分。用户自定义成分通常
只能起到装饰、美化的作用,而不能响应用户的动作,也不具
有交互功能。
由于用户自定义成分易于学习和掌握,同时,各种基本图
形和说明性文字又是容器和控制组件的基本成分,而且考虑到
由浅入深的学习规律,因此我们先在本章利用AWT包学习用户
自定义成分,在第9章和第10章再学习控制组件和复杂的容器。

8.1.2
屏幕坐标系
文本与图形通过一定的坐标关系显示在屏幕的适当位置上。
Java坐标系是一个二维网格,它可以标识屏幕上每个点的坐标位
置。坐标单位用像素来度量。一个像素是一台显示器的最小分
辨单位。坐标系由一个x坐标(水平坐标)和一个y坐标(垂直坐标)
组成。在缺省状态下原点为屏幕左上角坐标(0,0),因此,x坐
标是从左向右移动的水平距离,y坐标是从上向下移动的垂直距
离。图8.1中的坐标(x,y)表示点与原点的水平距离是x,垂直距
离是y。

图8.1 Java坐标系
0
0
X轴
Y轴

8.1.3
与文字图形有关的类
图8.2给出了java.awt包层次的一部分——有关文字、颜色和
基本图形的类。图中的每一个类都是从类Object直接派生出来的:
类Font是用于操作字体的;类Color是用于操作颜色的;类
FontMetrics主要用于获取字体的有关信息;类Polygon用于创建
多边形;类Graphics用于绘制各种串、线、矩形、圆和其他几何
图形。

图8.2 java.awt包中的文字图形类(是由Object类派生的)
Object
Font FontMetrics Color Graphics Polygon Component

8.1.4 Applet
的执行程序
限于我们目前的知识,在讲述本章的内容时我们以Applet
应用程序为所有示例程序的容器,且通过引用或重载Applet类
的某些成员方法来实现文字及图形的绘制。为此,有必要先介
绍Applet应用程序的执行过程及其所引用的方法。每个Applet应
用程序都是Applet类的子类,在实际运行中,浏览器在下载字
节码的同时,会自动创建一个用户Applet子类的对象,并在适
当事件发生时自动调用该对象的几个主要方法。下面说明这些
方法的引用过程。

(1) init()方法:当Applet程序启动时自动调用init()方法。
init()方法仅用来做初始化操作。用户程序可以重载父类的init()
方法,通过init()方法初始化图像文件、声音文件、字体或者其
他一些对象等。
(2) start()方法:Applet运行init()方法之后将自动调用start()
方法,start()方法体现了小应用程序要完成的功能。我们可以重
载父类的start() 方法,在这个方法体内实现我们程序的功能。
(3) paint()方法:它的主要作用是在Applet的界面中显示文
字、图形和其他界面元素。浏览器调用paint()方法的事件主要
有如下三种。

① 当浏览器首次显示Applet时,会自动调用paint()方法。
② 当用户调整窗口大小或移动窗口时,浏览器会调用paint()
方法。
③ 当repaint()方法被调用时,系统将首先调用update()方法
将Applet对象所占用的屏幕空间清空,然后调用paint()方法重画。

(4) stop()方法:当用户将浏览Applet程序所在的Web页面
切换到其他页面时,浏览器会自动调用stop()方法,让Applet程
序终止运行。如果用户又回到Applet程序所在的Web页面时,
则浏览器将重新启动Applet程序的start()方法。
(5) destroy():当用户关闭Applet程序窗口时,浏览器会自
动执行此方法,结束程序,释放所占资源。

8.2




8.2.1
绘制文字的成员方法
由于字符串可以用字符串对象、字符数组、字节数组三种
不同形式表示,故Java在Graphics类中相应地提供了三个成员方
法来绘制这三种不同形式的字符串(见表8.1)。

表8.1
绘制字符和字符串的成员方法
成 员 方 法参 数 说 明功 能
drawString{String string,int x,int
y}
string是字符串对象;x,y
是起始坐标
以坐标x,y为起始位置,用
当前的字体和颜色绘制
string代表的字符串
drawChars{char[] ch, int offset,
int number,int x,int y}
ch是字符数组名;offset是
要绘制的第一个字符在数
组中的下标; number是要
绘制的字符个数;x,y是起
始坐标
从ch数组下标为offset的位
置开始截取number 个字
符,从坐标x,y处开始用当
前的字体和颜色绘制
number个字符
drawBytes{ byte [] by, int
offset,
int number,int x,int y }
by是字节数组名;offset是
要绘制的第一个字符在数
组中的下标; number是要
绘制的元素个数;x,y是起
始坐标
从by数组下标为offset的位
置开始取number个字节,
从坐标x,y处开始用当前的
字体和颜色绘制number个
字符

【示例程序c8_1.java】 使用上述三个成员方法绘制
“WELCOME TO KUNMING”。
import java.applet.Applet;
import java.awt.Graphics;
public class c8_1 extends Applet
{
private String s = "WELCOME!";
private char c[] = {'T','O','a','e','t'};
private byte b[] = {'d','4','K','U','N','M','I','N','G' };
public void paint( Graphics g) //覆盖Applet的成员方法
{
g.drawString( s, 50, 25);
g.drawChars( c, 0, 2, 50, 50);
g.drawBytes( b, 2, 7, 50, 75);
}
}

在这个程序中,为了学习使用绘制字符和字符串的三个成
员方法,我们分别定义了一个字符串对象s、一个字符数组c和
一个字节数组b,分别用于保存三行文字内容。最后,我们通过
覆盖Applet类的paint()方法,在这个方法中引用绘制字符和字符
串的成员方法来实现文字的绘制。该程序的运行结果见图8.3。

图8.3 程序c8_1的运行结果

8.2.2 Font

1. Font
类的构造方法
Font类用来描述字体的名称(Name)、大小(Size)和样式
(Style)。使用Font类的构造方法创建一个Font类的对象,其格式
如下:
Font(String
fontname,int
style,int
size)
其中:fontname为字型名,如宋体、黑体、楷体、Arial、Courier、
TimesRoman、Helvetica等;style为字体样式,如粗体(BOLD)、
斜体(ITALIC)、正常体(PLAIN);Size为用像素点表示的字体大
小。

2. Font
类的成员方法
创建一个Font类对象后,就可以使用Font类提供的成员方
法来获取字体、字型等方面的信息。Font类提供的常用成员方
法如表8.2所示。

表8.2
java.awt.Font
类方法
成 员 方 法功 能 说 明
public static Font decode(String str) 使用传递进来的名称获得指定的字体
public string getFamily() 获得指定平台的字体名
public string getName() 获得字体的名称
public int getStyle() 获得字体的样式
public int getSize() 获得字体的大小
public boolean isPlain() 若字体是正常型,则返回true
public boolean isBold() 若字体是粗体,则返回true
public boolean isItalic() 若字体是斜体,则返回true
public string toString() 将此对象转换为一个字符串表示

3.
设置字体
可以用java.awt.Graphics类的成员方法来设置自己希望使用
的字体,其格式如下:
setFont(Font myFont);
【示例程序c8_2.java】 使用不同的字体绘制文字。
import java.awt.*;
import java.applet.Applet;
public class c8_2 extends Applet

{ Font f1 = new Font("TimesRoman",Font.BOLD,16); //字体
为TimesRoman,字体样式加粗
Font f2 = new Font("Courir",Font.ITALIC,24); //字体为
Courir,字体样式倾斜
Font f3 = new Font("Helvetica",Font.PLAIN,14);//常规
String hStr = "Courir";
public void paint(Graphics g)

{
g.setFont(f1);
g.drawString("TimesRoman",20,50);
g.setFont(f2);
g.drawString(hStr,20,100);
g.setFont(f3);
g.drawString("Helvetica",20,150);
}
}

图8.4 程序c8_2的运行结果

该程序的运行结果如图8.4所示。
<【示例程序c8_3.java】 获取字体信息。
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Font;
public class c8_3 extends Applet
{
Font f=new Font("Courier", Font.ITALIC+Font.BOLD,24); // 字体样式倾斜加粗
public void paint(Graphics g)
{ int style,size;

String s,name;
g.setFont(f);
style=f.getStyle(); //得到字体样式
if (style ==Font.PLAIN) s="Plain";
else if (style ==Font.BOLD) s="Bold";
else if (style ==Font.ITALIC) s="Italic";
else s="Bold italic";
size=f.getSize(); //得到字体大小
s+=size+"point";
name=f.getName(); //得到字体名称
s+=name;
g.drawString(s,10,50);
g.drawString("Font family is"+f.getFamily(),10,100);
}
}

图8.5 程序c8_3的运行结果

【示例程序c8_4.java】 使用识别字型字体的成员方法。
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Font;
public class c8_4 extends Applet
{
Font f=new Font("Courier",Font.ITALIC+Font.BOLD,24);
public void paint(Graphics g)
{
String s;
g.setFont(f);

if(f.isPlain()==true) s="Font is plain.";
else if(f.isBold()==true && f.isItalic()==false) s="Font is bold.";
else if(f.isItalic()==true && f.isBold()==false) s="Font is italic.";
else
s="Font is bold italic.";
g.drawString(s,25,25);
}
}

图8.6 程序c8_4的运行结果

8.2.3
FontMetrics

图8.7 字体信息图

高度(height):上下两行基线之间的距离;
下差(descent):一个字符低于基线的部分;
上差(ascent):一个字符高于基线的部分;
字冠(leading):高度去掉基线下差和基线上差后剩余的部分。

1
.FontMetrics
类的构造方法
创建一个FontMetrics类的对象需要使用FontMetrics类的构
造方法,其格式如下:
protected FontMetrics (Font font)
这个构造方法用指定的字体创建一个新的FontMetrics类对
象。

2
.FontMetrics
类的成员方法
表8.3
java.awt.FontMetrics
类成员方法
成 员 方 法功 能 说 明
public Font getFont() 获得当前字体
public int getLeading() 获得字体的leading(字冠)值
public int getAscent() 获得字体的ascent(上差)值
public int getDescent() 获得字体的descent(下差)值
public int getHeight() 获得字体的height(高度)值
public String toString() 返回对象的字符串表示

【示例程序c8_5.java】 FontMetrics类成员方法的使用。
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Font;
public class c8_5 extends Applet
{
Font font1,font2;
font1=new Font("Courier",Font.BOLD,14);
font2=new Font("TimesRoman",Font.PLAIN,10);
public void paint(Graphics g)
{

g.setFont(font1);
showStatus(g.getFont().toString());
int ascent=g.getFontMetrics().getAscent();
int descent=g.getFontMetrics().getDescent();
int height=g.getFontMetrics().getHeight();
int leading=g.getFontMetrics().getLeading();
String s1="Ascent of Font font1 is "+String.valueOf(ascent);
String s2="Descent of Font font1 is "+String.valueOf(descent);
String s3="Height of font font1 is "+String.valueOf(height);
String s4="Leading of Font font1 is "+String.valueOf(leading);
g.drawString(s1,10,10);
g.drawString(s2,10,40);
g.drawString(s3,10,70);
g.drawString(s4,10,100);

ascent=g.getFontMetrics(font2).getAscent();
descent=g.getFontMetrics(font2).getDescent();
height=g.getFontMetrics(font2).getHeight();
leading=g.getFontMetrics(font2).getLeading();
s1="Ascent of Font font2 is "+String.valueOf(ascent);
s2="Descent of Font font2 is "+String.valueOf(descent);
s3="Height of Font font2 is "+String.valueOf(height);
s4="Leading of Font font2 is "+String.valueOf(height);
g.drawString(s1,10,130);
g.drawString(s2,10,160);
g.drawString(s3,10,190);
g.drawString(s4,10,220);
}
}

图8.8 程序c8_5的运行结果

8.3 Color

8.3.1 Color
类的构造方法
表8.4
java.awt.Color
类的构造方法
构 造 方 法功 能 说 明
public Color(int r, int g, int b) 使用在0~255范围内的整数指定红、绿和蓝三种
颜色的比例来创建一种Color对象
public Color(float r, float g,
float b)
使用在0.0~1.0范围内的浮点数指定红、绿和蓝
三种颜色的比例来创建一种Color对象
public Color(int rgb) 使用指定的组合RGB值创建一种Color对象

不论使用哪个构造方法来创建Color对象,都需要指定新建
颜色中的R(红)、G(绿)、B(蓝)三色的比例。Java提供的这三个构
造方法用不同的方式确定RGB的比例,可以使编程者从
256×256×256(约16 000 000)种颜色中进行选择。一个RGB值由
三部分组成:第一个RGB部分定义红色的量;第二个RGB部分
定义绿色的量;第三个RGB部分定义蓝色的量。RGB值中某一
部分的值越大,那种特定颜色的量就越大。

8.3.2 Color
类数据成员常量
用户除了可以使用构造方法指定Color的RGB值外,Java还
对一些常用的颜色提供了如表8.5所示的Color类数据成员常量。

表8.5 Color
类static
数据成员常量和RGB

颜色数据成员常量颜 色RGB值
public final static Color red 红255,0,0
public final static Color green 绿0,255,0
public final static Color blue 蓝0,0,255
public final static Color black 黑0,0,0
public final static Color white 白255,255,255
public final static Color yellow 黄255,255,0
public final static Color orange 橙255,200,0
public final static Color cyan 青蓝0,255,255
public final static Color magenta 洋红255,0,255
public final static Color pink 淡红色255,175,175
public final static Color gray 灰128,128,128
public final static Color lightGray 浅灰192,192,192
public final static Color darkGray 深灰64,64,64

8.3.3 Color
类的成员方法
表8.6
Java.awt.Color
类成员方法
成 员 方 法 功 能 说 明
public int getRed() 获得对象的红色值
public int getGreen() 获得对象的绿色值
public int getBlue() 获得对象的蓝色值
public int getRGB() 获得对象的RGB值
public Color brighter() 获取此颜色的一种更亮版本
public Color darker() 获取此颜色的一种更暗版本

此外,还可以用java.awt.Graphics类的方法设定颜色或获取
颜色。这些方法及其功能如下:
setColor(Color c):设定前景颜色,c代表颜色。
setColor(new Color(int r,int g,int b)):设定前景颜色的另一
个方法。
setBackground(Color c):设定背景颜色,c代表颜色。
getColor():获取当前所使用的颜色。

8.3.4
应用举例
【示例程序c8_6.java】 使用整型数设置字符颜色。
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;
public class c8_6 extends Applet
{
public void paint ( Graphics g)
{

int red,green,blue;
red = 99;
blue = 120;
green = 125;
g.setColor( new Color( red,green,blue));
g.drawString("Welcome to Xi/047an", 25,75);
showStatus("Current RGB:" + g.getColor().toString());
}
}

图8.9 程序c8_6的运行结果

【示例程序c8_7.java】 使用浮点型数设置字符颜色。
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;
public class c8_7 extends Applet
{
public void paint ( Graphics g)
{
float red,green,blue;

red = 0.39f;
blue = 0.49f;
green = 0.47f;
g.setColor( new Color( red,green,blue));
g.drawString("Welcome to Xi/047an", 25,75);
showStatus("Current RGB:" + g.getColor().toString());
}
}

图8.10 程序c8_7的运行结果

【示例程序c8_8.java】 使用Color类的数据成员常量设置字符颜色。
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;
public class c8_8 extends Applet
{
Color c;
c = Color.blue;
public void paint( Graphics g )
{

g.setColor( c );
g.drawString("Welcome to Xi/047an", 25, 75);
showStatus("Current RGB: " +
String.valueOf( c.getRed()) +
" " + String.valueOf( c.getGreen()) +
" " + String.valueOf( c.getBlue() ) );
}
}

图8.11 程序c8_8的运行结果

8.4 Graphics

8.4.1
绘制线段与矩形
线段与矩形是最常用的几何图形之一,Graphics类中提供了
绘制直线、平面矩形、圆角矩形、三维立体矩形等图形的成员
方法。我们将这些方法一并列于表8.7中。在这些方法中,绘制
圆角矩形稍微复杂一些,它除了要指定矩形区域外,还需要指
明圆角的弧宽(arcWidth)和弧高(arcHeight)。该方法中参数的详
细描述请参阅图8.12。

表8.7 Graphics
类中提供线段与矩形的成员方法
成 员 方 法功 能参 数 说 明
drawLine(int x1,int y1,int x2,int y2) 绘制一条直线x1,y1 为起点坐标; x2,y2
为终点坐标;
drawRect(int x,int y,int width,int
height) 绘制平面矩形
x,y为矩形左上角顶点坐
标;width为矩形的宽度;
height为矩形的高度
fillRect(int x,int y,int width,int
height) 绘制用当前颜色填充的矩形
clearRect(int x,int y,int width,int
height) 清除矩形区域

表8.7 Graphics
类中提供线段与矩形的成员方法
drawRoundRect(int x,int y,int
width,
int height, int arcWidth,int
arcHeight)
绘制圆角矩形
x,y,width,height四个
参数的意义同上;
arcWidth为圆角的弧宽;
fillRoundRect(int x,int y,int width, arcHeight为圆角的弧高
int height, int arcWidth,int
arcHeight)
绘制用当前颜色填充的圆角
矩形
Draw3Drect(int x,int y,int width,
int height,boolean b) 绘制三维矩形
x,y,width,height四
个参数的意义同上; b用
于确定矩形的凸凹,当b
为true 时矩形凸出, b 为
flase时矩形凹下

图8.12 圆角矩形

【示例程序c8_9.java】 绘制直线。
import java.applet.Applet;
import java.awt.Graphics;
public class c8_9 extends Applet
{ public void paint(Graphics g)
{
g.drawLine(25,25,100,100);
}
}
该程序的运行结果如图8.13所示。

图8.13 程序c8_9的运行结果

图8.14 程序c8_10的运行结果

【示例程序c8_10.java】 绘制矩形。
import java.applet.Applet;
import java.awt.Graphics;
public class c8_10 extends Applet
{ public void paint(Graphics g)
{ g.drawRect(20,25,100,100);
g.fillRect(150,25,100,100); }
}
该程序的运行结果如图8.14所示。

【示例程序c8_11.java】 绘制圆角矩形。
import java.applet.Applet;
import java.awt.Graphics;
public class c8_11 extends Applet
{
public void paint(Graphics g)
{
g.fillRoundRect(10,15,50,80,70,10);
g.drawRoundRect(80,35,50,50,10,20);
g.fillRoundRect(150,15,80,80,0,0);
g.drawRoundRect(270,15,100,100,100,0);
g.drawRoundRect(390,50,70,40,90,50);
}
}

图8.15 程序c8_11的运行结果

示例程序c8_12.java】 绘制三维矩形。
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;
public class c8_12 extends Applet
{ public void paint(Graphics g)
{ g.setColor(Color.red);
g.draw3DRect(10,10,100,100,true);
g.draw3DRect(130,10,100,100,false);
g.fill3DRect(10,120,100,100,true);
g.fill3DRect(130,120,100,100,false);
}
}
该程序的运行结果如图8.16所示。

图8.16 程序c8_12的运行结果

8.4.2
绘制椭圆
在Java中,绘制一个椭圆需要指定4个参数,分别是外切矩
形左上角顶点坐标x,y和椭圆的宽度与高度。Graphics类中提供
了两种绘制椭圆的成员方法,分别是:
drawOval(int x,int y,int width,int height):用于绘制椭圆;
fillOval(int x,int y,int width,int height):用于绘制一个用当前
颜色填充的椭圆。
这两个方法中的x,y为外切矩形左上角顶点的坐标,width
为外切矩形的宽度,height为外切矩形的高度。方法中参数的详
细描述请参阅图8.17。这两个方法的区别仅在于前者不填充,而
后者会用当前颜色将椭圆区域进行填充。

图8.17 椭圆参数坐标
0

(height)
宽(width)

【示例程序c8_13.java】 绘制椭圆。
import java.applet.Applet;
import java.awt.Graphics;
public class c8_13 extends Applet
{
public void paint(Graphics g)
{
g.drawOval(20,25,50,100);
g.fillOval(120,35,100,50);
}
}

图8.18 程序c8_13的运行结果

8.4.3
绘制弧
画弧实际上是画部分椭圆。绘制一个弧需要指定6个参数,
这6个参数中的前4个的含义与椭圆中的相同,另外的2个参数一
个为起始角度,一个为弧角度。弧的角度用度数来衡量,表明
一段弧在两个角度之间绘制。Graphics类中提供了两种绘制弧的
成员方法,其格式如下:
drawArc(int x,int y,int width,int height,int startAngle,int arcAngle);
fillArc(int x,int y,int width,int height,int startAngle,int arcAngle)。

第一种格式用来绘制一个弧,其中:x,y为外切矩形左上
角顶点坐标值;width为外切矩形的宽度;height为外切矩形的高
度;startAngle为起始角度;arcAngle为弧角度。arcAngle表示从
起始角度转多少角度,arcAngle为正,表示逆时针画弧,
arcAngle为负,表示顺时针画弧。
第二种格式用来绘制一个弧并用当前颜色将弧填满。其中:
x,y为被填充弧的外切矩形的左上角顶点的坐标值;width为被
填充弧的外切矩形的宽度;height为被填充弧的外切矩形的高
度;startAngle为起始角度;arcAngle为弧角度。

图8.19 逆时针画弧
0
宽(width)

(height)

【示例程序c8_14.java】 绘制各种弧。
import java.applet.Applet;
import java.awt.Graphics;
public class c8_14 extends Applet
{ public void paint(Graphics g)
{ g.drawArc(15,15,80,80,0,180); // 逆时针画弧
g.drawArc(100,100,80,80,0,110);
g.fillArc(100,15,70,80,0,278);
g.fillArc(15,70,70,80,0,-110); // 顺时针画弧
g.fillArc(190,15,80,140,0,-360);
//当arcAngle与startAngle之差为360时成为椭圆
}
}

图8.20 程序c8_14的运行结果

8.4.4
绘制多边形
多边形是由一系列首尾相接的直线组成的,用户只需按照
某种次序连续绘制每一条直线,Java自动将最后一条直线的终点
与第一条直线的起点相连,就可形成多边形。多边形也是Java的
一个类——Polygon。因此,画多边形首先需要创建Polygon类的
对象,然后向该对象中添加点的坐标,最后调用drawPolygon()
成员方法或fillPolygon()成员方法画多边形。下面是绘制多边形
的具体步骤及所使用的成员方法。

1
.创建Polygon
类对象
创建Polygon类对象需要使用Polygon类的下述两个构造方法
之一:
public Polygon();
public Polygon(int xPoints[],int yPoints[],int nPoints);
无参数的Polygon构造方法创建一个不含任何坐标点的
Polygon对象。当需要坐标点时,可以再用Polygon中的成员方法
addPoint()将每个坐标点加入到Polygon对象中。
带参数的Polygon构造方法创建一个多边形对象,指定x坐标
的数据为数组xPoints[],y坐标的数据为数组yPoints[],坐标点的
总个数为nPoints。

2
.绘制多边形的Graphics
方法
表8.8
绘制多边形的Graphics
方法
成 员 方 法功 能 说 明
public abstract void drawPolygon(int xPoints[],
int yPoints[],int nPoints) 绘制一个由x点和y点数组定义的多边形
public abstract void drawPolygon(Polygon p) 绘制一个由指定多边形定义的多边形
public abstract void fillPolygon(int xPoints[],
int yPoints[],int nPoints) 使用当前颜色填充一个多边形
public abstract void fillPolygon(Polygon p) 使用当前颜色填充一个指定多边形

【示例程序c8_15.java】 绘制多边形。
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.*;
public class c8_50 extends Applet
{
int xs1[]={20,40,50,30,20,15,20}; //第一个多边形的x坐标数据
int ys1[]={20,20,30,50,50,30,20}; //第一个多边形的y坐标数据
int xs2[]={90,110,100,80,70,65,60,70}; //第二个多边形的x坐标数据
int ys2[]={90,110,80,100,100,80,60,70}; //第二个多边形的y坐标数据
//创建Polygon对象p4,p5

Polygon p4=new Polygon(xs1,ys1,7);
Polygon p5=new Polygon();
public void paint(Graphics g)
{
g.setColor(Color.red);
g.fillPolygon(xs2,ys2,8);
g.drawPolygon(p4);
//绘制五角星
p5.addPoint(190,20);

p5.addPoint(218,100);
p5.addPoint(150,46);
p5.addPoint(230,46);
p5.addPoint(162,100);
g.fillPolygon(p5);
}
}
该程序的运行结果如图8.21所示。

图8.21 程序c8_15的运行结果

8.4.5
复制图形
在制作动画时,常常需要将一个图形稍微移动位置后重新
显示出来,即将图中的一块区域复制到另一块区域中。Graphics
类提供的copyArea(拷贝)方法就是实现这一操作的。Graphics类
的拷贝方法格式如下:
copyArea(int x,int y,int width,int height,int dx,int dy);
其中,x,y为矩形左上角顶点坐标,width为矩形的宽度,
height为矩形的高度,这是我们要复制的图形范围,而dx和dy分
别表示从(x,y)开始的偏移量,即(x+dx,y+dy)为放置拷贝位置
的左上角坐标点。

【示例程序c8_16.java】 屏幕图形移位重画。
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;
public class c8_16 extends Applet
{
int xs1[]={20,40,50,30,20,15,20};
int ys1[]={20,20,30,50,50,30,20};
int xs2[]={90,110,100,80,70,65,60,70};
int ys2[]={90,110,80,100,100,80,60,70};

public void paint(Graphics g)
{
g.setColor(Color.red);
g.drawPolygon(xs1,ys1,7); //绘制多边形
g.fillPolygon(xs2,ys2,8); //绘制填充的多边形
g.copyArea(0,0,200,200,140,10); //将上述两个图形复制到另一
个区域
}
}

图8.22 程序c8_16的运行结果

8.4.6
绘图模式
AWT提供了两种绘图模式:
(1) 覆盖模式:在一个图形上画另一个图形时,直接将后一
图形画在前一个图形的上面,使前一图形中与后一图形的重叠部
分不可见。缺省的绘图模式为覆盖模式。
(2) 异或模式:在此模式下,后一图形并不直接覆盖在前一
个图形之上,而是将两个图形的重叠区域的像素进行异或运算,
以运算结果作为图形的设置来显示。这是制作多彩图形、创造动
画效果的一种高效方式。异或模式由Graphics类的成员方法
setXORMode()来设置,格式如下:
setXORMode(Color c)

【示例程序c8_17.java】 绘制多彩图形。
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;
public class c8_17 extends Applet
{
public void paint(Graphics g)
{ //首先使用系统默认的覆盖模式绘图
g.setColor(Color.blue);
g.fillRect(20,30,123,45);

g.setColor(Color.yellow);
g.fillOval(30,20,123,34);
g.setColor(Color.orange);
g.fillOval(130,20,35,23);
g.setXORMode(Color.green); //设置异或模式
g.fillOval(120,30,110,14);
g.setColor(Color.red);
g.fillArc(150,40,20,20,4,360);
g.setColor(Color.pink);
g.fillArc(30,30,30,30,0,397);
}
}