java语言学习后续.ppt
第7章 图形用户界面的设计与实现,7.1 图形用户界面概述7.2 用户自定义成分7.3 Java的事件处理7.4 GUI标准组件概述7.5 标签、按钮与动作事件7.6 文本框、文本区域与文本事件7.7 单、复选按钮,列表与选择事件,7.8 滚动条与调整事件7.9 画布与鼠标、键盘事件7.10 布局设计7.11 Panel与容器事件7.12 Frame与窗口事件7.13 菜单的定义与使用7.14 对话框、组件事件与焦点事件7.15 小结习题,本章介绍Java程序中图形用户界面(GUI)的设计与实现。图形用户界面是程序与用户交互的窗口。每个图形界面下的Java程序都必须设计、建立自己的图形用户界面并利用它接受用户的输入,向用户输出程序运行的结果。本章将介绍图形用户界面的基本组成和主要操作,包括绘制图形,显示动画,使用AWT包各组件和实现Java的事件处理功能等。,7.1 图形用户界面概述设计和构造用户界面,是软件开发中的一项重要工作。用户界面是计算机的使用者用户与计算机系统交互的接口,用户界面功能是否完善,使用是否方便,将直接影响到用户对应用软件的使用。图形用户界面(graphics user interface)简称GUI,使用图形的方式借助菜单、按钮等标准界面元素和鼠标操作,帮助用户方便地向计算机系统发出命令,启动操作,并将系统运行的结果同样以图形的方式显示给用户。图形用户界面操作简便,省去了字符界面用户必须记忆各种命令的麻烦,已经成为目前几乎所有应用软件的既成标准。所以,学习设计和开发图形用户界面,是软件开发人员必修的一课。,随着图形用户界面的普及和界面元素标准化程度的提高,许多辅助设计和实现图形用户界面的方法和工具也相应出现,例如,可视化编程方法允许设计人员直接绘出图形界面,然后交给专门的工具自动编码生成这个图形界面,免除了开发者的许多编程负担,目前许多应用软件开发工具都具有可视化编程的功能。Java语言中,为了方便图形用户界面的开发,设计了专门的类库来生成各种标准图形界面元素和处理图形界面的各种事件。这个用来生成图形用户界面的类库就是java.awt包。AWT是abstract window toolkit(抽象窗口工具集)的缩写。,所谓抽象,是因为Java是一种跨平台的语言,要求Java程序能在不同的平台系统上运行,这对于图形用户界面尤其困难。为了达到这个目标,AWT类库中的各种操作被定义成在一个并不存在的“抽象窗口”中进行。正如Java虚拟机使得Java程序独立于具体的软硬件平台一样,“抽象窗口”使得开发人员所设计的界面独立于具体的界面实现。也就是说,开发人员用AWT开发出的图形用户界面可以适用于所有的平台系统。当然,这仅是理想情况。实际上AWT的功能还不是很完全,Java程序的图形用户界面在不同的平台上(例如,在不同的浏览器中)可能会出现不同的运行效果,如窗口大小、字体效果将发生变化等。,首先考察一下图形用户界面的构成。简单地说,图形用户界面就是一组图形界面成分和界面元素的有机组合,这些成分和元素之间不但外观上有着包含、相邻、相交等物理关系,内在的也有包含、调用等逻辑关系,它们互相作用、传递消息,共同组成一个能响应特定事件、具有一定功能的图形界面系统。,设计和实现图形用户界面的工作主要有两个:创建组成界面的各成分和元素,指定它们的属性和位置关系,根据具体需要排列它们,从而构成完整的图形用户界面的物理外观。定义图形用户界面的事件和各界面元素对不同事件的响应,从而实现图形用户界面与用户的交互功能。Java中构成图形用户界面的各种元素和成分可以粗略地被分为三类:容器、控制组件和用户自定义成分。,1.容器容器是用来组织其他界面成分和元素的单元。一般说来一个应用程序的图形用户界面首先对应于一个复杂的容器,如一个窗口。这个容器内部将包含许多界面成分和元素,这些界面元素本身也可能又是一个容器,这个容器再进一步包含它的界面成分和元素,依此类推就构成一个复杂的图形界面系统。容器的引入有利于分解图形用户界面的复杂性,当界面的功能较多时,使用层层相套的容器是非常有必要的。,2.控制组件与容器不同,控制组件是图形用户界面的最小单位之一,它里面不再包含其他的成分。控制组件的作用是完成与用户的一次交互,包括接收用户的一个命令(如菜单命令),接收用户的一个文本或选择输入,向用户显示一段文本或一个图形,等等。从某种程度上来说,控制组件是图形用户界面标准化的结果,目前常用的控制组件有选择类的单选按钮、复选按钮、下拉列表;有文字处理类的文本框、文本区域;有命令类的按钮、菜单等。其中文本框、按钮和标签是前面使用过的GUI组件。,使用控制组件,通常需要如下的步骤:(1)创建某控制组件类的对象,指定其大小等属性。(2)使用某种布局策略,将该控制组件对象加入到某个容器中的某指定位置处。(3)将该组件对象注册给它所能产生的事件对应的事件监听者,重载事件处理方法,实现利用该组件对象与用户交互的功能。严格说来,容器也是一种控制组件,因为一个容器也可以被视为组件而包含在其他容器的内部。,3.用户自定义成分除了上述的标准图形界面元素,编程人员还可以根据用户的需要设计一些用户自定义的图形界面成分,例如绘制一些几何图形、使用标志图案等。用户自定义成分由于不能像标准界面元素一样被系统识别和承认,所以通常只能起到装饰、美化的作用,而不能响应用户的动作,也不具有交互功能。,7.2 用户自定义成分本节主要介绍如何利用Java类库中的类及其方法来绘制用户自定义的图形界面成分。编程人员可以利用这些方法自由地绘制图形和文字,也可以将已经存在的图形、动画等加载到当前程序中来。绘制图形和文字将要用到前面已经接触过的类Graphics。,Graphics是java.awt包中一个类,其中包括了很多绘制图形和文字的方法。当一个Applet运行时,执行它的浏览器会自动为它创建一个Graphics类的实例,利用这个实例,就可以在Applet中随意绘制图形和文字。实际上Applet本身就是一个图形界面的容器。而如果希望在图形界面的Java Application程序中绘制图形,则需要创建一个Canvas类的对象加入到这个Application程序的图形界面容器中,Canvas对象也拥有一个与Applet类的paint()方法相同的paint()方法,利用系统传递给这个paint()方法的Graphics类参数对象就可以在Application程序的图形用户界面中绘制各种图形和文字。,7.2.1 绘制图形利用Graphics类可绘制的图形有直线、各种矩形、多边形、圆和椭圆等。下面的例子综合了这些方法。例 7-1 DrawFigures.java 1:import java.awt.*;2:import java.applet.Applet;3:public class DrawFigures extends Applet4:5:public void paint(Graphics g)6:7:g.drawLine(30,5,40,5);/画直线,8:g.drawRect(40,10,50,20);/画矩形框(左上角x坐标,左上角y坐标,x轴尺寸,y轴尺寸)9:g.fillRect(60,30,70,40);/画实心矩形10:g.drawRoundRect(110,10,130,50,30,30);/画圆角矩形框11:g.drawOval(150,120,70,40);/画椭圆形框(左上角x坐标,左上角y坐标,x轴尺寸,y轴尺寸),若x轴尺寸与y轴尺寸相等,则画出圆形12:g.fillOval(190,160,70,40);/画实心椭圆13:g.drawOval(90,100,50,40);/画椭圆框14:g.fillOval(130,100,50,40);/画实心椭圆15:drawMyPolygon(g);/自定义的画多边形的方法16:g.drawString(They are figures!,100,220);,17:18:public void drawMyPolygon(Graphics g)19:20:int xCoords=30,50,65,119,127;/保存多边形各点x坐标的数组21:int yCoords=100,140,127,169,201;/保存多边形各点y坐标的数组22:g.drawPolygon(xCoords,yCoords,5);/画自由多边形框23:24:,图7.1是例7-1的运行结果。从例7-1可以看出,要在Java程序图形界面的容器中绘制图形,首先,需要明确希望绘制的图形是什么,是圆、椭圆,还是直线,这由所选定的方法来确定;其次,需要指明所绘制图形或文字的大小和位置,这要通过相对于界面容器的二维像素坐标来决定。Java的屏幕坐标是以像素为单位,容器的左上角被确定为横坐标(x轴)和纵坐标(y轴)的起点,向右和向下延伸坐标值递增。,图 7.1 例7-1的运行结果,绘制图形的方法很多,每种方法一般也有多种灵活的使用方式,这里不再赘述,读者可以查阅程序员手册中的详细规定。除了Graphics类,Java中还定义了其他一些用来表示几何图形的类,对绘制用户自定义成分也很有帮助。例如,利用Point表示一个像素点;利用Dimension类表示宽和高;利用Rectangle类表示一个矩形;利用Polygon类表示一个多边形;利用Color类表示颜色等,后面的例子中将利用这些系统定义的类绘图。,7.2.2 显示文字从前面的例子中可以知道,Graphics类的方法drawString()可以在屏幕的指定位置显示一个字符串。Java中还有一个类Font,使用它可以获得更加丰富多彩和逼真精确的字体显示效果。一个Font类的对象表示了一种字体显示效果,包括字体类型、字型和字号。下面的语句用于创建一个Font类的对象:Font MyFont=new Font(TimesRoman,Font.BOLD,12);MyFont对应的是12磅TimesRoman类型的黑体字,其中指定字型时需要用到Font类的三个常量:Font.PLAIN,Font.BOLD,Font.ITALIC。,如果希望使用该Font对象,则可以利用Graphics类的setFont()方法:g.setFont(MyFont);如果希望指定控制组件,如按钮或文本框中的字体效果,则可以使用控制组件的方法setFont()。如设btn是一个按钮对象,则语句:btn.setFont(MyFont);将把这个按钮上显示的标签的字体改为12磅的TimesRoman黑体字。另外,与setFont()方法相对的getFont()方法将返回当前Graphics或组件对象使用的字体。,例 7-2 AvailableFonts.java1:import java.applet.*;2:import java.awt.*;3:4:public class AvailableFont extends Applet5:6:GraphicsEnvironment gl=GraphicsEnvironment.getLocalGraphicsEnvironment();7:String FontNames=gl.getAvailableFontFamilyNames();8:9:public void paint(Graphics g)10:,11:Font current,oldFont;12:13:oldFont=g.getFont();14:for(int i=0;iFontNames.length;i+)15:16:current=new Font(FontNamesi,Font.PLAIN,10);17:g.setFont(current);18:g.drawString(current.getName(),10+i%4*120,20+i/4*15);19:20:g.setFont(oldFont);21:22:,在例7-2中,首先在第6句利用java.awt包的GraphicsEnvironment类的静态方法getLocalGraphicsEnvironment()获得代表Java程序运行的当前平台的图形环境的对象gl,然后在第7句调用gl对象的getAvailableFontFamilyNames()获得当前平台上所有可以使用的字体名字,返回给字符串数组FontNames,该数组的每个元素是一代表字体名的字符串。第13句首先获取并保存当前缺省的字体对象。第14到19句的循环修改当前字体,设置成一可用的字体并输出该字体的名称,每四个字体占用一行;其中第16句使用Font类的构造函数创建新字体对象。最后,第20句把字体恢复成原来的缺省值。例7-2的运行结果如图7.2所示。,图 7.2 例7-2的运行结果,7.2.3 控制颜色Applet中显示的字符串或图形的颜色可以用Color类的对象来控制,每个Color对象代表一种颜色,用户可以直接使用Color类中定义好的颜色常量,也可以通过调配红、绿、蓝三色的比例创建自己的Color对象。Color类中定义有如下的三种构造函数:public Color(int Red,int Green,int Blue);public Color(float Red,float Green,float Blue);public Color(int RGB);,不论使用哪个构造函数创建Color对象,都需要指定新建颜色中R(红)、G(绿)、B(蓝)三色的比例。在第一个构造函数中通过三个整型参数指定R,G,B,每个参数的取值范围在0255之间;第二个构造函数通过三个浮点参数指定R,G,B,每个参数的取值范围在0.01.0之间;第三个构造函数通过一个整型参数指明其RGB三色比例,这个参数的07比特(取值范围为0255)代表红色的比例,815比特代表绿色的比例,1623比特代表蓝色的比例。例如下面的语句创建的是蓝色:Color blueColor=new Color(0,0,255);,调用Graphics对象的setColor()方法可以把当前的缺省颜色修改成新建的颜色,使此后调用该Graphics对象完成的绘制工作,如绘制图形、字符串等,都使用这个新建颜色:g.setColor(blueColor);除了创建自己的颜色,也可以直接使用Color类中定义好的颜色常量,如:g.setColor(Color.cyan);Color类中共定义了13种静态颜色常量,包括black,orange,pink,grey等,使用时只需以Color为前缀,非常方便。,对于GUI的控制组件,它们有四个与颜色有关的方法分别用来设置和获取组件的背景色和前景色:public void setBackground(Color c)public Color getBackground()public void setForeground()public Color getForeground()例 7-3 UseColor.java1:import java.applet.Applet;2:import java.awt.*;3:4:public class UseColor extends Applet5:,6:Color oldColor;7:String ParamName=red,green,blue;/三个HTML参数的名称8:int RGBarray=new int3;/保存三色比例的数组9:10:public void init()11:12:for(int i=0;iParamName.length;i+)/取得HTML文件指定的三色13:RGBarrayi=Integer.parseInt(getParameter(ParamNamei);14:15:public void paint(Graphics g),16:17:oldColor=g.getColor();/保存原有的缺省颜色18:g.setColor(new Color(RGBarray0,RGBarray1,RGBarray2);/置新颜色19:g.drawString(How do you think about Current color:20:+g.getColor().toString(),10,20);/用新建颜色显示该颜色的三色分量21:g.setColor(oldColor);/恢复原有颜色22:g.drawString(Back to old default color:+g.getColor().toString(),10,40);23:24:,例7-3的运行结果如图7.3所示。例7-3利用HTML文件传递给Java Applet的三个参数作为R,G,B三色的比例。第18句用该比例创建颜色,并用新颜色显示字符串(包括新颜色中三色的比例含量)。第21句再恢复原来的缺省颜色。,图 7.3 例7-3的运行结果,此程序对应的HTML文件如下:UseColor 通过改变三个参数的数值(应在0255之间),就可以指定不同的颜色而不需要重新编译Java Applet程序。,7.2.4 显示图像由于图像的数据量要远远大于图形,所以一般不在程序中自行绘制图像,而是把已经存在于本机硬盘或网络某地的二进制图像文件直接调入内存。图像文件有多种格式,如bmp文件、gif文件、tiff文件等等,其中gif是Internet上常用的图像文件格式。Java中可以利用Graphics类的drawImage()方法显示图像,现考察下面的例子。例 7-4 DrawMyImage.java,1:import java.awt.*;2:import java.applet.Applet;3:public class DrawMyImage extends Applet4:5:Image myImage;6:public void init()7:8:myImage=getImage(getDocumentBase(),blackbrd.gif);9:10:public void paint(Graphics g)11:,12:g.drawImage(myImage,0,0,this);13:14:例7-4中,使用了Image类的对象myImage来保存二进制的图像数据,其中getImage()方法是系统为Applet类定义的方法,该方法将指定图像文件的内容加载到内存的Image对象中。getImage()方法有两个参数。第一个是图像文件所在的URL地址,在上例中由于图像文件与HTML文件保存在同一路径下,所以用Applet类另一个方法getDocumentBase()来获取含有该Applet的HTML文件的URL地址。getImage()的第二个参数是图像文件的文件名。Java可识别的图像文件格式有bmp,gif,jpeg等。,drawImage()是Graphics类中用来显示图像的方法。它的第一个参数是保存有图像数据的Image对象。第二、第三个参数是图像的左上角点坐标,它们决定了图像在容器中的显示位置。最后一个参数是显示图像的容器对象。例7-4中的this代表了当前的Applet对象。,7.2.5 实现动画效果动画曾是Java Applet最吸引人的特性之一。用Java实现动画的原理与放映动画片类似,取若干相关的图像或图片,顺序、连续地在屏幕上先显示,后擦除,循环往复就可以获得动画的效果。参考下面的例子。例 7-5 ShowAnimator.java,1:import java.applet.Applet;2:import java.awt.*;3:4:public class ShowAnimator extends Applet5:6:Image m-Images;/保存图片序列的Image数组7:int totalImages=18;/图片序列中的图片总数8:int currentImage=0;/当前时刻应该显示的图片 序号9:10:public void init()11:12:m-Images=new ImagetotalImages;,13:/从当前目录下的images子目录中将Img001.gif到 Img0018.gif的文件加载14:for(int i=0;itotalImages;i+)15:m-Imagesi=getImage(getDocumentBase(),imagesImg00+(i+1)+.gif);16:17:public void start()18:19:currentImage=0;/从第一幅开始显示20:21:public void paint(Graphics g)22:23:g.drawImage(m-ImagescurrentImage,50,50,this);/显示当前序号的图片,24:currentImage=+currentImage%totalImages;/计算下一个应显示图片的序号25:try26:Thread.sleep(50);/程序休眠50毫秒27:28:catch(InterruptedException e)/处理执行休眠方法可能引发的异常29:30:showStatus(e.toString();31:32:repaint();/图片停留50毫秒后被擦除,重新调 用paint()显示下一张图片33:34:,例7-5中使用了Thread.sleep()方法,目的是使当前的程序线程休眠一段时间,以便每幅图片在下一幅图片显示之前能在屏幕上逗留一小段时间,关于线程的具体编程将在以后的章节详细介绍。第14句到第15句的循环使用Applet的getImage()方法获取所有的.gif图像文件(注意其目录)。第21句到33句的paint()方法一次显示一幅图像,稍待片刻后再显示Image对象数组中的下一幅图像。图7.4是例7-5的运行结果。,图 7.4 例7-5的运行结果,在设计和实现程序的图形用户界面的过程中,绘制用户自定义成分仅仅完成了一部分工作,它可以装饰、美化用户界面,但却无法接收程序运行过程中的即时用户指令,不能提供与用户的动态交互。Java中用来解决这个问题的机制是事件及其处理。,7.3 Java的事件处理图形用户界面之所以能为广大用户所喜爱并最终成为事实上的标准,很重要的一点就在于它可以用更灵活、简便的方式来接收用户命令。用户在图形用户界面中输入命令是通过移动鼠标对特定图形界面元素单击、双击鼠标键来实现的,为了能够接收用户的命令,图形用户界面的系统首先应该能够识别这些鼠标和键盘的操作并做出相应的响应。,通常每一个键盘或鼠标操作会引发一个系统预先定义好的事件,用户程序只需要编制代码定义每个特定事件发生时程序应做出何种响应即可。这些代码会在它们对应的事件发生时由系统自动调用,这就是图形用户界面中事件和事件响应的基本原理。Java中,除了键盘和鼠标操作,系统的状态改变、标准图形界面元素等都可以引发事件,对这些事件分别定义处理代码,就可以保证应用程序系统在不同的状况下都合理有效、有条不紊地正常工作。Java的事件处理机制中引入了委托事件模型(如图7.5所示),不同的事件由不同的监听者处理。,图 7.5 委托事件模型,图7.5中,图形用户界面的每个可能产生事件的组件被称为事件源,不同事件源上发生的事件的种类不同。例如,Button对象或MenuItem对象等作为事件源可能引发ActionEvent类代表的事件ACTION-PERFORMED;Checkbox对象等作为事件源可能引发ItemEvent类代表的事件ITEM-STATE-CHANGES。,希望事件源上发生的事件被程序处理,就要把事件源注册给能够处理该事件源上那种类型事件的监听者。例如Button对象把自己注册给实现了ActionListener接口的对象,因为只有这种对象能够处理Button对象上发生的ActionEvent类的事件,监听者可以是包容事件源的容器,也可以是另外的对象。具体的注册方法是通过调用事件源本身的相关方法,例如调用Button类自身的addActionListener()方法,并以监听者对象作为实际参数来实现的。,监听者之所以成为监听者,并具有监听和处理某类事件的功能,是因为它实现了有关的接口,所以监听者需要对它所实现接口的所有抽象方法写出具体的方法体,对应事件源上发生的事件的处理代码就写在这些方法体里。例如对Button上发生的事件的处理代码应该写在Button对象所注册的监听者的actionPerformed()方法中,这个方法是对ActionListener接口中同名抽象方法的具体实现。,当事件源上发生监听者可以处理的事件时,事件源把这个事件作为实际参数传递给监听者中负责处理这类事件的方法(委托),这个方法被系统自动调用执行后,事件就得到了处理。这里,监听者并不一定是包容事件源的容器对象,这样处理使得程序中的事件处理代码与GUI界面构成代码得以分离,有利于优化程序结构;另外,由于Java对事件作了详细的分类并委托不同的接口方法加以处理,使得代码性能得到提高。Java的所有事件类和处理事件的监听者接口都定义在包中,其中事件类的层次结构如图7.6所示。,图 7.6 AWTEvent类体系结构图,这个体系结构图中包括的事件类很多,它们都是类的子类,而类则是类的子类。EventObject有一个重要的方法getSource()在前面已经使用过,该方法返回产生事件的事件源,几乎所有的事件类都要用到这个方法。需要注意的是,并非每个事件类都只对应一个事件,例如KeyEvent类可能对应KEY-PRESSED(键按下)、KEY-RELEASED(键松开)、KEY-TYPED(击键)三个具体的事件。,判断一个KeyEvent类的对象到底代表哪种事件,可以调用它的getID()方法并把方法的返回值与KEY-PRESSED等几个常量相比较。每个事件类的对象都拥有getID()方法,是它们从共同的父类AWTEvent那里继承来的。,包中还定义了11个监听者接口,每个接口内部包含了若干处理相关事件的抽象方法。一般说来,每个事件类都有一个监听者接口与之相对应,而事件类中的每个具体事件类型都有一个具体的抽象方法与之相对应,当具体事件发生时,这个事件将被封装成一个事件类的对象作为实际参数传递给与之对应的具体方法,由这个具体方法负责响应并处理发生的事件。例如与ActionEvent类事件对应的接口是ActionListener,这个接口定义了抽象方法:public void actionPerformed(ActionEvent e);,凡是要处理ActionEvent事件的类都必须实现ActionListener接口,实现ActionListener接口就必须重载上述的actionPerformed()方法,在重载的方法体中,通常需要调用参数e的有关方法。例如调用e.getSource查明产生ActionEvent事件的事件源,然后再采取相应的措施处理该事件。,比较特殊的情况有两个:一个是InputEvent类,因为它不对应具体的事件,所以没有监听者与之相对应;另一个是MouseEvent类,它有两个监听者接口与之相对应,一个是MouseListener接口(其中的方法可以响应MOUSE_CLICKED,MOUSE_ENTERED,MOUSE_EXITED,MOUSE_PRESSED,MOUSE_RELEASED五个具体事件),另一个是MouseMotionListener接口(其中的方法可以响应MOUSE_DRAGGED,MOUSE_MOVED的两个事件)。具体事件及其处理将结合GUI组件详细介绍。,7.4 GUI标准组件概述构建程序的图形用户界面的主要任务有两个:一是创建各界面组件并排列成图形用户界面的物理外观;二是定义这些组件对不同事件的响应从而完成图形用户界面功能。从本节开始将具体讨论如何用标准组件来构建图形用户界面,以及定义这些组件对事件的响应,包括它们相互之间和与用户之间的交互功能。,组成图形用户界面的成分有三类,前面已讨论过其中的用户自定义成分,余下的两类容器和控制组件都属于图形用户界面的标准组件,一般说来,容器是能够容纳并排列其他组件的对象,基本组件是放置在容器中的对象。在Java中,它们是由AWT包中的对象来代表的。这些对象间的层次关系可以参看图7.7,可见所有的GUI标准组件都是java.awt.*包中的根类Component类的子类,Component类的直接子类包括一个容器组件Container和八个基本组件,如Button,Label,Choice,TextComponent等。,其中TextComponent可以细分为包含多行文本的TextArea和包含单行文本的TextField;Container是所有容器组件的根类,容器组件的作用是包容其他组件并按一定的方式组织排列它们,同一个容器中的所有部件通常总是同时被显示和同时被隐藏的。从图7.7的AWT组件体系结构中可以看出,所有的容器组件都是Container类的子类,而Container类又是Component类的子类。作为Container子类的容器可分为三组:Panel和Applet一组的容器是无边框的;ScrollPanel一组是可以自动处理滚动操作的容器;Window,Frame,Dialog和FileDialog是一组大都含有边框,并可以移动、放大、缩小、关闭的功能较强的容器。,图 7.7 AWT组件层次关系图,基本控制组件被安放在容器中的某个位置,用来完成一种具体地与用户交互的功能。使用基本控制组件一般包括如下的步骤:(1)创建某种基本控制组件类的新对象,指定该对象的属性,如外观、大小等。(2)将该组件对象加入到某个容器的合适位置。(3)创建该组件对象的监听者,即实现以该组件为事件源的事件对应的监听者接口,也可以使现有的类实现该接口成为监听者。将该组件对象注册给此监听者,并在监听者内部实现监听者接口中定义的方法,对该组件可能引发的事件加以处理,定义新加入的组件对象的交互性界面功能,如接收用户输入的文本或选择、做屏幕显示输出等。,Component类是所有组件和容器的抽象父类,其中定义了一些每个容器和组件都可能用到的方法,较常用的有:(1)public void add(PopupMenu popup):在组件上加入一个弹出菜单,当用户用鼠标右键单击组件时将弹出这个菜单。(2)public Color getBackground():获得组件的背景色。(3)public Font getFont():获得组件使用的字体。(4)public Color getForeground():获得组件的前景色。,(5)public Graphics getGraphics():获得在组件上绘图时需要使用的Graphics对象。(6)public void repaint(int x,int y,int width,int height):以指定的坐标点(x,y)为左上角,重画组件中指定宽度(width)、指定高度(height)的区域。(7)public void setBackground(Color c):设置组件的背景色。(8)public void setEnabled(boolean b):设置组件的使能状态。参数b为真则组件使能,否则组件不使能。只有使能状态的组件才能接受用户输入并引发事件。,(9)public void setFont(Font f):设置组件使用的字体。(10)public void setSize(int width,int height):设置组件的大小。(11)public void setVisible(boolean b):设置组件是否可见的属性。参数b为真时,组件在包括它的容器可见时也可见;否则组件不可见。(12)public void setForeground(Color c):设置组件的前景色。(13)public void requestFocus():使组件获得注意的焦点。下面将从创建、常用方法和事件响应几个方面逐一介绍常用的GUI组件和容器。,7.5 标签、按钮与动作事件1.标签(Label)标签是用户不能修改只能查看其内容的文本显示区域,它起到信息说明的作用,每个标签用一个Label类的对象表示。(1)创建标签创建标签对象时应同时说明这个标签中的字符串:Label prompt=new Label(请输入一个整数:);(2)常用方法,如果希望修改标签上显示的文本,则可以使用Label对象的方法setText(新字符串),同样对于一个未知的标签,可以通过调用Label对象的getText()方法来获得它的文本内容。例如下面的程序片断将修改标签中的文本内容:if(prompt.getText()=你好)prompt.setText(再见);else if(prompt.getText()=再见)prompt.setText(你好);(3)产生事件标签不能接受用户的输入,所以不能引发事件。它不是事件源。,2.按钮(Button)按钮是图形用户界面中非常重要的一种基本组件,按钮本身不显示信息,它一般对应一个事先定义好的功能操作,并对应一段程序。当用户点击按钮时,系统自动执行与该按钮相联系的程序,从而完成预先指定的功能。(1)创建下面的语句用来创建按钮,传递给构造函数的字符串参数指明了按钮上的标签:Button enter=new Button(操作);(2)常用方法,调用按钮的getLabel()方法可以返回按钮标签字符串;调用按钮的setLabel(String s)方法可以把按钮的标签设置为字符串s。(3)产生事件按钮可以引发动作事件,当用户单击一个按钮时就引发了一个动作事件,希望响应按钮引发的动作事件的程序必须把按钮注册给实现了ActionListener接口的动作事件监听者,同时,为这个接口的actionPerformed(ActionEvent e)方法书写方法体。在方法体中,可以调用e.getSource()方法来获取引发动作事件的按钮对象引用,也可以调用e.getActionCommand()方法来获取按钮的标签或事先为这个按钮设置的命令名。,例 7-6 BtnLabelAction.java1:import java.applet.*;2:import java.awt.*;3:import java.awt.event.*;4:5:public class BtnLabelAction extends Applet implements ActionListener6:7:Label prompt;8:Button btn;9:public void init()10:11:prompt=new Label(你好);,12:btn=new Button(操作);13:add(prompt);14:add(btn);15:btn.addActionListener(this);16:17:public void actionPerformed(ActionEvent e)18:19:if(e.getSource()=btn)20:if(prompt.getText()=你好)21:prompt.setText(再见);22:else23:prompt.setText(你好);24:25:,例7-6中的Applet程序包括一个标签对象prompt和一个按钮对象btn。第5句声明该类将实现ActionListener接口,是ActionEvent事件的监听者。第15句将按钮对象btn注册给这个监听者,这样它将监听并处理btn引发的动作事件。第17到24句的actionPerormed()方法在用户单击btn时被系统自动调用。第19句判断动作事件是否是由按钮btn引发的,是则修改prompt对象的文本标签。图 7.8为例