《图形用户界面的设计与实现.ppt》由会员分享,可在线阅读,更多相关《图形用户界面的设计与实现.ppt(258页珍藏版)》请在金锄头文库上搜索。
1、第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 对话框、组件事件与焦点事件在Java语言中,为了支持图形用 户 界 面 的 开 发 , 设 计 了 类 库java.awt包来生成各种标准图形界面元素和处理图形界面的各种事件。AWT是abstract wi
2、ndow toolkit(抽象窗口工具集)的缩写。 7.1 图形用户界面概述图形用户界面的构成:图形用户界面是一组图形界面成分和界面元素的有机组合,这些成分和元素之间不但外观上有着包含、相邻、相交等物理关系,内在的也有包含、调用等逻辑关系,它们互相作用、传递消息,共同组成一个能响应特定事件、具有一定功能的图形界面系统。设计和实现图形用户界面的工作主要两个: 创建组成界面的各元素,指定它们的属性和位置关系,构成完整的图形用户界面的外观。 定义图形用户界面的事件和各界面元素对不同事件的响应,实现与用户的交互。Java中构成图形用户界面的各种元素和成分有三类:容器、控制组件和用户自定义成分。1. 容
3、器容器是用来组织其他界面成分和元素的单元。一个应用程序的图形用户界面首先对应于一个复杂的容器,如一个窗口。利用容器有利于分解图形用户界面的复杂性,当界面的功能较多时,可以使用嵌套的容器。2. 控制组件控制组件是图形用户界面的最小单位之一,它里面不再包含其他的成分。控制组件的作用是完成与用户的一次交互,包括接收用户的一个命令(如菜单命令),接收用户的一个文本或选择输入,向用户显示一段文本或一个图形,等等。使用控制组件的步骤:(1) 创建某控件类对象,指定属性。(2) 使用某种布局,将该控件对象加入到某容器中的指定位置。(3) 将该组件对象注册给它所能产生的事件对应的事件监听者,重载事件处理方法,
4、实现利用该组件对象与用户交互的功能。实际上,容器也是一种控件,因为一个容器也可以被视为组件而包含在其他容器的内部。3. 用户自定义成分绘制几何图形、使用标志图案等。用户自定义成分不能被系统识别和承认,通常只能起到装饰、美化的作用,而不能响应用户的动作,也不具有交互功能。Graphics是java.awt包中一个类,包含绘制图形和文字的方法。当一个Applet运行时,执行它的浏览器自动为它创建一个Graphics实例,利用这个实例,可在Applet中随意绘制图形和文字。若需在图形界面的Java Application程序中绘制图形,则需创建一个Canvas类的对象加入到该Application程
5、序的图形界面容器中,Canvas对象也有一个与Applet类的paint( )方法相同的paint( )方法,利用系统传递给这个paint( )方法的Graphics类参数对象就可以在Application程序的图形用户界面中绘制各种图形和文字。7.2 用户自定义成分7.2.1 绘制图形利用Graphics类可绘制的图形有直线、各种矩形、多边形、圆和椭圆等。例 7-1 UsedDrawFigures .javaimport java.awt.*;import java.applet.Applet;public class UsedDrawFigures extends Applet publi
6、c void paint ( Graphics g) g.drawLine(30,5,40,5); /画直线 g.drawRect(40,10,50,20);/画矩形框(左上角x坐标,左上角y坐标,x轴尺寸,y轴尺寸) g.fillRect(60,30,70,40); /画实心矩形 g.drawRoundRect(110,10,130,50,30,30); /画圆角矩形框 g.drawOval(150,120,70,40); /画椭圆形框(左上角x坐标,左上角y坐标,x轴尺寸,y轴尺寸),/ 若x轴尺寸与y轴尺寸相等,则画出圆形 g.fillOval(190,160,70,40); /画实心椭
7、圆 g.drawOval(90,100,50,40); /画椭圆框 g.fillOval(130,100,50,40); /画实心椭圆 drawMyPolygon(g); /自定义的画多边形的方法 g.drawString(They are figures!,100,220); public void drawMyPolygon( Graphics g) int xCoords = 30,50,65,119,127; /保存多边形各点x坐标的数组 int yCoords = 100, 140,127,169,201; /保存多边形各点y坐标的数组 g.drawPolygon( xCoords,
8、yCoords,5); /画自由多边形框 7.2.2 显示文字Graphics类的方法drawString( )可在屏幕的指定位置显示一个字符串。Font类,可获得更丰富多彩和逼真精确的字体显示效果。一个Font类的对象表示了一种字体显示效果,包括字体、字型和字号。例如:Font MyFont = new Font ( “TimesRoman”, Font.BOLD, 12 ); MyFont对应的是12磅TimesRoman类型的黑体字,其中指定字型时需要用到Font类的三个常量:Font.PLAIN, Font.BOLD, Font.ITALIC。若需使用该Font对象,可利用Graphi
9、cs类的setFont( )方法: g. setFont ( MyFont );若指定控件的字体效果,如按钮或文本框等,可使用控件的方法setFont( )。设btn是按钮对象,则语句: btn.setFont(MyFont);把该按钮上显示的字体改为12磅的TimesRoman黑体字。getFont( )方法将返回当前Graphics或组件对象使用的字体。例 7-2 AvailableFonts.javaimport java.applet.*;import java.awt.*;public class AvailableFont extends Applet GraphicsEnviro
10、nment gl = GraphicsEnvironment.getLocalGraphicsEnvironment( );String FontNames = gl.getAvailableFontFamilyNames( );public void paint(Graphics g)Font current,oldFont; oldFont = g.getFont( ); for(int i=0;iFontNames.length;i+) current = new Font(FontNames i,Font.PLAIN,10); g.setFont(current); g.drawStr
11、ing(current.getName( ),10+i%4*120,20+i/4*15); g.setFont(oldFont); 7.2.3 控制颜色Applet中显示的字符串或图形的颜色可以用Color类的对象来控制,每个Color对象代表一种颜色,用户可以直接使用Color类中定义好的颜色常量,也可通过调配红、绿、蓝三色的比例创建自己的Color对象。Color类定义了三种构造函数:public Color(int Red, int Green, int Blue);/整型参数指定R,G,B的取值范围在0255之间public Color(float Red, float Green,
12、float Blue);/浮点参数R,G,B的取值范围在0.01.0之间public Color(int RGB); /整型参数指明RGB三色比例,这个参数的07比特(取值范围为0255)代表红色的比例,815比特代表绿色的比例,1623比特代表蓝色的比例例:创建蓝色:Color blueColor = new Color(0,0,255);Graphics对象的setColor( ):把当前的缺省颜色修改成新建的颜色,此后调用该Graphics对象完成的绘制工作,如绘制图形、字符串等,都使用这个新建颜色: g.setColor(blueColor);除了创建自己的颜色,也可以直接使用Colo
13、r类中定义好的颜色常量,如: 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( ) import java.applet.*;import java.aw
14、t.*;public class MyUseColor extends Applet Color oldColor; String ParamName = red,green,blue; /三个HTML参数的名称 int RGBarray = new int3; /保存三色比例的数组 public void init( ) for(int i=0;iParamName.length;i+) /取得HTML文件指定的三色 RGBarrayi = Integer.parseInt(getParameter(ParamNamei); public void paint(Graphics g) old
15、Color = g.getColor( ); /保存原有的缺省颜色 g.setColor(new Color(RGBarray0,RGBarray1,RGBarray2); /置新颜色 g.drawString(How do you think about Current color: + g.getColor( ).toString( ),10,20); /用新建颜色显示该颜色的三色分量 g.setColor(oldColor); /恢复原有颜色 g.drawString(Back to old default color:+ g.getColor( ).toString( ),10,40)
16、; 例 7-3 UseColor.javaHTML文件如下:UseColor 通过改变三个参数的数值(应在0255之间),就可以指定不同的颜色而不需要重新编译Java Applet程序。 7.2.4 显示图像图像文件有多种格式,如bmp文件、gif文件、tiff文件等等,其中gif是Internet上常用的图像文件格式。Java中可以利用Graphics类的drawImage( )方法来显示图像。import java.awt.*;import java.applet.Applet;public class UsedDrawMyImage extends Applet Image myImag
17、e ; public void init( ) myImage = getImage(getDocumentBase( ), Winter.gif); public void paint(Graphics g) g.drawImage(myImage, 0, 0, this ); /显示图像 例 7-4 UsedDrawMyImage.javadrawImage( )是Graphics类中用来显示图像的方法。第一个参数保存有图像数据的Image对象。第二、第三个参数是图像的左上角点坐标,它们决定了图像在容器中的显示位置。最后一个参数是显示图像的容器对象。this代表当前的Applet对象。 获
18、取、显示本机其它位置处的图像获取、显示本机其它位置处的图像:Image myImage = getToolkit().getImage(“E:新建相册IMG_0207.jpg”); 或:Image myImage = Toolkit.getDefaultToolkit().getImage(E:新建相册IMG_0207.jpg); 显示来自网上的某张图片:显示来自网上的某张图片:1.myImage = this.getToolkit().getImage(new URL(http:/ myImage = this.getImage(new URL(http:/ http:/ 实现动画效果动画是
19、Java Applet最吸引人的特性之一。用Java实现动画的原理与放映动画片类似,取若干相关的图像或图片,顺序、连续地在屏幕上先显示,后擦除,循环往复就可以获得动画的效果。例 7-5 MyShowAnimator.javaimport java.applet.Applet;import java.awt.*;public class MyShowAnimator extends Applet int x=10;Image m_Images;/保存图片序列的Image数组 int totalImages = 5; /图片序列中的图片总数 int currentImage = 0; /当前时刻应
20、显示的图片序号 public void init( ) m_Images = new ImagetotalImages; /从当前目录下的images子目录中将Img001.gif到Img0010.gif的文件加载 for(int i=0;itotalImages;i+) m_Imagesi= getImage(getDocumentBase( ),imageswinter00+(i+1) + .gif); public void start( ) currentImage = 0; /从第一幅开始显示 public void paint(Graphics g) g.drawImage(m_I
21、magescurrentImage,x,50,this); /显示当前序号的图片 x+=20; currentImage = +currentImage % totalImages; /计算下一个应显示图片的序号 try Thread.sleep(200); /程序休眠50毫秒 catch(InterruptedException e) /处理执行休眠方法可能引发的异常 showStatus(e.toString( ); repaint( ); /图片停留50毫秒后被擦除,重新调用paint( )显示下一张图片 Thread.sleep( ):使当前的程序线程休眠一段时间,以便每幅图片在下一幅
22、图片显示之前在屏幕上逗留一时间,线程的具体编程将在以后章节介绍。getImage( )方法获取所有的.gif图像文件(注意目录)。paint( )方法一次显示一幅图像,稍后再显示Image对象数组中的下一幅图像。图形用户界面事件响应的基本原理图形用户界面事件响应的基本原理:键盘或鼠标操作能引发系统预先定义好的事件,用户程序只需要编制代码定义每个特定事件发生时程序应做出何种响应即可。这些代码会在它们对应的事件发生时由系统自动调用。Java中,除了键盘和鼠标操作,系统的状态改变、标准图形界面元素等都可以引发事件,对这些事件分别定义处理代码,就可保证应用程序在不同状况下都合理有效、有条不紊地正常工作
23、。Java的事件处理机制中引入了委托事件模型(如下图),不同的事件由不同的监听者处理。7.3 Java的事件处理委托事件模型图形用户界面的每个可能产生事件的组件叫事件源,不同事件源上发生的事件的种类不同。如,Button对象或MenuItem对象等作为事件源可能引发ActionEvent类 代 表 的 事 件 ACTION-PERFORMED;Checkbox对象等作为事件源可能引发ItemEvent类代表的事件ITEM-STATE-CHANGES。希望事件源上发生的事件被程序处理,应把事件源注册给能够处理该事件源上那种类型事件的监听 者 。 例 如 Button对 象 把 自 己 注 册 给
24、 实 现 了ActionListener接口的对象,因为只有这种对象能够处理Button对象上发生的ActionEvent类的事件,监听者可以是包容事件源的容器,也可为另外的对象。注册方法是通过调用事件源本身的相关方法,例如调用Button类自身的addActionListener( )方法,并以监听者对象作为实际参数来实现的。监听者具有监听和处理某类事件的功能,因为它实现了有关的接口,所以监听者需要对它所实现接口的所有抽象方法写出具体的方法体,对应事件源上发生的事件的处理代码就写在这些方法体中。例如对Button上发生的事件的处理代码就是写在Button对象所注册的监听者的actionPer
25、formed( )方法中,这个方法是对ActionListener接口中同名抽象方法的具体实现。当事件源上发生监听者可以处理的事件时,事件源把这个事件作为实际参数传递给监听者中负责处理这类事件的方法(委托),该方法被系统自动执行后,事件就得到了处理。监听者不一定是包容事件源的容器对象,这使程序中的事件处理代码与GUI界面构成代码可以分离,利于优化程序结构;另外,由于Java对事件作了详细的分类并委托不同的接口方法来处理,这也提高了的代码性能。AWTEvent类体系结构图Java的所有事件类和处理事件的监听者接口都定义在java.awt.event包中,事件类的层次结构如右图。上 图 中 包 括
26、 的 事 件 类 基 本 都 是java.awt.AWTEvent类的子类,而java.awt.AWTEvent类则是java.util.EventObject类的子类。EventObject的一个重要方法是getSource( ) ,该方法返回产生事件的事件源,几乎所有的事件类都要用到该方法。注注意意:并非每个事件类都只对应一个事件,例如KeyEvent类可能对应KEY-PRESSED(键按下)、KEY-RELEASED(键松开)、KEY-TYPED(击键)三个具体的事件。判断一个KeyEvent类的对象到底代表哪种事件,可以调用它的getID( )方法并把方法的返回值与KEY-PRESSE
27、D等几个常量相比较。每个事件类的对象都拥有getID( )方法,是它们从共同的父类AWTEvent那里继承来的。7.4 GUI标准组件概述构建程序的图形用户界面的主要任务有两个:一、创建各界面组件并排列成图形用户界面的物理外观;二、定义组件对不同事件的响应、完成图形用户界面功能。AWT组件层次关系图 基本控件被安放在容器中的某个位置,用来完成用户交互的功能。使用基本控件的步骤如下:(1) 创建某基本控件类的对象,指定其属性,如外观、大小等。(2) 将该对象加入到某个容器的合适位置。(3) 创建该组件对象的监听者,即实现以该组件为事件源的事件对应的监听者接口,也可以使现有的类实现该接口成为监听者
28、。将该组件对象注册给此监听者,并在监听者内部实现监听者接口中定义的方法,对该组件可能引发的事件加以处理,定义新加入的组件对象的交互性界面功能,如接收用户输入的文本或选择、做屏幕显示输出等。 Component类是所有组件和容器的抽象父类,它定义了每个容器和组件都可能用到的方法,常用的有:(1) public void add(PopupMenu popup): 在组件上加入一个弹出菜单,当用户用鼠标右键单击组件时将弹出该菜单。(2) public Color getBackground( ): 获得组件的背景色。(3) public Font getFont( ): 获得组件使用的字体。(4)
29、 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)
30、: 设置组件的使能状态。参数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 v
31、oid requestFocus( ): 使组件获得注意的焦点。下面从创建、常用方法和事件响应几个方面来讨论常用的GUI组件和容器。7.5 标签、按钮与动作事件1. 标签(Label)标签是用户只能查看其内容的文本显示区域,每个标签用一个Label类的对象表示。(1) 创建标签创建标签对象时应同时说明这个标签中的字符串:Label prompt = new Label(请输入一个整数:); (2) 常用方法若需修改标签的文本,可以使用Label对象的方法setText(新字符串);对于一个未知标签,可通过调用Label对象的getText( )方法来获得它的文本内容。如下所示:if(promp
32、t.getText( )=你好)prompt.setText(再见);else if(prompt.getText( )=再见)prompt.setText(你好); (3) 产生事件标签不能接受用户的输入,所以不能引发事件。它不是事件源。2. 按钮(Button)按钮一般对应一个事先定义好的功能操作,并对应一段程序。当用户点击按钮时,系统自动执行与该按钮相联系的程序,从而完成预先指定的功能。(1) 创建创建一个按钮,传递给构造函数的字符串参数指明按钮上的标签: Button enter = new Button ( 操作);(2) 常用方法 getLabel( ) :返回按钮标签字符串;se
33、tLabel(String s) :把按钮的标签设置为字符串s。(3) 产生事件按钮可以引发动作事件,当用户单击一个按钮时就引发一个动作事件,希望响应按钮引发的动作事件的程序须把按钮注册给实现了ActionListener接口的动作事件监听者,并为这个接口的actionPerformed(ActionEvent e)方法书写方法体。在方法体中,可调用e.getSource( ) 获取引发动作事件的按钮对象引用,或调用e.getActionCommand( ) 获取按钮的标签或事先为这个按钮设置的命令名。 import java.applet.*;import java.awt.*;import
34、 java.awt.event.*;public class UsedBtnLabelAction extends Applet implements ActionListener Label prompt; Button btn; public void init( ) prompt = new Label(你好); btn = new Button(操作); add(prompt); add(btn); btn.addActionListener(this); public void actionPerformed(ActionEvent e) if(e.getSource( )=btn)
35、 if(prompt.getText( )=你好) prompt.setText(再见); else prompt.setText(你好); 例 7-6 UsedBtnLabelAction .java运行结果3. 动作事件(ActionEvent)ActionEvent类只包含一个事件,即执行动作事件ACTION-PERFORMED。ACTION-PERFORMED是引发某个动作执行的事件。能触发该事件的动作有以下四类:(1) 点击按钮;(2) 双击一个列表中的选项;(3) 选择菜单项;(4) 在文本框中输入回车。ActionEvent类的重要方法有:(1) public String ge
36、tActionCommand( )该方法返回引发事件的动作的命令名,该命令名可通过调用setActionCommand( ) 指定给事件源组件,也可使用事件源的缺省命令名。例如一个按钮组件m-Button是ACTION-PERFORMED事件的事件源,如下语句将这个按钮对象的动作命令名设为“命令名”并将它注册给当前的监听者: Button m-Button = new Button(按钮标签); m-Button.setActionCommand(命令名); m-Button.addActionListener(this); 动作事件的监听者需要实现动作,监听者接口的方法为:public vo
37、id actionPerformed(ActionEvent e)if ( e.getActionCommand( ) = 命令名 ) 注意:setActionCommand( )方法与getActionCommand( )方法属于不同的类,getActionCommand( )方法是ActionEvent类的方法,而setActionCommand( )方法是其上发生动作事件的事件源,如按钮、菜单项等的方法。事件源对象也可以不专门调用setActionCommand( )方法来指定命令名,此时getActionCommand( )方法返回缺省的命令名,例如上面的程序片断如果去掉设置动作命令名
38、的一句,则监听者接口的方法可以写为:public void actionPerformed(ActionEvent e)if ( e.getActionCommand( ) = 按钮标签 ) 可见按钮的缺省命令名就是按钮的标签。使用getActionCommand( )方法可以区分产生动作命令的不同事件源,使actionPerformed( )方法对不同事件源引发的事件区分对待处理(区分事件的事件源也可以使用getSource( )方法,但是这样一来处理事件的代码就与GUI结合得过于紧密,对于小程序尚可接受,对于大程序则不提倡)。 (2) public int getModifiers( )如
39、果发生动作事件的同时用户还按了Ctrl、Shift等功能键,则可以调用这个事件的getModifiers( )方法来获得和区分这些功能键,实际上是把一个动作事件再细分成几个事件;把一个命令细分成几个命令。将getModifiers( )方法的返回值与ActionEvent类的几个静态常量ALT-MASK,CTRL-MASK,SHIFT-MASK,META-MASK相比较,就可以判断用户按下了哪个功能键。7.6 文本框、文本区域与文本事件 1. 文本事件(TextEvent)TextEvent类只包含一个事件,即代表文本区域中文本变化的事件TEXT-VALUE-CHANGED,在文本区域中改变文
40、本内容。例如,删除字符、键入字符都将引发这个事件。该事件较简单,不需特别判断事件类型的方法和常量。2. 文本框与文本域(TextField与TextArea)Java中用于文本处理的基本组件有两种:单行文本框TextField和多行文本区域TextArea,它们都是TextComponent的子类。(1) 创建在创建文本组件的同时可以指出文本组件中的初始文本字符串,如下创建一个10行45列的多行文本区域:TextArea textArea1 = new TextArea(10,45);而创建能容纳8个字符,初始字符串为“卡号”的单行文本框可以使用如下的语句:TextField name = n
41、ew TextField(卡号,8); (2) 常用方法先介绍TextComponent中的常用方法,即TextField和TextArea都拥有的常用方法。用户可以在已创建好的文本区域中自由输入和编辑文本信息,对于用户输入的信息,可以调用TextComponent的getText( )方法来获得,这个方法的返回值为一个字符串。如果希望在程序中对文本区域显示的内容赋值,可以调用TextComponent的另一个方法setText( )。例如下面的语句:textArea1.setText(你好,欢迎!);将文本区域的内容置为“你好,欢迎!”。某些情况下需要将文本区域设为不能编辑的。例如,电话卡的
42、卡号是系统自动生成的,不需要也不允许用户随意改动,这时可用如下的语句使对应电话卡卡号的文本框cardNo不可被用户通过界面改动:cardNo.setEditable(false);使用isEditable( )方法判断当前的文本区域是否可以被编辑。TextComponent中还有一些用来指定或获得文本区域中“选定状态”文本的方法,选定状态的文本一般用高亮或反白显示:select(int start, int end) 根据指定的起止位置选定一段文本;selectAll( ) :选定文本区域中的所有文本;setSelectionStart( ) 和setSelectionEnd( ) 分别指定选
43、定文本的起、止位置;getSelectionStart( ) 和getSelectionEnd( ):获得已经选定文本的起、止位置;getSelectedText( )获得选定文本的具体内容(字符串)。TextField自己的方法:例如某些场合下(如输入密码时)希望文本区域中的内容不如实回显在屏幕上,可以调用如下的方法:TextField tf = new TextField(输入密码);tf.setEchoChar(*);此时,TextField中的每个字符(无论中西文)都被回显成一个星号*,保证看不到其中的实际字符。另外,TextField还定义了echoCharIsSet( ) 确认当前
44、文本框是否处于不回显状态;getEchoChar( ) 获得当前文本框不回显的屏蔽字符。除了继承TextComponent类的方法,TextArea定义了两个特殊的方法,如下:append(String s)在当前文本区域已有文本的后面添加字符串参数s指定的文本内容;insert(String s, int index)将字符串s插入到已有文本的指定序号处。(3) 事件响应TextField和TextArea的事件响应首先由它们的父类TextComponent决定。TextComponent的事件响应如下:的事件响应如下:TextComponent可引发一种事件:当用户修改文本区域中的文本,如
45、做文本的添加、删除、修改等操作时,将引发TextEvent对象代表的文本改变事件。在此基础上TextField还比TextArea多产生一种事件,当用户在文本框中按回车时,将引发代表动作事件的ActionEvent事件。TextArea不能产生ActionEvent事件,也没有addActionListener( )方法。若需响应上述两类事件,则需把文本框加入实现了TextListener接口的文本改变事件监听者和实现了ActionListener接口的动作事件监听者: textField1.addTextListener(this); textField1.addActionListener
46、(this);在监听者内部分别定义响应文本改变事件和动作事件的方法: public void textValueChanged(TextEvent e); public void actionPerformed(ActionEvent e);来响应文本框引发的文本改变事件和动作事件。调用e.getSource( )可获得引发该事件的文本框的对象引用。调用该文本框的方法,可获得改变后的文本内容:String afterChange = (TextField)e.getSource( ).getText( );对于动作事件,同样可通过调用e.getSource( )方法获得用户输入回车的那个文本框
47、的对象引用。import java.applet.*;import java.awt.*;import java.awt.event.*;public class UsedTextComponentEvent extends Applet implements TextListener,ActionListener TextField tf; TextArea ta; public void init( ) tf = new TextField(45); ta = new TextArea(10,45); add(tf); add(ta); tf.addActionListener(this)
48、; tf.addTextListener(this); public void textValueChanged(TextEvent e) if(e.getSource( )=tf) ta.setText(TextField)e.getSource( ).getText( ); public void actionPerformed(ActionEvent e) if(e.getSource( )=tf) ta.setText(); 例 7-7 UsedTextComponentEvent.java7.7 单、复选按钮,列表与选择事件 1. 选择事件(ItemEvent)ItemEvent类只
49、包含代表选择项的选中状态发生变化的事件ITEM-STATE-CHANGED。引发这类事件的动作包括:(1) 改变列表类List对象选项的选中或不选中状态。(2) 改变下拉列表类Choice对象选项的选中或不选中。(3) 改变复选按钮类Checkbox对象的选中或不选中状态。(4) 改变检测盒菜单项CheckboxMenuItem对象的选中或不选中状态。ItmeEvent类的主要方法:(1) public ItemSelectable getItemSelectable( )返回引发选中状态变化事件的事件源,例如,选项变化的List对象或选中状态变化的Checkbox对象,这些能引发选中状态变化
50、事件的都是实现了ItemSelectable接口的类的对象,包括List对象、Choice对象、Checkbox对象等。getItemSelectable( )返回这些类的对象引用。(2) public Object getItem( )返回引发选中状态变化事件的具体选择项,如选中Choice的具体item,通过调用这个方法可知用户选中了哪个选项。(3) public int getStateChange( )返回具体的选中状态变化类型,它的返回值在ItemEvent类的几个静态常量列举的集合之内: ItemEvent.SELECTED: 代表选项被选中。 ItemEvent.DESELECT
51、ED:代表选项被放弃不选。2. 复选按钮(Checkbox)(1) 创建复选按钮也叫检测盒,用Checkbox类的对象表示。创建复选按钮对象时可指明其文本说明标签,该文本标签简要地说明了检测盒的意义和作用。Checkbox backg = new Checkbox(背景色);(2) 常用方法每个复选按钮都两种状态:被选中的check状态,未被选中的uncheck状态,复选按钮都只处于这两种状态之一。查看点击选择了复选按钮,可调用Checkbox的方法getState( )。若被选中,则返回true,否则返回false。调用Checkbox的另一个方法setState( )可以用程序设置是否选中
52、复选按钮。下面的语句使Checkbox处于选中状态。 backg.setState( true ); (3) 事件响应当用户点击检测盒使其选中状态发生变化时会引发ItemEvent类代表的选择事件。下面的语句: backg.addItemListener(this);把backg注册给ItemEvent事件的监听者ItemListener。则系统自动调用ItemListener中的方法:public void itemStateChanged(ItemEvent e) ;来响应复选按钮的状态改变。凡是实现了ItemListener接口的监听者,例如包容复选按钮的容器,需要具体实现此方法。此方法
53、的方法体通常包括如下语句:e.getItemSelectable( ):获得引发选择事件的事件源对象引用e.getState( )获取选择事件之后的状态。注意:getItemSelectable( )方法的返回值是实现了Selectable接口的对象,需将它强制转化成真正的事件源对象类型。例如:(Checkbox)e.getItemSelectable( ).getState( );(Checkbox)e.getItemSelectable( ).setState(false); 例 7-8 UsedTestCheckbox.javaimport java.applet.*;import ja
54、va.awt.*;import java.awt.event.*;public class UsedTestCheckbox extends Applet implements ItemListener Checkbox ckb; Button btn; public void init( ) ckb = new Checkbox(背景色); btn = new Button(效果); add(ckb); add(btn); ckb.addItemListener(this); public void itemStateChanged(ItemEvent e) Checkbox temp; i
55、f(e.getItemSelectable( ) instanceof Checkbox) temp = (Checkbox)(e.getItemSelectable( ); if(temp.getLabel( )=背景色) if(temp.getState( ) btn.setBackground(Color.cyan); else btn.setBackground(Color.gray); 3. 单选按钮组(CheckboxGroup)(1) 创建Checkbox提供“二选一”的机制。若实现“多选一”,可用单选按钮组。单选按钮组是一组Checkbox的集合,用CheckboxGroup类
56、的对象表示。每个Checkbox对应一种可能的取值情况。例:如下创建的单选按钮组代表了三种字体风格。style = new CheckboxGroup( );p = new Checkbox(普通,true,style);b = new Checkbox(黑体,false,style);i = new Checkbox(斜体,false,style); 把CheckboxGroup加入容器时需把每个单选按钮逐个加入到容器中,而不能使用CheckboxGroup对象一次性地加入。加入上面的单选按钮需引用如下的语句: add(p); add(b); add(i); (2) 常用方法单选按钮的选择是
57、互斥的。调用CheckboxGroup的getSelectedCheckbox( ) :获取选择了哪个按钮,并返回用户选中的Checkbox对象,再调用该对象的方法getLabel( ) 可知用户选择了什么信息。CheckboxGroup的setSelectedCheckbox( ) 用于指定单选按钮组中的某个按钮。例如,下面的语句说明字体的风格为斜体。 sex.setSelectedCheckbox( i );另外,也可直接使用按钮组中的Checkbox单选按钮的方法。直接调用 i.getState( ); 可知这个按钮是否被选中。如果该按钮被选中,则其他按钮一定处于未选中状态。单选按钮组中
58、可包括两个或更多的单选按钮。(3) 事件响应CheckboxGroup类不是java.awt.*包中的类,它是Object的直接子类,所以按钮组不能响应事件,但按钮组中的每个按钮可以响应ItemEvent类的事件。单选按钮组中的每个单选按钮都是Checkbox对象,它们对事件的响应与检测盒对事件的响应相同。 例 7-9 UsedCheckboxgroup.javaimport java.applet.*;import java.awt.*;import java.awt.event.*;public class UsedCheckboxgroup extends Applet implemen
59、ts ItemListener CheckboxGroup style; Checkbox p,b,i; Button btn; public void init( ) style = new CheckboxGroup( ); p = new Checkbox(普通,true,style); b = new Checkbox(黑体,false,style); i = new Checkbox(斜体,false,style); btn = new Button(效果); add(p); add(b); add(i); add(btn); p.addItemListener(this); b.a
60、ddItemListener(this); i.addItemListener(this); public void itemStateChanged(ItemEvent e) Checkbox temp; Font oldF = btn.getFont( ); if(e.getItemSelectable( ) instanceof Checkbox) temp = (Checkbox)(e.getItemSelectable( ); if(temp.getLabel( )=普通) btn.setFont(new Font(oldF.getName( ),Font.PLAIN,oldF.ge
61、tSize( ); if(temp.getLabel( )=黑体) btn.setFont(new Font(oldF.getName( ),Font.BOLD,oldF.getSize( ); if(temp.getLabel( )=斜体) btn.setFont(new Font(oldF.getName( ),Font.ITALIC,oldF.getSize( ); 4. Choice(下拉列表)(1) 创建下拉列表是“多选一”的输入界面。与单选按钮组利用单选按钮把所有选项列出的方法不同,下拉列表的所有选项被折叠收藏起来,只显示最前面的或被用户选中的一个。若需看到其他的选项,则需单击下拉
62、列表右边的下三角按钮来“下拉”出罗列了所有选项的长方形区域。创建下拉列表包括创建和添加选项两个步骤。 Choice size = new Choice( ); /创建下拉列表 size.add(10); /为下拉列表加入选项 size.add(14); size.add(18); (2) 常用方法下拉列表的常用方法有:获得选中选项、设置选中选项、添加和去除下拉列表选项的方法。getSelectedIndex( ) 返回被选中的选项的序号(下拉列表中第一个选项的序号为0,第二个选项的序号为1,)。getSelectedItem( ) 返回被选中选项的标签文本字符串。select(int inde
63、x) 和select(String item)方法使程序选中指定序号或文本内容的选项。add(String item) 和insert(String item, int index)方法分别将新选项item加在当前下拉列表的最后或指定的序号处。 remove(int index) 和remove(String item)方法把指定序号或指定标签文本的选项从下拉列表中删除。removeAll( )方法将把下拉列表中的所有选项删除。(3) 事件响应下拉列表可产生ItemEvent代表的选择事件。如果把选项注册给实现了接口ItemListener的监听者:size.addItemListener(
64、);则当用户单击下拉列表的某个选项做出选择时,系统自动产生一个ItemEvent类的对象包含这个事件的有关信息,并把该对象作为实际参数传递给被自动调用的监听者的选择事件响应方法。public void itemStateChanged(ItemEvent e); 在这个方法里,调用e.getItemSelectable( )可获得引发当前选择事件的下拉列表事件源,再调用此下拉列表的有关方法,可知用户具体选择了哪个选项。String selectedItem = (Choice)e.getItemSelectable( ).getSelectedItem( );这里需将e.getItemSele
65、ctable( )方法的返回值强制类型转换成Choice类的对象引用后方可调用Choice类的方法。UsedChoice.javaimport java.applet.*;import java.awt.*;import java.awt.event.*;public class UsedChoice extends Applet implements ItemListener Choice size; Button btn; public void init( ) size = new Choice( ); size.add(10); size.add(14); size.add(18);
66、add(size); btn = new Button(效果); add(btn); size.addItemListener(this); public void itemStateChanged(ItemEvent e) Choice temp; Font oldF; String s; int si; if(e.getItemSelectable( ) instanceof Choice) oldF = btn.getFont( ); temp = (Choice)(e.getItemSelectable( ); s = temp.getSelectedItem( ); si = Int
67、eger.parseInt(s); btn.setFont(new Font(oldF.getName( ),oldF.getStyle( ),si); 5. List(列表)(1) 创建列表也是列出一系列的选择项供用户选择,但是列表可以实现“多选多”,即允许复选。在创建列表时,也应将它的各选项(Item)加入到列表中,语句如下:MyList = new List(4,true);MyList.add(北京);MyList.add(上海); 创建一个包括两个地址选项的列表,List的构造函数的第一个参数说明列表的高度,可以一次同时显示几个选项,第二个参数表明列表是否允许复选。(2) 常用方法若
68、想获知选择了列表的哪个选项,可调用List对象的getSelectedItem( ),该方法返回选中的选择项文本。与单选按钮不同,列表中可以有复选和多选,故List对象还有一个方法getSelectedItems( ) ,该方法返回String类型的数组,其中的每个元素是一个被用户选中的选择项,所有的元素包括了所有被用户选中的选项。除了可直接返回被选中的选项的标签字符串外,还可获得被选中选项的序号。在List里面,第一个加入List的选项的序号是0,第二个是1,依此类推。getSelectedIndex( )方法将返回被选中的选项的序号,getSelectedIndexs( )方法将返回由所有
69、被选中的选项的序号组成的整型数组。select(int index)和deselect(int index)方法可以使指定序号处的选项被选中或不选中;add(String item)方法和add(String item, int index)方法分别将标签为item的选项加入列表的最后面或加入列表的指定序号处;remove(String item)方法和remove(int index)方法与之相反,将拥有指定标签的选项或指定序号处的选项从列表中移出。这两个方法使程序可以动态调整列表所包含的选择项。(3) 事件响应列表可产生两种事件:单击列表中的某个选项并选中它时,产生ItemEvent类的选
70、择事件;双击列表中的某个选项时,产生ActionEvent类的动作事件。若需对这两种事件都做出响应,需要把列表分别注册给ItemEvent的监听者ItemListener和ActionEvent的监听者ActionListener。MyList.addItemListener(this);MyList.addActionListener(this); 并在实现了监听者接口的类中分别定义响应选择事件的方法和响应动作事件的方法。public void itemStateChanged(ItemEvent e); /响应单击的选择事件public void actionPerformed(Actio
71、nEvent e); /响应双击的动作事件这样,当列表上发生了单击或双击动作时,系统就自动调用上述两个方法来处理相应的选择或动作事件。通常在itemStateChanged(ItemEvent e)方法中,会调用e.getItemSelectable( )来获得产生该选择事件的列表(List)对象的引用,再利用列表对象的方法getSelectedIndex( )或getSelectedItem( )就知选择了列表的哪个选项。与Checkbox的使用方法类似,e.getItemSelectable( )的返回值需先强制类型转化成List对象,然后再调用List类的方法。例如:String s =
72、 (List)e.getItemSelectable( ). getSelectedItem( );但在actionPerformed(ActionEvent e)方法里,调用e.getSource( )可得到产生此动作事件的List对象引用,同样要使用强制类型转换。(List)e.getSource( );调用e.getActionCommand( )可以获得事件的选项的字符串标签,在列表单选时,相当于执行(List)e.getSource( ).getSelectedItem( );注意:列表的双击事件不能覆盖单击事件。当双击一个列表选项时,首先产生一个单击的选项事件,然后再产生一个双击的
73、动作事件。如果定义并注册了两种事件的监听者,itemStateChanged( )方法和actionPerformed( )方法将分别被先后调用。UsedList.javaimport java.applet.*;import java.awt.*;import java.awt.event.*;public class UsedList extends Applet implements ActionListener,ItemListener List MyList; Label result; public void init( ) result = new Label(您双击了选项);
74、MyList = new List(4,true); MyList.add(北京); MyList.add(上海); MyList.add(南京); MyList.add(西安); MyList.add(重庆); MyList.add(深圳); add(MyList); add(result); MyList.addActionListener(this); MyList.addItemListener(this); public void actionPerformed(ActionEvent e) if(e.getSource( )=MyList) result.setText(您双击了选
75、项+e.getActionCommand( ); public void itemStateChanged(ItemEvent e) List temp; String sList; String mgr = new String(); if(e.getItemSelectable( ) instanceof List) temp = (List)(e.getItemSelectable( ); sList = temp.getSelectedItems( ); for(int i=0;isList.length;i+) mgr = mgr + sListi + ; showStatus(mg
76、r); 7.8 滚动条与调整事件 1. 调整事件(AdjustmentEvent)AdjustmentEvent类只包含一个事件ADJUSTMENT-VALUE-CHANGED事件。与ItemEvent事件引发的离散状态变化不同,ADJUSTMENT-VALUE-CHANGED是GUI组件状态发生连续变化的事件,引发这类事件的具体动作有:(1) 操纵滚动条(Scrollbar)改变其滑块位置。(2) 操纵用户自定义的Scrollbar对象的子类组件,改变其滑块位置。AdjustmentEvent类的主要方法有:类的主要方法有:(1)public Adjustable getAdjustable
77、( )(2) public int getAdjustmentType( )(3) public int getValue( )AdjustmentEvent 与ScrollBar均有方法getValue(),作用相同(1) public Adjustable getAdjustable( ):返回引发状态变化事件的事件源,能够引发状态变化事件的事件源都是实现了Adjustable接口的类。例如,Scrollbar类就是实现了Adjustable接口的类。Adjustable接口是java.awt包中定义的一个接口,一个方法的返回值类型被标志为一个接口,代表这个方法将返回一个实现了这个接口的类
78、的对象。例如,调用getAdjustable( )方法将返回引发这个事件的Scrollbar对象的引用。(2) public int getAdjustmentType( )返回状态变化事件的状态变化类型,其返回值在AdjustmentEvent类的几个静态常量所列举的集合之内。AdjustmentEvent.BLOCK-DECREMENT: 代表点击滚动条下方引发块状下移的动作。AdjustmentEvent.BLOCK-INCREMENT: 代表点击滚动条上方引发块状上移的动作。AdjustmentEvent.TRACK:代表拖动滚动条滑块的动作。AdjustmentEvent.UNIT-
79、DECREMENT: 代表点击滚动条下三角按钮引发最小单位下移的动作。AdjustmentEvent.UNIT-INCREMENT: 代表点击滚动条上三角按钮引发最小单位上移的动作。通过调用getAdjustmentType( )方法并比较其返回值,就可以得知用户发出的哪种操作引发了哪种连续的状态变动。(3) public int getValue( )调用getValue( )方法可以返回状态变化后的滑块对应的当前数值。滑块是可以连续调整的,调整将引发AdjustmentEvent事件,getValue( )方法可以返回调整后滑块对应的最新数值。 2. 滚动条(Scrollbar)(1) 创
80、建滚动条是一种比较特殊的GUI组件,它能够接受并体现连续的变化,称为“调整”。创建Scrollbar类的对象将创建一个含有滚动槽、增加箭头、减少箭头和滑块(也称为气泡)的滚动条。滚动条的各组成部分 Scrollbar mySlider = new Scrollbar(Scrollbar.HORIZONTAL,50,1,0,100);第一个参数:新滚动条的方向,使用常量Scrollbar.HORIZONTAL将创建横向滚动条,使用常量Scrollbar.VERTICAL将创建纵向滚动条。第二个参数:滑块初显位置,是一个整型量。第三个参数:滑块的大小,对滑块滚动同时引起文本区域滚动的情况,滑块大小
81、与整个滚动槽长度的比例应与窗口中可视的文本区域与整个文本区域的比例相当,对于滑块滚动不引起文本区域滚动的情况,可把滑块大小设为1。第四个参数:滚动槽代表的最小数据。第五个参数:滚动槽代表的最大数据。(2) 常用方法对于新创建的滚动条,设置它的单位增量和块增量需要调用如下的方法:mySlider.setUnitIncrement(1);mySlider.setBlockIncrement(50); setUnitIncrement(int):指定滚动条的单位增量,单击滚动条两端的三角按钮时代表的数据改变;setBlockIncrement(int):滚动条的块增量,即用户单击滚动槽时代表的数据改
82、变。getUnitIncrement( ) 和getBlockIncrement( ):分别获取滚动条的单位增量和块增量。getValue( ):返回当前滑块位置代表的整数值,当滚动条改变滑块在滚动槽中的位置时,getValue( )方法的返回值将相应随之改变。(3) 事件响应滚动条可以引发AdjustmentEvent类代表的调整事件,当用户通过各种方式改变滑块位置从而改变其代表的数值时,都会引发调整事件。程序要响应滚动条引发的调整事件,必须首先把这个滚动条注册给实现了AdjustmentListener接口的调整事件监听者。mySlider.addAdjustmentListener(th
83、is);调整事件监听者中用于响应调整事件的方法是: public void adjustmentValueChanged(AdjustmentEvent e); 该方法需调用e.getAdjustable( )来获得引发当前调整事件的事件源,如滚动条。另一个方法是AdjustmentEvent类的方法getValue( ),它与滚动条的getValue( )方法功能相同,e.getValue( ):返回调整事件后的数值。调用e.getAdjustmentType( ) 可知当前调整事件的类型,即用户使用何种方式改变了滚动条滑块的位置。具体方法是把这个方法的返回值与AdjustmentEvent
84、类的几个静态常量相比较。 AdjustmentEvent.BLOCK-INCREMENT:块增加。AdjustmentEvent.BLOCK-DECREMENT:块减少。AdjustmentEvent.UNIT-INCREMENT:单位增加。AdjustmentEvent.UNIT-DECREMENT:单位减少。AdjustmentEvent.TRACK:用鼠标拖动滑块移动。 import java.applet.*;import java.awt.*;import java.awt.event.*;public class UsedSlider extends Applet implemen
85、ts AdjustmentListener Scrollbar mySlider; TextField sliderValue; public void init( ) setLayout(new BorderLayout( ); mySlider = new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,Integer.MAX_VALUE); mySlider.setUnitIncrement(1); mySlider.setBlockIncrement(50); add(South,mySlider); 创建并使用滚动条TestSlider.javamySlid
86、er.addAdjustmentListener(this); sliderValue = new TextField(30); add(Center,sliderValue); public void adjustmentValueChanged(AdjustmentEvent e) int value; if(e.getAdjustable( ) = mySlider) value = e.getValue( ); sliderValue.setText(new Integer(int)value).toString( ); sliderValue.setBackground(new Co
87、lor(value); 7.9 画布与鼠标、键盘事件 1. 鼠标事件(MouseEvent)MouseEvent类和KeyEvent类都是InputEvent类的子类,InputEvent类不包含任何具体的事件,但是调用InputEvent类的getModifiers( )方法,并把返回值与InputEvent类的几个静态整型常量ALT-MASK,CTRL-MASK,SHIFT-MASK,META-MASK,BUTTON1-MASK,BUTTON2-MASK,BUTTON3-MASK相比较,就可知用户在引发KeyEvent事件时是否同时按下了功能键,或者用户在单击鼠标时单击的是哪个鼠标键。 M
88、ouseEvent类包含七个鼠标事件,分别用MouseEvent类的同名静态整型常量标志。(1) MOUSE-CLICKED:代表鼠标点击事件。(2) MOUSE-DRAGGED:代表鼠标拖动事件。(3) MOUSE-ENTERED:代表鼠标进入事件。(4) MOUSE-EXITED:代表鼠标离开事件。(5) MOUSE-MOVED:代表鼠标移动事件。(6) MOUSE-PRESSED:代表鼠标按钮按下事件。(7) MOUSE-RELEASED:代表鼠标按钮松开事件。调用MouseEvent对象的getID( ) 并把返回值与上述各常量比较,就可知用户引发的是哪个具体的鼠标事件。例如假设mou
89、seEvt是MouseEvent类的对象,下面的语句将判断它代表的事件是否是MOUSE-CLICKED:if ( mouseEvt . getID( ) = MouseEvent. MOUSE-CLICKED )但一般不这样处理,因为监听MouseEvent事件的监听者MouseListener和MouseMotionListener中有七个具体方法,分别针对上述的七个具体鼠标事件,系统会分辨鼠标事件的类型并自动调用相关的方法,所以只需把处理相关事件的代码放到相关的方法里即可。MouseEvent类有如下主要方法,(1) public int getX( ): 返回发生鼠标事件的X坐标。(2)
90、 public int getY( ): 返回发生鼠标事件的Y坐标。(3) public Point getPoint( ): 返回Point对象,包含鼠标事件发生的坐标点。(4) public int getClickCount( ): 返回鼠标点击事件的点击次数。MouseListener和MouseMotionListener的事件处理方法,都以MouseEvent类的对象为形参。通过调用MouseEvent类的上述方法,这些事件处理方法可以得到引发它们的鼠标事件的具体信息。例 7-13 ResponseToMouse.javaimport java.applet.*;import ja
91、va.awt.*;import java.awt.event.*;public class ResponseToMouse extends Applet implements MouseListener, MouseMotionListener public void init( ) this.addMouseListener(this); this.addMouseMotionListener(this); public void mouseClicked(MouseEvent e) if(e.getClickCount( )=1) showStatus(您在(+e.getX( )+,+e.
92、getY( )+)单击了鼠标。); else if(e.getClickCount( )=2) showStatus(您在(+e.getX( )+,+e.getY( )+)双击了鼠标。); public void mouseEntered(MouseEvent e) showStatus(鼠标进入Applet。); public void mouseExited(MouseEvent e) showStatus(鼠标离开Applet。); public void mousePressed(MouseEvent e) showStatus(您按下了鼠标。); public void mouseR
93、eleased(MouseEvent e) showStatus(您松开了鼠标。); public void mouseMoved(MouseEvent e) showStatus(您移动了鼠标,新位置在(+e.getX( )+,+e.getY( )+)。); public void mouseDragged(MouseEvent e) showStatus(您拖动了鼠标。); MouseListener: public void mouseClicked(MouseEvent e); public void mousePressed(MouseEvent e); public void mo
94、useReleased(MouseEvent e); public void mouseEntered(MouseEvent e); public void mouseExited(MouseEvent e);MouseMotionListener: public void mouseDragged(MouseEvent e); public void mouseMoved(MouseEvent e);2. 键盘事件键盘事件(KeyEvent)KeyEvent类包含三个键盘事件,分别对应KeyEvent类的几个同名的静态整型常量。KEY-PRESSED: 键盘按键被按下。KEY-RELEASE
95、D: 键盘按键被放开。KEY-TYPED: 按键被敲击。KeyEvent类的主要方法:public char getKeyChar( ):返回引发键盘事件的按键对应的Unicode字符。如果该按键没有Unicode字符与之相对应,则返回KeyEvent类的一个静态常量KeyEvent.CHAR-UNDEFINED。与KeyEvent事件相对应的监听者接口是KeyListener,这个接口中定义了三个抽象方法,分别与KeyEvent中的三个具体事件类型相对应:(1) public void keyPressed(KeyEvent e);(2) public void keyReleased(Ke
96、yEvent e);(3) public void keyTyped(KeyEvent e);事件类中的事件类型名与对应的监听者接口中的抽象方法名很相似,也体现了二者之间的响应关系。凡实现了KeyListener接口的类,都必须具体实现上述的三个抽象方法,把用户程序对这三种具体事件的响应代码放在实现后的方法体中,这些代码里通常需要用到实参KeyEvent对象e的若干信息,这可以通过调用e的方法,如getSource( ),getKeyChar( )等来实现。例如,下面的语句将判断用户键入了y还是n,代表肯定或否定的回答。 public void keyPressed(KeyEvent e)ch
97、ar ch = e.getKeyChar( );if(ch = y | ch = Y) m-result.setText(同意);else if(ch = n | ch = N) m-result.setText(反对);else m-result.setText(非法输入);其中m-result是一个用来输出信息的Label对象。3. 画布(Canvas)画布是用来画图的矩形背景组件,在画布里可以像在Applet里那样绘制各种图形,也可以响应鼠标和键盘事件。(1) 创建Canvas的构造函数没有参数,例如Canvas myCanvas = new Canvas( );在创建了Canvas对象
98、之后,还需调用setSize( )方法确定画布对象的大小,否则用户在运行界面中将看不到这个画布。 (2) 常用方法Canvas常用方法:只有一个public void paint(Graphics g),用户程序重载这个方法就可以实现在Canvas上面绘制有关图形。(3) 产生事件Canvas对象与Applet相似,可以引发键盘和鼠标事件。例 7-14 TestCanvas.java 7.10 布局设计 在前面的例子中,基本组件仅仅被简单地加入容器。如果程序需要进一步考虑如何设计和控制这些组件在容器中的位置和相互关系,就需要学习布局设计的知识。在Java的GUI界面设计中,布局控制是通过为容器
99、设置布局编辑器来实现的。java.awt包中共定义了五种布局编辑类,每个布局编辑类对应一种布局策略,分别是FlowLayout,BorderLayout,CardLayout,GridLayout和GridBagLayout。当一个容器选定一种布局策略时,它应该创建该策略对应的布局编辑类的对象,并将此对象设置为自己的布局编辑器。没有设置布局编辑器的容器,其中的对象会互相覆盖、遮挡,影响使用,所以必须为每个容器设置一个合适的布局编辑器。下面讨论这几种布局编辑策略。7.10.1 FlowLayout FlowLayout是容器Panel和它的子类Applet缺省使用的布局编辑策略,如果不专门为Pa
100、nel或Applet指定布局编辑器,则它们就使用FlowLayout的布局策略。FlowLayout对应的布局策略简单。遵循这种策略的容器将其中的组件按照加入的先后顺序从左向右排列,一行排满之后就下转到下一行继续从左至右排列,每一行中的组件都居中排列;在组件不多时,使用这种策略非常方便,但是当容器内的GUI元素增加时,就显得高低参差不齐。对于使用FlowLayout的容器,加入组件使用命令:add(组件名);这些组件将顺序地排列在容器中,有时由于FlowLayout的布局能力有限,程序会采用容器嵌套的方法,即把一个容器当作一个组件加入另一个容器,这个容器组件可以有自己的组件和自己的布局策略,使
101、整个容器的布局达到应用的需求。对于一个原本不使用FlowLayout布局编辑器的容器,若需要将其布局策略改为FlowLayout,可使用:setLayout(new FlowLayout( );setLayout( )方法是所有容器的父类Container的方法,用于为容器设定布局编辑器。创建FlowLayout类的对象可以使用上面语句中的无参数构造函数,也可以使用下面的两种构造函数:(1) FlowLayout(int align, int hgap, int vgap)Align:指定每行组件的对齐方式(取三个静态常量LEFT,CENTER,RIGHT之一)hgap和vgap:分别指定各组
102、件间的横向和纵向间的以像素为单位的间距。(2) FlowLayout(int align)参数align指定每行组件的对齐方法,组件间的横纵间距都固定为五个像素;无参数的构造函数创建的FlowLayout对象,其对齐方式为CENTER常量指定的居中方式,组件间的横纵间距都为五个像素。7.10.2 BorderLayout BorderLayout把容器内的空间简单地划分为东、西、南、北、中五个区域,每加入一个组件需指明把这个组件加在哪个区域中。分布在北部和南部区域的组件将横向扩展至占据整个容器的长度,分布在东部和西部的组件将伸展至占据容器剩余部分的全部宽度,最后剩余的部分将分配给位于中央的组件
103、。如果某个区域没有分配组件,则其他组件可以占据它的空间。例如,如果北部没有分配组件,则西部和东部的组件将向上扩展到容器的最上方,如果西部和东部没有分配组件,则位于中央的组件将横向扩展到容器的左右边界。BorderLayout布局策略使用无参数构造函数创建的BorderLayout规定各组件间的横、纵间距都为0。如果希望使用大于0的间距,则可以使用BorderLayout的另一个构造函数创建它 。BorderLayout(int hgap, int vgap);BorderLayout只能指定五个区域位置。如果容器中需要加入超过五个组件,必须使用容器的嵌套或改用其他的布局策略。例7-15中的Ap
104、plet使用了BorderLayout并分配了五个组件。import java.applet.*;import java.awt.*;import java.awt.event.*;public class TestBorderLayout extends Applet Button north,south,west,east,center; public void init( ) setLayout(new BorderLayout( );/设置 BorderLayout布局编辑器 north = new Button(North); south = new Button(South); w
105、est = new Button(West); east = new Button(East); center = new Button(Center); add(East,east);/加入组件时分配区域 add(Center,center); add(North,north); add(South,south); add(West,west); 7.10.3 CardLayout 使用CardLayout的容器表面上可以容纳多个组件,但在同一时刻容器只能从这些组件中选出一个来显示,并且被显示的组件将占据所有的容器空间。使用CardLayout的一般步骤如下(4步):(1) 创建CardLa
106、yout对象作为布局编辑器:Mycard = new CardLayout( );(2) 使用容器的setLayout( )方法为容器设置布局编辑器:setLayout(Mycard); (3) 调用容器的方法add( )将组件加入容器,同时为组件分配一个字符串名字,以便布局编辑器根据这个名字调用显示这个组件。add (字符串,组件);(4) 调用CardLayout的方法show( ),根据字符串名字显示一个组件:show(容器名,字符串);或按组件加入容器的顺序显示组件,如first(容器名) 显示第一个组件,last(容器名) 显示最后一个组件等。使用CardLayout的布局策略的示例
107、如下: import java.applet.*; import java.awt.*; import java.awt.event.*; public class TestCardLayout extends Applet CardLayout MyCard = new CardLayout( );/创建CardLayout布局编辑器对象 Button btn1 = new Button(第一页); Button btn2 = new Button(第二页); Button btn3 = new Button(第三页); Button btn4 = new Button(第四页); Butt
108、on btn5 = new Button(第五页); public void init( ) setLayout(MyCard);/设置容器的布局策略为CardLayout add(第一页,btn1);/加入组件并指定名字 add(第二页,btn2); add(第三页,btn3); add(第四页,btn4); add(第五页,btn5); btn1.addMouseListener(new MouseMoveCard(MyCard,this); btn2.addMouseListener(new MouseMoveCard(MyCard,this); btn3.addMouseListene
109、r(new MouseMoveCard(MyCard,this); btn4.addMouseListener(new MouseMoveCard(MyCard,this); btn5.addMouseListener(new MouseMoveCard(MyCard,this); class MouseMoveCard extends MouseAdapterCardLayout cl;Applet m_Parent;MouseMoveCard(CardLayout c,Applet a)cl = c;m_Parent = a; public void mouseClicked(MouseE
110、vent e)if(e.getModifiers( )=InputEvent.BUTTON1_MASK)cl.next(m_Parent);elsecl.previous(m_Parent); 运行结果7.10.4 GridLayout GridLayout是使用较多的布局编辑器,它把容器的空间划分成若干行乘若干列的网格区域,组件就位于这些划分出来的小格中。GridLayout比较灵活,划分多少网格由程序自由控制,而且组件定位也比较精确。使用GridLayout布局编辑器的一般步骤如下:(1) 创建GridLayout对象作为布局编辑器。指定划分网格的行数和列数,并使用容器的setLayout
111、( )方法为容器设置这个布局编辑器:setLayout(new GridLayout(行数, 列数)。 (2) 调用容器的方法add( )将组件加入容器。组件填入容器的顺序将按照第一行第一个、第一行第二个第一行最后一个、第二行第一个最后一行最后一个进行。每个网格中都必须填入组件,如果希望某个网格为空白,可以为它加入一个空的标签:add (new Label( )。import java.applet.*; import java.awt.*; import java.awt.event.*; public class TestGridLayout extends Applet public v
112、oid init( ) setLayout(new GridLayout(5,6);/GridLayout布局策略5行6列30网格 for(int i=0;i5;i+) for(int j=0;j=50) add(new Button(Integer.toString(i*6+j);/随机加入按钮 else add(new Label( ); /随机加入空白 运行结果7.11 Panel与容器事件 从本节开始详细讨论GUI各种容器及其使用方法。1. Container类抽象类Container中包含了所有容器组件都必须具有的方法和功能。(1) add( ): Container类中有多个经过重
113、载的add( )方法,其作用都是把Component组件(基本组件或容器组件)加入到当前容器中。每个被加入容器的组件根据加入的先后顺序获取一个序号。(2) getComponent(int index)与getComponent(int x,int y): 分别获得指定序号或指定(x,y)坐标点处的组件。(3) remove(Component)与remove(int index): 将指定的组件或指定序号的组件从容器中移出。(4) removeAll( ): 将容器中所有的组件移出。(5) setLayout( ): 设置容器的布局编辑器。Container可以引发ContainerEven
114、t类代表的容器事件。当容器中加入或移出一个组件时,容器将分别引发COMPONENT-ADDED和COMPONENT-REMOVED两种容器事件。希望响应容器事件的程序需要实现容器事件的监听者接口ContainerListener,并在监听者内部具体实现该接口中用来处理容器事件的两个方法。 public void componentAdded(ContainerEvent e);/响应向容器中加入组件事件的方法public void componentRemoved(ContainerEvent e);/响应从容器中移出组件的方法 在这两个方法内部,可以调用实际参数e的方法e.getContai
115、ner( )获得引发事件的容器对象的引用,其返回类型为Container;也可以调用e.getChild( )方法获得事件发生时被加入或移出容器的组件,这个方法的返回类型为Component。2. 容器事件(ContainerEvent)ContainerEvent类包含两个事件:(1) COMPONENT-ADDED: 把组件加入当前容器对象。(2) COMPONENT-REMOVED: 把组件移出当前容器对象。ContainerEvent类的主要方法有:(1) public Container getContainer( ): 返回引发容器事件的容器对象。(2) public Compon
116、ent getChild( ): 返回引发容器事件时被加入或移出的组件对象。3. PanelPanel属于无边框容器。无边框容器包括Panel和Applet,其中Panel是Container的子类,Applet是Panel的子类。 uPanel是最简单的容器,它没有边框或其他的可见的边界,不能被移动、放大、缩小或关闭。u程序不能使用Panel作为它的最外层的图形界面的容器,一般来说,Panel总是作为一个容器组件被加入到其他的容器,如Frame,Applet等中去。Panel也可以进一步包含另一个Panel,使用Panel的程序中总是存在着容器的嵌套。使用Panel的目的通常是为了层次化管理
117、图形界面的各个组件,同时使组件在容器中的布局操作更为方便。u程序不能显式地指定Panel的大小,Panel的大小是由其中包含的所有组件,以及包容它的那个容器的布局策略和该容器中的其他组件决定的。import java.applet.*;import java.awt.*;import java.awt.event.*;public class TestBorderLayout extends Applet Button north,south,west,east,center; public void init( ) Panel p = new Panel(); p.setLayout(new
118、 GridLayout(4,4); for(int i = 0;i16;i+) p.add(new Button(Integer.toString(i+1); setLayout(new BorderLayout( ); north = new Button(North); south = new Button(South); west = new Button(West); east = new Button(East); center = new Button(Center); add(East,east);/加入组件时分配区域 add(Center,p); add(North,north
119、); add(South,south); add(West,west); import java.awt.*;import java.applet.*;import java.awt.event.*;public class TestPanel extends Applet implements ActionListener,ContainerListenerPanel p1,p2,p3;Label prompt1,prompt2,prompt3;Button btn;public void init( ) p1 = new Panel( ); p1.setBackground(Color.g
120、ray); p2 = new Panel( ); p2.setBackground(Color.red); p3 = new Panel( ); p3.setBackground(Color.cyan); prompt1 = new Label(我在第一个Panel里); prompt2 = new Label(我在第二个Panel里); prompt3 = new Label(我在第三个Panel里); btn = new Button(in Panel3); p1.add(prompt1); p2.add(prompt2); p3.add(prompt3); p3.add(btn); p1
121、.add(p3); add(p1); add(p2); btn.addActionListener(this); p1.addContainerListener(this);public void actionPerformed(ActionEvent e) if(e.getSource( )=btn)p1.remove(p3);public void componentRemoved(ContainerEvent e) showStatus(您移去了第三个Panel); public void componentAdded(ContainerEvent e)运行结果容器的嵌套是Java程序G
122、UI界面设计和实现中经常需要使用到的手段,实现这一类GUI界面时,应该首先明确各容器之间的包含嵌套关系。例如,例7-18中的程序GUI存在如下的包含层次关系(图7.20)。多容器图形界面的结构层次关系由于这个程序是一个Java Applet,所以程序最外层的容器是一个Applet,其中包含了两个组件:第一个组件是一个Panel对象p1;第二个组件是另一个Panel对象p2,p1中包含了一个标签prompt1和第三个Panel对象p3;p3中包含一个标签prompt3和一个按钮btn。这里所有的容器都使用缺省的FlowLayout布局策略。当用户单击按钮btn时,程序从p1移去组件p3并引发CO
123、NTAINER-REMOVED事件,程序响应这个事件后在状态条中显示移去组件容器的信息。 Applet是一种特殊的Panel,它是Java Applet程序的最外层容器,但Java Applet不是完整独立的程序,而是WWW浏览器中的一个控件,作为浏览器的一部分依赖于浏览器而存在,所以Applet可以依赖浏览器的窗口来完成放大、缩小、关闭等功能。Applet程序本身只需负责它所拥有的Applet容器中的那部分无边框区域就足够了。Applet容器的缺省布局策略与其父类Panel一致,都是FlowLayout,但是Applet容器中还额外定义了一些用来与浏览器交互的方法,如init( ),star
124、t( ),stop( )等。 7.12 Frame与窗口事件 除了Applet和Panel这组无边框容器,Container还有一组有边框的容器的子类,包括Window,Frame,Dialog和FileDialog。Window是所有有边框容器的父类,但是Window本身并无边框,是有边框容器的特例。这一组里的其他容器都是有边框可独立存在的容器。1. Frame在前面的例子中已经使用过Frame这种容器,它是Java中最重要、最常用的容器之一,是Java Application程序的图形用户界面容器。Frame可以作为一个Application的最外层容器,也可以被其他容器创建并弹出成为独立
125、的容器,但是无论哪种情况,Frame都作为最顶层容器存在,不能被其他容器所包含。 Frame有自己的外边框和自己的标题,创建Frame时可以指定其窗口标题。Frame(String title);也可以使用专门的方法getTitle( )和setTitle(String)来获取或指定Frame的标题。新创建的Frame是不可见的,需用setVisible(boolean) 并使实参为true才可见。每个Frame在其右上角都有三个控制图标(窗口最小化、最大化和关闭)。最小化和最大化操作可由Frame自动完成,而关闭窗口的操作不能通过点击关闭图标实现,需要程序专门书写有关的代码。常用的关闭窗口的
126、方法有三个:一个是设置一个按钮,当用户点击按钮时关闭窗口;第二个方法是对WINDOWS-CLOSING事件做出响应,关闭窗口;第三个方法是使用菜单命令。前一种方法需要专门的按钮,而后一种方法实现WindowListener接口所需的代码较多,无论使用何种方法,都需要用到关闭Frame的dispose( )方法。向Frame窗口中添加和移出组件使用的方法与其他容器相同,也是add( )和remove( ),Frame可以引发WindowEvent类代表的所有七种窗口事件。2. 窗口事件(WindowEvent)WindowEvent类包含如下几个具体窗口事件。(1) WINDOW-ACTIVAT
127、ED:窗口被激活(在屏幕的最前方待命)。(2) WINDOW-DEACTIVATED:窗口失活(其他窗口被激活后原活动窗口失活)。(3) WINDOW-OPENED:窗口被打开。(4) WINDOW-CLOSED:窗口已被关闭(指已关闭后)。(5) WINDOW-CLOSING:窗口正在被关闭(指关闭前,如点击窗口的关闭按钮)。(6) WINDOW-ICONIFIED:窗口最小化成图标。(7) WINDOW-DEICONIFIED:窗口从图标恢复。WindowEvent类的主要方法有:public window getWindow( ):返回引发当前WindowEvent事件的具体窗口,与ge
128、tSource( )方法返回的是相同的事件引用;但是getSource( )的返回类型为Object,而getWindow( )方法的返回值是具体的Window对象。import java.awt.*;import java.awt.event.*;public class TestFrame public static void main(String args) new MyFrame(); class MyFrame extends Frame implements ActionListenerButton btn;MyFrame()super(我的窗口);btn=new Button(
129、关闭);setLayout(new FlowLayout();add(btn);btn.addActionListener(this);this.addWindowListener(new closeWin();setSize(300,200);setVisible(true);public void actionPerformed(ActionEvent e) if(e.getActionCommand()=关闭)dispose();System.exit(0); class closeWin extends WindowAdapterpublic void windowClosing(Wi
130、ndowEvent e)Frame fr = (Frame)(e.getSource();fr.dispose();System.exit(0); 运行结果上述程序定义了三个类,closeWin是窗口事件的剪裁类WindowAdapter的子类,重载了windowClosing( )方法来关闭被用户单击关闭图标按钮的事件源窗口。MyFrame是用户定义的系统类Frame的子类,里面包括一个按钮btn,用户单击这个按钮时将关闭这个MyFrame对象。主类TestFrame的main( )方法里所创建的MyFrame的对象就是这个Application的图形界面窗口。7.13 菜单的定义与使用 F
131、rame是可以拥有菜单的容器,它实现了MenuContainer接口。菜单是重要的GUI组件,每个菜单组件包括一个菜单条MenuBar。每个MenuBar包含若干个菜单项Menu。每个菜单项还包含若干个菜单子项MenuItem。每个菜单子项在用户点击时引发一个动作命令,整个菜单就是一组经层次化组织、管理的命令集合;使用它,用户可以方便地向程序发布指令。菜单分为两大类:菜单条式菜单和弹出式菜单。下面讨论菜单条式菜单的实现与使用。1. 菜单的设计与实现菜单的设计与实现步骤如下:(1) 创建菜单条MenuBar。 m_MenuBar = new MenuBar( ); /创建一个空的菜单条。(2)
132、创建不同的菜单项Menu加入到空菜单条中。 menuEdit = new Menu(编辑); /创建了一个菜单项 m_MenuBar.add(menuEdit); /把菜单项它加入到菜单条中(3) 为每个菜单项创建其所包含的更小的菜单子项MenuItem,并把菜单子项加入到菜单项中去。 mi_Edit_Copy = new MenuItem(复制); menuEdit.add(mi_Edit_Copy); (4) 将整个建成的菜单条加入到某个容器中去。this.setMenuBar(m_MenuBar);注意注意:并非每个容器都可配菜单条式菜单,只有实现了MenuContainer接口的容器才
133、能加入菜单。(5) 上述步骤组建了菜单的结构,包括菜单项及菜单子项。如何定义各个菜单子项所对应的命令和操作?首先将各菜单子项注册给实现了动作事件的监听接口ActionListener的监听者,如,例7_20中的容器。mi_Edit_Copy.addActionListener(this); (6) 为监听者定义actionPerformed(ActionEvent e)方法,在这个方法中调用e.getSource( )或e.getActionCommand( )来判断用户点击的菜单子项,并完成这个子项定义的操作。创建好的菜单条式菜单位于窗口的上方,如下图所示 。 拥有菜单条的Frame窗口2.
134、 使用分隔线若需在菜单子项之间增加一条横向分隔线,以便把菜单子项分成几组。加入分隔线可使用Menu的addSeparator( )方法,但要注意该语句的位置。菜单子项按照加入的先后顺序排列在菜单项中,希望把分隔线加在哪里,就把分隔线语句放在哪里。例如,在“文件”菜单项中用如下的语句加入了一条分隔线。menuFile.addSeparator( ); /加一条横向分隔线 3. 使用菜单子项快捷键除了用鼠标选择菜单子项,还可为每个菜单子项定义键盘快捷键来选择菜单子项。快捷键是一个字母,定义好后按住Ctrl键和这个字母就可以选中对应的菜单子项。为菜单子项定义快捷键有两种方法:(1)在创建菜单子项的时
135、定义快捷键。MenuItem mi_File_Open = new MenuItem(打开,new MenuShortcut(o); (2)为已经存在的菜单子项定义快捷键。mi_File_Exit.setShortcut(new MenuShortcut(x); /单独设置菜单子项的快捷键设置后菜单子项“打开”对应快捷键Ctrl+O,菜单子项“退出”对应Ctrl+X,参见图7.22。 4. 使用二级菜单二级菜单的使用方法很简单,创建一个包含若干菜单子项(MenuItem)的菜单项(Menu),把这个菜单项像菜单子项一样加入到一级菜单项中即可。m_Edit_Paste = new Menu(粘贴
136、); /创建二级菜单项mi_past_All = new MenuItem(全部粘贴);mi_past_Part = new MenuItem(部分粘贴);m_Edit_Paste.add(mi_Paste_Part); /为二级菜单项加入菜单子项m_Edit_Paste.add(mi_Paste_All);menuEdit.add(m_Edit_Paste); /把二级菜单项加入菜单项 二级菜单与检测盒菜单子项5. 使用检测盒菜单子项检测盒菜单子项CheckboxMenuItem与检测盒一样,有“选中”和“未选中”两种状态,每次选择这类菜单子项都使它在这两种状态之间切换,处于“选中”状态的检
137、测盒菜单子项的前面有一个小对号(如图7.23所示),处于“未选中”状态时没有这个小对号。创建检测盒菜单子项并把它加入菜单项的方法:mi_Edit_Cut = new CheckboxMenuItem(剪切);/创建选择菜单子项menuEdit.add(mi_Edit_Cut); 选择检测盒菜单子项引发的事件不是动作事件ActionEvent,而是选择事件ItemEvent,所以需要把检测盒菜单子项注册给ItemListener,并具体实现ItemListener的itemStateChanged(ItemEvent e)事件,与响应检测盒的事件较为相似。 mi_Edit_Cut.addItem
138、Listener(this); 6. 使用弹出式菜单弹出式菜单附着在某一个组件或容器上,一般它是不可见的,只有当用户用鼠标右键点击附着有弹出式菜单的组件时,这个菜单才“弹出”来显示。弹出式菜单也包含若干个菜单子项,创建弹出式菜单并加入菜单子项的操作如下:PopupMenu popM = new PopupMenu( );/创建弹出窗口MenuItem pi_New = new MenuItem( 新建 ); /为弹出窗口创建菜单子项pi_New.addActionListener(this); /使菜单子项响应动作事件popM.add(pi_New); /为弹出菜单加入菜单子项然后把弹出式菜单
139、附着在某个组件或容器上。ta.add(popM); /将弹出窗口加在文本域上用户点击鼠标右键时弹出式菜单不会自动显示出来,还需要一定的程序处理,首先把附着有弹出菜单的组件或容器注册给MouseListener。ta.addMouseListener(new HandleMouse(this);/文本域响应鼠标事件,弹出菜单重载MouseListener的mouseReleased(MouseEvent e)方法,调用弹出式菜单的方法show( )把它自身显示在用户鼠标点击的位置。 public void mouseReleased(MouseEvent e)/鼠标按键松开事件弹出菜单if(e.
140、isPopupTrigger( ) /检查鼠标事件是否由弹出菜单引发m_Parent.popM.show(Component)e.getSource( ),e.getX( ),e.getY( ); /将弹出菜单显示在用户鼠标点击的位置e.getSource( )返回附着有弹出式菜单的组件或容器,弹出式菜单应该显示在这个组件或容器中鼠标点击的位置(由e.getX( )方法和e.getY( )方法确定鼠标点击的坐标位置),如下图所示。 弹出式菜单的显示与使用import java.awt.*;import java.awt.event.*;public class UsedMenu /定义主类 p
141、ublic static void main(String args) MyMenuFrame mf = new MyMenuFrame( ); mf.setSize(new Dimension(300,200); mf.setVisible(true); /使窗口可见 class MyMenuFrame extends Frame implements ActionListener,ItemListener /定义窗口 MenuBar m_MenuBar; Menu menuFile,menuEdit,m_Edit_Paste; MenuItem mi_File_Open,mi_File_C
142、lose,mi_File_Exit,mi_Edit_Copy; MenuItem pi_New,pi_Del,pi_Pro,mi_Paste_All,mi_Paste_Part; CheckboxMenuItem mi_Edit_Cut; PopupMenu popM; TextArea ta; MyMenuFrame( ) /构造函数 super(拥有菜单的窗口); /指定窗口标题 ta = new TextArea(nnnnnnttt没有选择,5,20); ta.addMouseListener(new HandleMouse(this); /文本域响应鼠标事件 add(Center,ta
143、); popM = new PopupMenu( ); /创建弹出窗口 pi_New = new MenuItem( 新建 ); /为弹出窗口创建菜单子项 pi_New.addActionListener(this); /使菜单子项响应动作事件 popM.add(pi_New); /为弹出菜单加入菜单子项 pi_Del = new MenuItem( 删除 ); pi_Del.addActionListener(this); popM.add(pi_Del); pi_Pro = new MenuItem( 属性 ); pi_Pro.addActionListener(this); popM.a
144、dd(pi_Pro); ta.add(popM); /将弹出窗口加在文本域上 m_MenuBar = new MenuBar( );/创建菜单条 menuFile = new Menu(文件); /创建菜单项,创建菜单子项并指定快捷键 mi_File_Open = new MenuItem(打开,new MenuShortcut(o); mi_File_Close = new MenuItem(关闭); mi_File_Exit = new MenuItem(退出); mi_File_Exit.setShortcut(new MenuShortcut(x); /设置菜单子项的快捷键 mi_Fi
145、le_Open.setActionCommand(打开); /再设置命令名 mi_File_Exit.setActionCommand(退出); /以便动作响应程序调用 mi_File_Open.addActionListener(this); /使菜单子项响应动作事件 mi_File_Close.addActionListener(this); mi_File_Exit.addActionListener(this); menuFile.add(mi_File_Open); /把菜单子项加入菜单项 menuFile.add(mi_File_Close); menuFile.addSepara
146、tor( ); /加一条横向分割线 menuFile.add(mi_File_Exit); m_MenuBar.add(menuFile); /把菜单项加入菜单条 menuEdit = new Menu(编辑); mi_Edit_Copy = new MenuItem(复制); mi_Edit_Cut = new CheckboxMenuItem(剪切); /创建选择菜单子项 m_Edit_Paste = new Menu(粘贴);/创建二级菜单项 mi_Paste_All = new MenuItem(全部粘贴); mi_Paste_Part = new MenuItem(部分粘贴); mi
147、_Edit_Copy.addActionListener(this); mi_Edit_Cut.addItemListener(this);/检测盒菜单子项产生选择事件 m_Edit_Paste.add(mi_Paste_Part); /为二级菜单项加入菜单子项 m_Edit_Paste.add(mi_Paste_All); mi_Paste_Part.addActionListener(this); mi_Paste_All.addActionListener(this); menuEdit.add(mi_Edit_Copy); menuEdit.add(mi_Edit_Cut); menu
148、Edit.addSeparator( ); menuEdit.add(m_Edit_Paste); /把二级菜单项加入菜单项 m_MenuBar.add(menuEdit); this.setMenuBar(m_MenuBar); /把菜单条加入整个Frame容器 public void actionPerformed(ActionEvent e) /响应动作事件 if(e.getActionCommand( )=退出)/选择退出菜单则关闭窗口退出程序 dispose( ); System.exit(0); else /否则显示选择的命令名 ta.setText(nnnnnnttt+e.get
149、ActionCommand( ); public void itemStateChanged(ItemEvent e) /响应CheckboxMenuItem单击事件 if(e.getSource( )=mi_Edit_Cut) if(CheckboxMenuItem)e.getSource( ).getState( )/查看是否选中 ta.setText(nnnnnntt t+选择了 /因为无命令名,所以用标签 +(CheckboxMenuItem)e.getSource( ).getLabel( ); else ta.setText(nnnnnntt t+未选择 +(CheckboxMen
150、uItem)e.getSource( ).getLabel( ); class HandleMouse extends MouseAdapter/处理鼠标事件类,继承鼠标事件裁剪类 MyMenuFrame m_Parent;/产生事件的组件所在的窗口容器 HandleMouse(MyMenuFrame mf)/构造函数 m_Parent = mf; public void mouseReleased(MouseEvent e)/鼠标按键松开事件弹出菜单 if(e.isPopupTrigger( ) /检查鼠标事件是否是由弹出菜单引发的 m_Parent.popM.show(Component)
151、e.getSource( ),e.getX( ),e.getY( ); /将弹出菜单显示在用户鼠标点击的位置UsedMenu.java7.14 对话框、组件事件与焦点事件对话框、组件事件与焦点事件1. 组件事件(ComponentEvent)该类是所有低级事件的根类,共有四个具体事件,可以用ComponentEvent类的几个静态常量来表示。(1) ComponentEvent.COMPONENT_HIDDEN:隐藏组件事件(2) ComponentEvent.COMPONENT_SHOWN:显示组件事件(3) ComponentEvent.COMPONENT_MOVED:移动组件事件(4)
152、ComponentEvent.COMPONENT_RESIZED:改变组件大小把getID( )方法的返回值与上述常量相比较,就可知ComponentEvent对象所代表的具体事件。2. 焦点事件(FocusEvent)FocusEvent类包含两个具体事件,分别对应这个类的两个同名静态整型常量。(1) FOCUS_GAINED:获得注意的焦点。(2) FOCUS_LOST:失去注意的焦点。GUI的对象必须首先获得注意的焦点,才能被进一步操作。例如,一个文本输入区域必须首先获得注意的焦点,才能接受用户键入的文字。一个窗口只有先获得了注意的焦点,其中的菜单才能被选中等。获得注意的焦点使对象被调到
153、整个屏幕的最前面并处于待命状态,是缺省操作的目标对象,而失去注意焦点的对象则被调到屏幕的后面并可能被其他对象遮挡。3. 对话框(Dialog)Dialog:有边框、有标题的独立存在的容器,并且不能被其他容器包容;但Dialog不能作为程序的最外层容器,不能包含菜单条。与Window一样,Dialog必须隶属于某个Frame并由这个Frame负责弹出。Dialog通常起到与用户交互的对话框的作用,例如向用户报告消息并要求确认的消息对话框,接受用户输入的一般对话框等。 Dialog的构造函数有四种重载方式,其中最复杂的为:Dialog(Frame parent, String title, boo
154、lean isModal) 第一个参数指明新创建的Dialog对话框所属的Frame窗口,第二个参数指明新建Dialog对话框的标题,第三个参数指明该对话框是否是有模式的。 “有模式” 对话框:打开后用户必须对其做出响应的对话框,否则不能使用程序的其他部分的,带有一定的强制性;无模式对话框则没有这种限制,用户完全可以不理会这个打开的对话框而去操作程序的其他部分,缺省情况下对话框都是无模式的。新建的对话框使用缺省的BorderLayout,它是不可见的,可以使用show( )方法显示它。 对已经创建的对话框,可以用setModal(boolean isModal)方法来改变其模式属性,或使用bo
155、olean isModal( )方法来判断它是否是一个有模式对话框。Dialog获得和修改其对话框标题的是getTitle( )和setTitle(String newTitle);加入和移出组件的方法add(Component)和remove(Component)。例:用Dialog实现消息对话框和一般对话框import java.awt.*;import java.awt.event.*;public class UsedDialog public static void main(String args)MyDialogFrame df = new MyDialogFrame( );cl
156、ass MyDialogFrame extends Frame implements ActionListener,ComponentListener,FocusListenerDialog MegDlg,InOutDlg; /对话框隶属于FrameButton btn1,btn2,btnY,btnN,btnR;TextField tf = new TextField(没有信息,45);TextField getMeg = new TextField(输入信息,10); MyDialogFrame( ) super(使用对话框);Image iconImage = Toolkit.getDef
157、aultToolkit().getImage(.myIcon.gif);this.setIconImage(iconImage); btn1 = new Button(隐藏); btn2 = new Button(询问); btnY = new Button(是); btnN = new Button(否); btnR = new Button(返回); setLayout(new FlowLayout( ); add(tf); add(btn1); add(btn2); btn1.addComponentListener(this); btn1.addActionListener(this)
158、; btn2.addActionListener(this); btnY.addActionListener(this); btnN.addActionListener(this); btnR.addActionListener(this); this.addWindowListener(new WinAdpt( ); this.setLocation(200,300); setSize(350,150); this.setVisible(true); public void actionPerformed(ActionEvent e) /响应按钮引发的动作事件if(e.getActionCo
159、mmand( )=隐藏) /按“隐藏”按钮将隐藏此按钮本身/创建有模式的消息对话框向用户确认删除操作MegDlg = new Dialog(this,真要隐藏吗?,true);MegDlg.setLocation(220, 400);Panel p1 = new Panel( );p1.add(new Label(此操作将隐藏该按钮,要继续吗?);MegDlg.add(Center,p1);Panel p2 = new Panel( );p2.add(btnY);p2.add(btnN);MegDlg.add(South,p2);MegDlg.setSize(200,100);MegDlg.s
160、how( );/显示对话框 else if(e.getActionCommand( )=询问)/创建无模式的对话框接受用户输入的信息InOutDlg = new Dialog(this,请输入信息);InOutDlg.add(Center,getMeg);InOutDlg.add(South,btnR);InOutDlg.setSize(200,100);InOutDlg.setLocation(220, 400);InOutDlg.addFocusListener(this);InOutDlg.show( ); else if(e.getActionCommand( )=是) MegDlg.
161、dispose( ); /关闭消息对话框btn1.setVisible(false); /确认隐藏,引发组件事件 else if(e.getActionCommand( )=否) MegDlg.dispose( ); else if(e.getActionCommand( )=返回) tf.setText(getMeg.getText( )+是对话框的输入); InOutDlg.dispose( );public void componentShown(ComponentEvent e)public void componentResized(ComponentEvent e)public v
162、oid componentMoved(ComponentEvent e)public void componentHidden(ComponentEvent e)/当按钮被隐藏时,显示相关信息tf.setText(按钮+(Button)e.getComponent( ).getLabel( )+被隐藏!);public void focusGained(FocusEvent e)getMeg.setText(对话框+(Dialog)e.getComponent( ).getTitle( ) +获得了注意的焦点!); public void focusLost(FocusEvent e) cla
163、ss WinAdpt extends WindowAdapter /创建窗口剪裁类子类,处理窗口关闭事件public void windowClosing(WindowEvent e)(Frame)e.getWindow( ).dispose( ); /获得引发事件的窗口并关闭之System.exit(0); 例 UsedDialog.java这个程序的最外层容器是一个Frame窗口,它可以响应动作事件和容器事件。窗口中包含一个文本框和两个按钮。用户点击第一个按钮“隐藏”时,弹出消息对话框MegDlg。其中包含一个Label询问用户是否确实要隐藏第一个按钮,还包含两个按钮“是”和“否”。如果用
164、户按“否”,则关闭此对话框;如果按“是”,则关闭对话框并隐藏第一个按钮,此时隐藏按钮的操作将引发组件事件把相关信息显示在Frame的文本框tf中。用户点击Frame的第二个按钮“询问”时,弹出输入输出对话框InOutDlg,请用户在这个对话框的文本框中输入信息。InOutDlg对话框可以响应获得注意焦点的事件,当用户输入并按“返回”按钮时,关闭此对话框并把其文本框getMeg中的信息传送回Frame的文本框tf显示。程序运行结果如图7.25所示。 Dialog 还有一个子类FileDialog,用来表示一种特殊的用来搜索目录和文件,并打开或保存特定文件的对话框,将在后面结合Java的文件操作介
165、绍FileDialog的使用方法。运行结果GUI设计总结如下AWT包GUI的组成用户自定义成分GUI标准控件、事件处理Abstract Windows Toolkit提供各种构成GUI的标准控件抽象:抽取不同软硬件平台中所实现的窗口的公共特性, 针对一个只具有上述公共特性的虚窗口操作依赖于具体平台系统实现:显示效果可能不同Java.awt的体系结构: borderlayout cardlayout CheckboxGroup Color Dimension Event Font Flowlayout FontMericsJava.lang.object Graphics GridBagLayo
166、ut GridLayout image . MenuComponent componentCompoentsButtonConvasContainerchoiceCheckboxTextComponentLabelSCrollbarlistPanelScrollPaneWindowTextAreaTextfieldAppletFrameDialogfileDialog容器组件AWT1、图形用户界面2、布局管理器3、事件处理 略4、组件的定位(布局设计中的绝对定位)1、组件:Button Label Checkbox Checkboxgroup Choice .2、容器PanelAppletWi
167、ndowDialog.FiledialogFrameFlowLayout (Panel默认)BorderLayout (Window Frame默认)GridLayoutCardLayoutGridBagLayout一、组件的定位(布局设计中的绝对定位)特点:1、设置了布局管理器后,组件的定位失效 2、组件的定位与平台有关 3、要使组件的定位有效,可使用setLayout(null),使布局管 理器失效组件定位的方法有:1)setLocation(int x,int y) /设定坐标位置2)setSize(int width,int height) /设定组件宽和高3)setBounds(in
168、t x,int y,int w,int h) /设定组件的大小和位置二、容器1、窗口Window类特点:1、窗口没有标题栏和改变窗口大小的按钮,在实际的应用中经常使用的是它的两个子类(Frame和Dialog是带标题和按钮的顶层窗口), 2、不能作为最外层的容器 2、框架Frame类 -特点:1、是不可见的,无大小尺寸 2、Application程序用它 3、有窗体,默认布局为BorderLayout()-声明: 格式:Frame f =new Frame(“界面”); Frame f =new Frame( );-方法:1)setSize(int w,int h) 2)setVisible(
169、true/false) 或show( ) 3)setTitle(Strint str)Toolkit tk = Toolkit.getDefaultToolkit();Image img = tk.getImage(icon.gif);f.setIconImage(img);-事件1、JFrame类可以引发类可以引发WindowEvent类代表的所有七种窗口类代表的所有七种窗口事件事件2、每个、每个JFrame在其右上角都有三个控制图标,分别代表最在其右上角都有三个控制图标,分别代表最小化、最大化和关闭窗口的操作。其中,小化、最大化和关闭窗口的操作。其中,Frame可自动完成窗口可自动完成窗口
170、的最小化和最大化操作,而关闭窗口的操作不能通过点击关闭的最小化和最大化操作,而关闭窗口的操作不能通过点击关闭图标来实现,但可以使用下述三个办法之一来关闭窗口图标来实现,但可以使用下述三个办法之一来关闭窗口:1)设置一个按钮,当用户点击此按钮时关闭窗口;)设置一个按钮,当用户点击此按钮时关闭窗口;2)用)用WINDOWS_CLOSING事件做出响应,关闭窗口;事件做出响应,关闭窗口;3)使用菜单命令。)使用菜单命令。无论使用哪一种办法,都需要用到关闭无论使用哪一种办法,都需要用到关闭JFrame的的System.exit(0)方法。方法。3、面板Panel类-特点:1、可包含其他的构件或另外的面
171、板 2、缺省布局是FlowLayout 3、其要加载到其它容器中,如Frame或Applet浏览器中 4、无边框、不能被移动、放大、缩小或关闭的容器-声明: 格式:Panel p =new Panel( );-方法:1)setSize(width,Height) 2)setBackground(Color.red) 3)f.add(p)4、Dialog( 对话框)(1)特点:1、显示提示信息和接受用户输入 2、要有一个父窗口,父窗口关闭时,它其中的对话 框也关闭 3、是Window的子类,是可移动窗口 4、缺省布局是BorderLayout 5、对话框是不可见,要用setVisible(tru
172、e)变为可见 可用setVisible(false)隐藏对话框 (2)创建对象 Dialog d=new Dialog(f,”dialog”,true);(3)常用构造方法Dialog(Frame win,boolean b) 构造一个非可视的对话框,通过show( )变为可视,b为true时,对话框为可视,其它构件不能接收用户的输入,此为模式状态Dialog(Frame win,String str,boolean b) 构造一个非可视的对话框 ,String类型为对话框的标题(4)事件:WindowEvent(5)常用方法show()setMode(boolean Model)dispos
173、e()-关闭窗体getTitle()setTitle()getModel (boolean Model)45、FileDialog(文件对话框)(1)特点:1、对文件进行选择存取的组件, 2、是可移动窗口 3、是Dialog的子类 4、是非可视的,要用show( )或setVisible(true)变为可视(2)创建对象 FileDialog f d=new FileDialog(f,”dialog”,save);文件对话框分为二种类型: 1、装入或打开文件。 2、保存文件(3)构造方法FileDialog(Frame parent); 构造一个不带标题的装入文件对话框FileDialog(F
174、rame parent,String titler)FileDialgon(Frame parent,Strings title,int mode) mode为SAVE或 mode 为LOAD(4)常用方法 getFile() /返回文件名getDirectory() /返回文件对话框中的路径setDirectory()Set FilenameFilter() /设置当前文件过滤器setFile( ) /设置默认文件名(5)事件-ActionEvent(6)类型:load用于装入文件Save-用于保存文件1、EventObject类 get Source()-返回产生事件的事件源同老版 tar
175、get()2、AWTEvent类 getID()-返回事件的种类二、布局管理器 每个容器都有对应的布局方式。 没有设置时,为缺省的布局方式。 由布局管理器来管理每个容器的布局。 布局管理器提供了接口LayoutManager。 设置布局的方法setLayout(LayoutManager); Container类中的方法validate( )去更新容器中的布局。在一个容器中,一次只允许使用一种布局管理器。1、FlowLayout (Panel默认)1)声明: 格式: FlowLayout fl=new FlowLayout ( );2) 构造方法 - FlowLayout()/默认为居中 -
176、FlowLayout(int align)/默认间距为4个单元 - FlowLayout(int align, int n1,int n2)Align为FlowLayout.LEFT, FlowLayout.RIGHT FlowLayout.CENTER间矩n1,n2分别指定各组件间的横向和纵向间的3)加组件 f.add(对象名)组件按加入的先后排4)设置布局 f.setLayout(fl)2、BorderLayout (Frame默认) 1)声明: 格式: BorderLayout bl=new BorderLayout ( ); 按 East,South,West,North,Center
177、放2)构造方法 - BorderLayout ( ) /各组件间的横纵向距都为0 -BorderLayout (int horizontal-gap,int vertical-gap) 3)加组件 f.add(b,”South”)或f.add(”South” , b) f.add(b,BorderLayout.SOUTH)3、GridLayout 1)声明: 格式: GridLayout gl= new GridLayout ( );2)构造方法 - GridLayout ( ) - GridLayout (int row,int cols) - GridLayout (int row,int
178、 cols,int hgap,int vgap)3)加组件 f.add(b)4)布局的设置 -f.setLayout(fl);4、CardLayout1)声明: 格式: CardLayout cl= new CardLayout ( );2)构造方法 - CardLayout ( ) 3)方法 -first( )- -next( )- 每次只能显示一个卡片 -prvious( )- -last( )-4)加组件 格式:add(字符串,组件),通过字符串名调用显示组件 f.add(p1,”first”) f.add(p2,”second”)5)布局的设置 -f.setLayout(cl);4、G
179、ridBagLayout GridBagConstraints 容器中的各个控件按网格状整齐排列, 每个控件可以占一个或多个格。 除了生成GridBagLayout对象外,还需生成GridBagConstraints对象来设置每个控件的约束条件。使用以下几个实例变量:gridx, gridy 控件左端、上端的位置。gridwidth, gridheight 控件所占的行列数。fill 控件填满整个显示区。ipadx, ipady 比例关系。insets 控件与边缘的距离。anchor 控件位置。weightx, weighty 分配额外的空间三、事件处理1、接口2、注册监听器3、接口方法对事件
180、进行处理4、适配器(一)基本概念:1、事件:在java和其它面向对象的程序设计中,通常把用户每次通过 鼠标或键盘的输入称为一个事件(event)2、事件源:图形用户界面的每个可能发生事件的组件称为事件源。 程序对事件的反应是通过执行一段被称作事件方法的代码 来实现的,而编写这段代码则是由程序设计者来完成的。 在其他的面向对象的程序设计语言如VB中,在能够成为事 件源的对象中,系统预置了所有可能发生事件及其方法的 名称,编程时只要在系统提供的方法中添加需要的代码即 可。在这样的程序设计语言中,事件方法是作为对象的一 个成员方法出现的。在java语言中,事件源对事件的监听 与处理不是由其本身的成员
181、方法来实现,而是委托一个另 外的对象来完成,这个另外的对象称作事件监听者 (Listener)。当一个事件发生时,由系统将事件发生的消息 传送给事件监听者,通过执行监听者的事件方法作出反应。 (二)委托事件模型(二)委托事件模型 JavaJava采用委托事件模型来处理事件。委托事件模型的特点是将事件的处采用委托事件模型来处理事件。委托事件模型的特点是将事件的处理委托给独立的对象,而不是组件本身,从而将使用者界面与程序逻辑分开。理委托给独立的对象,而不是组件本身,从而将使用者界面与程序逻辑分开。整个整个“委托事件模型委托事件模型”由产生事件的对象(事件源)、事件对象以及监听者由产生事件的对象(事
182、件源)、事件对象以及监听者对象之间的关系所组成。对象之间的关系所组成。 产生事件的对象会在事件产生时,将与该事件相关的信息封装在一个称产生事件的对象会在事件产生时,将与该事件相关的信息封装在一个称之为之为“事件对象事件对象”的对象中,并将该对象传递给监听者对象,监听者对象根的对象中,并将该对象传递给监听者对象,监听者对象根据该事件对象内的信息决定适当的处理方式。监听者对象要收到事件发生的据该事件对象内的信息决定适当的处理方式。监听者对象要收到事件发生的通知,必须在程序代码中向产生事件的对象注册,当事件产生时,产生事件通知,必须在程序代码中向产生事件的对象注册,当事件产生时,产生事件的对象就会主
183、动通知监听者对象,监听者对象就可以根据产生该事件的对象的对象就会主动通知监听者对象,监听者对象就可以根据产生该事件的对象来决定处理事件的方法。来决定处理事件的方法。 监听者对象(监听者对象(listener)就是用来处理事件的对象)就是用来处理事件的对象。监听者对象等候事件的发。监听者对象等候事件的发生,并在事件发生时收到通知。生,并在事件发生时收到通知。 不同事件源上发生的事件种类不同,不同的事件由不同的监听者处理。不同事件源上发生的事件种类不同,不同的事件由不同的监听者处理。 二、事件处理的三步 一个事件源构件的事件监听者是一个自定义类或已有类的对象,为了能够实现事件监听者的功能,它必须满
184、足以下3 个条件:1、必须实现与事件相关的接口。 在java中已经定义了所有可能发生的事件类并且预置了相应的事件接口,在这些事件接口中定义了事件处理的抽象方法。在系统正是通过这些已定义好的事件和事件接口来传递事件消息和进行事件处理的,因此事件监听者必须通过implements关键字来实现与所有监听事件相对应的接口。2、必须重置接口中的方法。 由于接口中的方法都是抽象的,在事件监听者中必须对接口中的方法依据事件处理的要求进行定义,这段重新定义的代码就是具有事件处理功能的处理方法代码,它是整个事件处理的核心部分。3、将事件监听者通过事件源的addxxxListener( )方法进行注册。 这种注册
185、将事件源与事件监听者联系进来,使得事件监听者接受事件源的委托去监听发生的事件并进行相应的事件处理三、适配器 当接口方法超过一个时用适配器Adapter(接口名中的Listener用Adapter换)。定义“Adaper”类为事件剪裁类,这些Adapter类就是把它们对应接口中的所有方法用空的方法体实现事件事件(Event)事件监听者事件监听者(Listener)说明说明ComponentEventComponentListener主要处理组件大小的改变,位置的改变主要处理组件大小的改变,位置的改变及可见与不可见状态等及可见与不可见状态等ComponentEventComponentListen
186、er主要处理组件的加入或移出容器主要处理组件的加入或移出容器FocusEventFocusListener主要处理取得焦点或移开焦点等操作主要处理取得焦点或移开焦点等操作KeyEventKeyListener主要处理键盘的操作主要处理键盘的操作MouseEventMouseListener主要处理鼠标是否在某个组件上、是否主要处理鼠标是否在某个组件上、是否按下鼠标等操作按下鼠标等操作MouseMotionEventMouseMotionListener主要追踪鼠标的位置主要追踪鼠标的位置WindowEventWindowListener主要处理窗口问题,如打开、关闭、最主要处理窗口问题,如打开
187、、关闭、最大或最小化等大或最小化等表表9.4Component类与类与Container类提供的事件与事件监听者之类提供的事件与事件监听者之间的关系间的关系MouseListenermouseClicked(MouseEvente)mouseEntered(MouseEvente)mouseExited(MouseEvente)mousePressed(MouseEvente)mouseReleased(MouseEvente)MouseMotionListenermouseDragged(MouseEvente)mouseMoved(MouseEvente)ContainerListener
188、componentAdded(ContainerEvente)componentRemoved(ContainerEvente)ComponentListenercomponentHidden(ComponentEvente)componentMoved(ComponentEvente)componentResized(ComponentEvente)componentShown(ComponentEvente)FocusListenerfocusGained(FocusEvente)focusLost(FocusEvente)ItemListenerKeyListenerkeyPressed
189、(KeyEvente)keyReleased(KeyEvente)keyTyped(KeyEvente)AdjustmentListeneradjustmentValueChanged(AdjustmentEvente)itemStateChanged(ItemEvente)几种常用的事件情况:一、ActionEvent 事件1、引发事件的动作 1)在文本框( TextField )中按回车键时 2)双击列表框(List )时 3)单击命令按钮(Button)时 4)单击菜单项(MenuItem)时2、接口是:ActionListener3、注册监听程序 addActionListener(t
190、his)4、实现接口方法 actionPerformed(ActionEvent e)5、主要方法: -getSource( ) 获取引发事件的对象名 -getActionCommand() 获取对象的标签或事先为这个对象设 置的命令名 -ID 获得事件源的类型各组件的getActionCommand()命令名为: (1)Button为按钮的标签 如:Button b=new Button(“hello”) if (e.getActionCommand()=“hello” ) / 或 if(e.getSource()=b)(2)菜单是菜单项的标签名(3)列表选项是其标签名(4)文本域为文本区域
191、中的字符串 二、ItemEvent事件1、引发事件的动作(1)改变复选框改变复选框Checkbox对象的选中或不选中状态;对象的选中或不选中状态;(2)改变单选按钮改变单选按钮RadioButton对象的选中或不选中状态;对象的选中或不选中状态;(3)改变下拉列表框改变下拉列表框ComboBox对象中选项的选中或不选中对象中选项的选中或不选中状态;状态;(4)改变菜单项改变菜单项MenuItem对象中选项的选中或不选中状态;对象中选项的选中或不选中状态;(5)改变改变CheckboxMenuItem对象中选项的选中或不选中状对象中选项的选中或不选中状态。态。(6)改变改变List对象选项的选中
192、或不选中状态对象选项的选中或不选中状态(7)改变)改变Choice对象选项的选中或不选中状态对象选项的选中或不选中状态2、接口是:ItemListener3、注册监听程序 addItemListener(this)4、实现接口方法 itemStateChanged(ItemEvente)5、主要方法: -e.getItemSelectable()方法以获得引发选择事件的事件源方法以获得引发选择事件的事件源对象,对象,-getStateChange()方法获取选择事件之后的状态变化类型方法获取选择事件之后的状态变化类型ItemEvent.SELECTED:代表选项被选中代表选项被选中ItemEv
193、ent.DESELECTED:代表选项被放弃不选代表选项被放弃不选-getItem()返回引发选中状态变化事件的具体选择项返回引发选中状态变化事件的具体选择项e.g:if(e.getStateChange()=e.SELECTED)或或if(cbx.getText()=“red”/CheckBoxcbx=(CheckBox).getItem();三、TextEvent事件1、引发事件的动作、引发事件的动作(1)文本区域中改变文本的内容。如:删除和键入字符)文本区域中改变文本的内容。如:删除和键入字符2、接口是:、接口是:TextListener3、注册监听程序注册监听程序addTextList
194、ener(this)4、实现接口方法实现接口方法TextValueChanged(TextEvente)四、组件41、Button(按钮)(1)创建创建ButtonmyB=newButton(“Cancel”);(2)常用构造方法常用构造方法Button();Button(Stringlabel);(3)常用方法常用方法getLabel()返回按钮的标签返回按钮的标签setActionCommand()为按钮设置一个命令名为按钮设置一个命令名getActionCommand()获得这个命令名获得这个命令名(4)事件响应 a:接口为接口为ActionListenerb:注册事件监听程序注册事件监
195、听程序addActionListenerc:接口方法接口方法ActionPerformered(ActionEvente)d:动作事件的对象动作事件的对象e,getSource()获取引发动作事件的按钮对象获取引发动作事件的按钮对象e.getActionCommand()获取事件设置的命令名获取事件设置的命令名(5)组件加入容器组件加入容器2、Label(标签标签)Labelmyl=newLabel(“标签内容标签内容”);设置标签内容:设置标签内容:myl.setText(“新内容新内容”);3、Checkbox复复选框选框(1)创建创建Checkboxcb=newCheckbox(“reg
196、istered”,true);(2)常用构造方法常用构造方法Checkbox()不带标签不带标签,初始状态为关初始状态为关Checkbox(Stringlabel)带标签带标签,初始状态为关初始状态为关Checkbox(Stringlabel,booleanstate)带标签带标签,初始状态初始状态由由boolean型变量型变量state决定决定(2)常用构造方法常用构造方法Checkbox()不带标签不带标签,初始状态为关初始状态为关Checkbox(Stringlabel)带标签带标签,初始状态为关初始状态为关Checkbox(Stringlabel,booleanstate)带标签带标签
197、,初始状态初始状态由由boolean型变量型变量state决定决定(3)常用方法常用方法getState()返回值为布尔量返回值为布尔量,选中为选中为true,否则为否则为falsesetState(true)设置是否选中设置是否选中(4)事件响应 a: 接口为 ItemListener b: 注册事件监听程序 addItemListener c: 接口方法 ItemStateChanged(ItemEvent e) d: 动作事件的对象 e,getSelectabel() 获取引发动作事件的事件源对象 再调用e.getState() 获取选择事件之后的状态 或用e.getStateChang
198、e()=ItemEvent.SELECTED)表示选(5)组件加入容器 Checkbox one=new Checkbox(“one”) Checkbox two=new Checkbox(“two”); Checkbox three=new Checkbox(“three”); Checkbox four=new Checkbox(“four”); p.add(one); p.add(two); p.add(three); p.add(four);44、CheckboxGroup(单选按钮组)单选按钮组是一组Checkbox的集合(1)创建CheckboxGroup,再加入单个按钮例:new
199、 Checkbox(“male”, 组名, false);CheckboxGroup cbg=new CheckboxGroup(); Checkbox one=new Checkbox(“one”,cbg,false) Checkbox two=new Checkbox(“two”,cbg,true); Checkbox three=new Checkbox(“three”,cbg,true);(2)常用构造方法 Checkbox(String label,boolean state,CheckboxGroup group);Checkbox(String label,CheckboxGro
200、up group ,boolean state);(3)常用方法 getSelectedCheckbox() 获知选择哪个按钮 再调用getlabel 知道选择了什么 信息 setSeclectCheckbox()指定单选择按钮组中的那个按钮 (4)事件响应 同Checkbox45、Choice 下拉列表(1)创建 Choice c=new Choice(); c.addtem(“First”);c.addItem(“Second”);c.addItem(“Third”);(2)常用构造方法 Choice();(3)常用方法 getSelectedIndex() 返回被选项的序号(第一个选项的
201、序号为0) getSelectedItem() 返回被选取中的标签文本字符串(4)事件响应 a: 接口为 ItemListener b: 注册事件监听程序 addItemListener c: 接口方法 ItemStateChanged(ItemEvent e) d: 动作事件的对象 e,getSelectabel() 获取引发动作事件的事件源对象 再调用e.getState() 获取选择事件之后的状态 或用e.getStateChange()=ItemEvent.SELECTED)表示选中6、TextField(文本域)-无滚动条(1)作用:可进行编辑,接受用户输入,而且输入内容为单行 显示
202、(2)创建对象 TextField tf=new TextField(“sample”,30); 构成一个列数为30,初始字符串为Sample的文本域(3)常用构造方法A: TextField()-构造一个空文本域B:TextField(String text)-构造一个显示指定初始字符串的文本框C:TextField(String text,int columns)-构造一个具有指定列数 columns,显示指定初始字符串的文本域D.TextField(int column)-构造一个指定列数的空文本域(4)常用方法:注:在单行文本域中输入时,若内容超出了指定列宽,将 自动向右流动.查看输入
203、的全部内容时,用左右移动A:getText()-获取文本域中显示的内容B:setText(String str/value)-设置文本域中的内容C:setEchoChar(Char c)- 设置文本域的输入为回显字符 D:setEditable(true/false)-设置文本域的编辑方式,false 为只读, 默认设置为true(5)事件:有两个事件 A:当用户按Enter或Reture键时,将引发ActionEvent事件 B:改变文本的内容,如:删字符或键入字符时引发TextEvent 事件ActionEvent事件 a: 接口为 ActionListener b: 注册事件监听程序 a
204、ddActionListener c: 接口方法 actionPerformed(ActionEvent e) 用getActionCommand( ) 得文本域命令名 。TextEvent事件 a: 接口为 TextListener b: 注册事件监听程序 addTextListener c: 接口方法 textValuechanged(TextEvent e)7、TextArea(文本区)-有滚动条(1)作用:支持用户做多行输入和显示(2)创建对象 TextArea ta=new TextArea(“sample”,4,30); 构成一个列数为4,列为30,初始字符串为Sample的文本域
205、(3)常用构造方法A: TextArea()-构造一个的水平和垂直滚动杠的空文本域B:TextArea(String text)-构造一个的水平的垂直流动杠 并显示初始文本内容的文本区C:TextArea(String text,int rows,int columns)-构造一个 有水平和垂直流动杠并具有指定行数为rows, 列数columns,显示指定初始字符串的文本区D.TextArea(int rows,int column)-构造一个有水平和 垂直滚动杠,具有指定列数的空文本区E.TextArea(String text, int rows,int column, int scrol
206、lbars) -构造一个具有指定行数和列数及滚动杠并显 示初始文本内容的文本区Scrollbars参数指定要显示的滚动杠,四种可能的取值:SCROLLBARS_BOTH同时显示水平和垂直流动杠SCROLLBARS_VERTICAL_ONLY只显示垂直滚动杠SCROLLBARS_HORIONTAL_ONLY只显示水平流动杠SCROLLBARS_NONE两个滚动杠都不显示(4)常用方法:Append(String)将指定文本追加到文本区Insert(String,int)将指定文本插入到文本区的特定位置replaceRange(String ,int,int)用指定文本替换文本区中的内容setEd
207、itable(boolean)将文本区设置为不可编辑或可编辑状态5)事件: 当用户按Enter或Reture键时,将不引发ActionEvent事件和TextEvent事件,其结果只是向缓冲区输入一个字符,而不能表示输入结束,因此,当需要识别用户“输入完成”时,通常要在文本区旁放置一个Apply或Commit之类的按钮6)TextArea和TextField的父类TextComponent类主要方法: getSelectedText() 从文本组件中提取被选中的文本内容 getText() 从文本组件中提取所有文本的内容select(int,int) 在文本组件中选中部分内容selectAll
208、()在文本组件中选中所有内容setEditable(boolean)设置为可编辑或不可编辑状态setText(String)设置文本组件中的文本内容8、List( 列表)(1)作用:供用户运行选择的一系列可选项(2)创建对象 List l=new List(4,false); 构成一个显示4项的单项列表,false单选,true多选取 使用 addItem()向列表中加入可选项 l.addItem(“Monday”); l.addItem(“Tuesday”); l.addItem(“Wednesday”);(3)常用构造方法 List() 构造 一个单选列表 List(int rows)构造
209、 一个指定项数的单选列表 List(int rows,boolesn multipleMode)构造一个显示指定项数 row列表,multipleMode为false单选为false,多选为true(4)常用方法 add(String name) add(String name,int index)(4) 事件单击列表项-引以ItemEvent事件双击列表项-引以ActionEvent事件用getSelectedItem()获得当前选中项的内容(单选)用getSelectedItems()获得当前选中项的内容(多选)返回是一个 数组用getSelectedItem()获得当前选中项的内容(单选
210、)用getSelectedItems()获得当前选中项的内容(多选)返回是一个数组getSelectedIndex()获得当前选中项下标索引值9、菜单(1)特点:1、不能放入普通容器中,只能放入“菜单容器” 如:Frame ,MenuBar, Menu 2、不能用布局管理器进行控制 3、菜单条不支持监听者,其预期的事件自动处理(2)与菜单组件相关的类: MenuBar , Menu ,MenuItem, CheckboxMenuItem(3)菜单的创建分三步: A:菜单条:Frame f =new Frame(“MenuBar”); MenuBar mb=new MenuBar( ); f.a
211、ddMenuBar(mb) B:菜单Menu( ) : 1、构造方法有两个: - Menu(String str ) /用给定的标识构造一个菜单 e.g: Menu(“file”) -Menu(String str,boolean b) /用给定的标识构造一 个菜单.如果布尔值为false,那么当释放鼠标按后,菜单项 会消失,如果布尔值为true,那么当释放鼠标时菜单项仍将 显示; 2、创建对象 Menu m1=new Menu(“File”); Menu m2=new Menu(“Edit”); 3、方法:Disable 为不可选项,enable方法为可选项C:菜单项MenuItem( )
212、: 1、MenuItem与CheckboxMenuItem()类的构造方法 MenuItem(String str) MenuItem( _ ) /建一个分隔符 或m1.setSeparator( ) CheckboxMenuItem(String str) / 2、创建对象 MenuItem mi1=new MenuItem(“new”); MenuItem mi2=new MenuItem(“cope”); MenuItem mi2=new MenuItem(“delete”); 3、 添加不同内容到菜单项中 a:加菜单项 m1.add(mi1); m1.add(mi2); b:加复选项CheckboxMenuItem()的菜单选项(选中为钩) CheckboxMenuItem cb=new CheckboxMenuItem( ) m1.add(cb);(4)事件处理 A、菜单项被选中的事件是ActionEvent B 、CheckboxMenuItem复选状态发生变化时引发ItemEvent事件10、弹出式菜单(PopupMenu)(1)特点:1)需要依附在某个组件上 2)不受布局管理器的控制 3)显示必须主调用show()构造方法: PopupMenu() PopupMenu(“java”)