JAVA图形用户界面的设计与实现.ppt
第7章 图形用户界面的设计与实现,7.1 图形用户界面(GUI)概述,界面设计的主要任务:(1)创建组成界面的各成分和元素,指定它们的属性和位置关系;(2)定义界面事件和各元素对不同事件的响应,实现界面与用户的交互功能;生成界面的类库:java.awt(abstract window toolkit)抽象:操作定义在一个虚拟的窗口中进行,实现跨平台;,界面的元素和成分,容器控制组件用户自定义成分,容 器(1),容器(container):组织其他界面成分和元素的单元,用来存放别的组件。有三种类型的容器:Window、Panel和ScrollPane。,容 器(2):Frame容器,Window是能独立存在的容器,Frame是它的子类。Frame 是有边框容器,通常用作最外层容器,不能被其他容器包含。Frame方法:Frame(String title);add():在Frame中加入其他组件。pack()方法会自动确定Frame的大小,确保Frame容器中的组件都会有与布局相适应的合理大小。setVisible(true):使Frame成为可见。Frame被创建后,它是不可见的。例子:见2007ch7srcSimpleFrame.java,容 器(3):Panel容器,特点:1)没有边框,不能被移动、缩放或关闭。2)不能作为最外层图形界面的容器,不能单独存在只能用做容器组件加入其他容器。3)通常用于层次化界面组件管理。P260:例 7-20 TestPanel.java例子:ch7srcMyFrame.java,组件:图形用户界面的最小单元,用来完成与用户的交互;用户界面标准化的结果,例如:标签、文本框、按钮、菜单等。使用组件的步骤:1)创建组件类的对象,指定其属性;2)使用某种布局策略;3)将组件对象注册给对应的事件监听器,覆盖事件处理方法,实现与用户交互的功能;,组 件,用户自定义成分:如绘制几何图形、使用标志图案等。通常只能起到装饰、美化的作用,不能响应用户的动作,不具有交互功能。,用户自定义成分,7.2 绘制图形 利用 Graphics 类可以绘制文字及直线、矩形、多边形、圆和椭圆等各种图形。对于Application程序:创建 Canvas 对象,并将它加入界面容器中。Applet 类和 Canvas 类都有一个 paint()方法,系统会自动创建一个 Graphics 类的实例作为其参数,实现各种图形绘制;,Graphics 类的常用绘图方法例7-1 DrawFigures.java(p185)drawLine(int x1,int y1,int x2,int y2):绘制直线 drawRect(int x,int y,int width,int height):绘制矩形 fillRect(int x,int y,int width,int height):填充矩形,设置字体Font类显示文字:Graphics 类的 drawString()方法,在屏幕的指定位置显示字符串。Font 类:表示一种字体,包含字体类型、字型和字号。如:Font fnt=new Font(“TimesRoman”,Font.BOLD,12);Font 类有三种字体:Font.PLAIN,Font.BOLD,Font.ITALIC。使用字体:Graphics 类的 setFont()方法如:g.setFont(fnt);btn.setFont(fnt);,例7-2AvailableFonts.JavaGraphicsEnviroment类:The GraphicsEnvironment class describes the collection of GraphicsDevice objects and Font objects available to a Java(tm)application on a particular platform.,设置颜色Color类Color 类对象:控制文字或图形的颜色;构造函数:public Color(int Red,int Green,int Blue);各参数取值范围:0255 public Color(float Red,float Green,float Blue);参数取值范围:0.01.0 public Color(int RGB);参数的07位为红色分量,815位为绿色分量,1623位为蓝色分量例:Color blueColor=new Color(0,0,255);/问这是什么颜色?,颜色设置:Graphics 类的 setColor()方法使用自定义的颜色:Color blueColor=new Color(0,0,255);g.setColor(blueColor);使用 Color 类的颜色常量:g.setColor(Color.black);Color 类定义了 13 个静态颜色常量,包括:black(0,0,0)red(255,0,0)green(0,255,0)blue(0,0,255)等。,对 GUI 组件,可用下列方法设置或获取组件的背景色和前景色:public void setBackground(Color c);public Color getBackground();public void setForeground(Color c);public Color getForeground();例7-3 UseColor.Java问题:HTML文件中的参数是以什么形式、如何传入字节码的?,显示图像一、获取图像:Applet 类的 getImage();public Image getImage(URL url,String name)该方法将指定图像文件的内容返回到 Image 对象。方法中的参数 url 是一个 URL(统一资源定位器)地址,也就是图像所在网址。name 是图像文件名。Java 支持的图像文件格式包括bmp,gif,jpeg 等。,二、绘制图像:drawImage(Image img,int x,int y,ImageObserver observer)有4个参数:图像的 Image 对象,显示图像的左上角 x、y 坐标,显示图像的容器对象。如:g.drawImage(image,10,10,this);例7-4DrawMyImage.java,实现动画效果制作步骤:1)构造或获取动画的各帧;2)绘制各帧;动画的各帧可以用绘图的方法绘制,也可在给定关键帧的情况下,采用插值方法生成,还可以用 getImage()方法获取文件中的 gif 或 jpg 格式图像。例 7-5:其中的 paint()方法一次显示一幅图像,并调用 Thread.sleep()方法使程序休眠片刻,从而前一副图像在屏幕上暂留,再显示下一幅图像,形成动画。,7.3 Java 的标准组件与事件处理,每一个可以触发事件的组件被当作事件源。每一个事件都对应专门的监听者,监听者用来接收和处理这种事件。如果一个事件源注册了对应的监听者,那么这种事件就会被监听者接收和处理。这种模式称为“委托模型”。,Java 的事件处理机制:委托事件模型,事件源(可能产生事件的组件)注册:btn.addActionListener(监听者对象);,ActionEvent 事件,监听者(负责监听并处理事件的对象)实现接口:public void actionPerformed(ActionEvent e);,触发事件,调用并传递参数,注册,图7-5 委托事件模型,事件与监听者接口,要注意以下问题:有哪些事件源,可能发生什么事件?将事件源注册给哪个监听者?监听接口包含什么方法?各代表对什么事件的处理?举例:见P215表格,AWT的事件处理模型:监听者对象是实现监听者接口的类的实例。事件源在事件发生时把事件对象发送给注册的监听者。监听者对象会使用事件对象中的信息来决定如何响应事件。注册监听者对象是通过调用事件源的.addXXXListener()来实现的。如下:eventSourceObject.addEventListener(eventListenerObject);,并非每个事件类都只对应一个事件,例如:KeyEvent类对应KEY_PRESSED,KEY_RELEASED,KEY_TYPED三个具体的事件。KeyEvent类的getID()可以返回不同的常量,以此来判断具体的事件类型。,以 JButton为例,关心的事件就是按钮被按下,想注册该事件,就需要调用 JButton的addActionListener()方法,该方法带一个参数实现 ActionListener接口的对象,ActionListener接口只包含一个 actionPerformed()方法,所以,将实现的代码与JButton联系起来的方法就是在类里实现ActionListener接口,而且将该类的对象用JButton 的addActionListener()方法注册。这样 actionPerformed()方法将在按钮被按下时被回调。,事件处理,用内部类实现监听接口:见例子ButtonCounter.java将容器类实现监听接口:见例子FrameCounter.java定义专门的外部类实现监听接口:见例子OuterCounter.java采用事件适配器:见例子AdapterCounter.java,注意适配器是类,不是接口。,7.4 GUI 标准组件概述,Component,Button,组件名,Canvas,TextArea,TextField,List,Scrollbar,Label,TextComponent,Checkbox,Choice,Container,Dialog,Frame,Window,Applet,Panel,ScrollPane,容器,FileDialog,图7-7 AWT 组件层次关系图,Component 类的常用方法 public void add(PopupMenu popup):在组件上加上一个弹出菜单。public Color getBackground():获得组件的背景色。public Font getFont():获得组件使用的字体。public Color getForeground():获得组件的前景色。public Graphics getGraphics():获得绘图用的 Graphics 对象。public void repaint(int x,int y,int width,int height):以指点的坐标点为左上角,重画组件中指点宽、高的区域。public void setBackgound(Color c):设置组件的背景色。public void setEnable(boolean b):设置组件的使能状态。public void setFont(Font f):设置组件的字体。public void setSize(int width,int height):设置组件大小。public void setVisible(boolean b):设置组件是否可见的属性。public void setForeground(Color c):设置组件的前景色。public void requestFocus():使组件获得注意的焦点。,标签、按钮和动作事件1.标签(Label)标签类 Label 的对象用来显示文本信息。它不是事件源,不能引发事件。常用方法是 getText()和 setText(String s)。按钮(Button)Button 类的常用方法是 getLabel()和 setLabel(String s)。按钮可以引发动作事件,如 ActionEvent。为此,对应的监听者必须实现 ActionListener 接口,并实现相应的 actionPerFormed(ActionEvent e)方法。,动作事件(ActionEvent)ActionEvent 类只包含一个执行动作事件 ACTION_PERFORMED。可触发该事件的动作包括:()按钮-点击;()列表中的某一选项-双击;()菜单项-选择;()文本框-回车;(5)定时器经过一定的时间(a certain amount of time has elapsed),区分不同的事件源 Button btn=new Button(“计算”);btn.setActionCommand(“命令名”);btn.addActionListener(this);/接口的动作响应方法 public void actionPerformed(ActionEvent e)if(e.getActionCommand()=“命令名”)/若无第2句,则用 if(e.getActionCommand()=“计算”)/或者用 if(e.getSource()=btn),public int getModifiers():判断是否还按了Ctrl、Shift等功能键;该方法返回一个整数,可与 ActionEvent 类的静态常量 ALT_MASK,SHIFT_MASK,CTRL_MASK,META_MASK 比较,用来判断动作事件发生时,是否同时按下某个功能键。目的:将一个动作事件再细分成几个事件;,文本框、文本区域与文本事件,文本域(TextField)与文本区(TextArea)TextField 是单行文本框,TextArea 是多行文本区域。它们都是 TextComponent 的子类。创建 TextArea txtArea=new TextArea(10,45);/10 行 25 列的文本区 TextField name=new TextField(“卡号”,8);/初始字符串为“卡号”,可容纳 8个字符,常用方法 父类 TextComponent 的方法 getText():获取文本信息 setText(String text):设置文本内容 setEditable(bollean b):指定文本是否可编辑 isEditable():判断文本是否可编辑 select(int start,int end):选择指定范围内的文本 selectAll():选定全部文本 setSelectionStart(int start)和 setSelectionEnd(int end):设置选定文本的起、止位置 getSelectionStart()和 getSelectionEnd():获得选定文本的起、止位置 getSelectText():获取选定文本的内容,TextField 类的特殊方法:setEchoChar(char c):设置回显字符,用在不希望如实回显的场合(如输入密码时)。getEchoChar():获取屏蔽当前文本域的回显字符。EchoCharIsSet():判断是否设置了屏蔽当前文本域的回显字符。TextArea 类的特殊方法:append(String s):在已有文本后面添加字符串 s insert(String s,int index):将字符串 s 插入到指定序号处。,(3)事件响应 TextEvent 事件:该类包含代表文本变化(如删除或键入字符)的事件TEXT_VALUE_CHANGED;由TextField 和TextArea 的父类 TextComponent 产生;要响应这个事件,程序应实现 TextListener 接口,并实现响应该事件的方法:public void textValueChanged(TextEvent e);调用 e.getSource 可以获得引发该事件的文本域对象引用。ActionEvent 事件:当用户在文本域按回车键时,可由 TextField 对象产生这一事件。,单、复 选按钮,列表与选择事件,选择事件(ItemEvent)ItemEvent 类包含的是代表选择项的选中状态发生变化的事件 ITEM_STATE_CHANGED。引发这类事件的动作包括:(1)改变列表类 List 对象选项的选择状态。(2)改变下拉列表类 Choice 对象选项的选择状态。(3)改变复选按钮类 Checkbox 对象的选择状态。(4)改变检测盒菜单项 CheckboxMenuItem 对象的选择状态。,ItemEvent 类的主要方法,public ItemSelectable getItemSelectable():返回引发选中状态变化事件的事件源,如选项或状态变化的 List、Choice 或 Checkbox对象。public Object getItem():返回引发选择状态变化的具体选择项(指“文本”),如选中的具体的 item。public int getStateChange():返回选择状态的具体类型,其值包括 ItemEvent.SELECTED(被选中)和 ItemEvent.DESELECTED(不选)。,复选按钮(Checkbox 检测盒)(1)创建(可同时指明其文本说明标签)Checkbox bcakg=new Checkbox(“背景色”);(2)常用方法 getState()返回复选按钮的状态:选中(true)或未选中(false)。setState(boolean b)设置复选按钮的状态。,(3)事件响应 将检测盒注册给 ItemEvent 事件监听者 ItemListener 事件源.addItemListener(监听者);实现接口方法,以响应检测盒状态变化public void itemStateChanged(ItemEvent e)在方法体中,用 e.getItemSelectable()方法获取事件源对象引用,再调用 e.getState()方法获取选择状态。例 7-8 TestCheckbox.java,单选按钮组(CheckboxGroup)单选按钮组是一组 Checkbox 的集合(每个Checkbox 对应一种情况),用 CheckboxGroup 类的对象表示。例如,下述语句创建一个CheckboxGroup,三个Checkbox 对象,并设置从属关系:CheckboxGroup checkboxGroup1=new CheckboxGroup();Checkbox checkbox1=new Checkbox();checkbox1.setCheckboxGroup(checkboxGroup1);Checkbox checkbox2=new Checkbox();checkbox2.setCheckboxGroup(checkboxGroup1);Checkbox checkbox3=new Checkbox();checkbox3.setCheckboxGroup(checkboxGroup1);,事件响应 CheckboxGroup 类是 Object 类的直接子类,不能响应事件,但可由组中的每个 Checkbox 对象响应 itemStateChanged 类的事件。,下拉列表(Choice)(1)创建包括创建 Choice 对象和添加选项两步:size=new Choice();/创建下拉列表 size.add(“10”);/添加选项 size.add(“16”);size.add(“20”);(2)常用方法 getSelectedIndex():返回被选项的序号 getSelectedItem():返回被选项的标签文本字符 select(int index)、select(String item)选中指定序号或文本内容的选项 add(String item)和 insert(String item,int index):将新选项 item 加在下拉列表的最后或指定的序号处。remove(int index)和 remove(String item):删除指定序号或指定标签文本的选项。removeAll():删除所有选项,列表(List)(1)创建 列表可以实现“多选多”(复选)。构造函数包括:public List();public List(int rows);public List(int rows,boolean multipleMode);其中,rows 为可同时显示的选项(Item)个数,multipleMode 指明是否允许复选。缺省时不允许复选。创建列表时,也要同时添加选项:List MyList=new List(5,true);MyList.add(“北京”);MyList.add(“上海”);,(2)常用方法 getSelectedItem():返回被选项目的文本。getSelectedItems():返回包含所有被选项目的字符串数组。getSelectedIndex():返回被选项目的序号。getSelectedIndexs():返回由所有被选项目的序号组成的整型数组。select(int index)和 deselect(int index):选中或不选指定序号的选项。add(String item):将标签为 item 的项目加至列表的最后。add(String item,int index):将标签为 item 的项目加至指定序号处。remove(int index):删除指定序号处的选项。,(3)事件响应 产生的事件:itemStateChanged:单击某一选项;actionPerformed:双击某一选项;要响应这两种事件,必须将列表注册给相应的事件监听者。list1.addItemListener(new Applet1_list1_itemAdapter(this);list1.addActionListener(new Applet1_list1_actionAdapter(this);并实现相应的接口及方法。例 7-11TestList.java,7.7 设计事件处理专用类,7.7.1 内部类外部类可以使用自己的内部类,比如创建内部类的对象并调用其方法。内部类能访问外部类中定义的所有属性和方法。,7.7.2 用内部类实现事件处理例子见前面。,7.7.3 焦点事件FocusEvent类包含两个具体事件:FOCUS_GAINED,FOCUS_LOST。FocusListener监听者接口定义了两个方法:public void focusGained(FocusEvent e)public void focudLosted(FocusEvent e)组件与焦点有关的方法:requestFocus()hasFocus(),滚动条与调整事件,调整事件(AdjustmentEvent)AdjustmentEvent 类只包含一个表示 GUI 组件发生连续变化的事件 ADJUSTMENT_VALUE_CANGED,当用户操纵滚动条(Scrollbar)或其子类组件,改变滑块位置时,引发这一事件。AdjustmentEvent 类的主要方法:public Adjustable getAdjustable():返回引发状态变化的事件源。public int getAdjustmentType():返回事件的状态变化类型,其值包括:TRACK(拖动滑块)、UNIT_DECREMENT(点击下三角按钮,引发最小单位下移)、UNIT_INCREMENT(点击上三角按钮,引发最小单位上移)。public int getValue():返回状态变化后滑块对应的当前数值。,滚动条(Scrollbar)(1)创建 Scrollbar mySlider=new Scrollbar(Scrollbar.HORIZONTAL,50,1,0,100);其中,参数 1 指明滚动条方向,Scrollbar.HORIZONTAL 为水平方向,Scrollbar.VERTICAL 为垂直方向。参数 2 为滑块的初始位置,整型量。参数 3 为滑块的大小。参数 4、5 分别为滑块代表的最小和最大数据。(2)常用方法 setUnitIncrement(int unit):指定单位增量,即单击两端的三角按钮时的数据改变。setBlockIncrement(int blk):指定块增量,即单击滚动槽时的数据改变。getValue():返回当前滑块位置代表的整数值。,例 7-12TestSlider.Java,画布与鼠标、键盘事件,鼠标事件(MouseEvent)MouseEvent 类包含 7 个鼠标事件:MOUSE_CLICKED:鼠标点击事件MOUSE_DRAGGED:鼠标拖动事件MOUSE_ENTERED:鼠标进入事件MOUSE_EXITED:鼠标离开事件MOUSE_MOVED:鼠标移动事件MOUSE_PRESSED:鼠标按钮按下事件MOUSE_RELEASED:鼠标按钮松开事件 MouseEvent 事件的监听者 MouseListener 和 MouseMoveListener 中有 7 个方法,与上述事件对应。系统会根据具体事件类型,自动调用相关的方法。MouseEvent 类的主要方法 getX()和 getY():分别返回鼠标事件的 X 和 Y 坐标。getPoint():返回包含鼠标事件坐标的 Point 对象。getClickCount():返回鼠标点击事件的点击次数。,键盘事件(KeyEvent)KeyEvent 类包含 3 种键盘事件:KEY_PRESSED:按键被按下 KEY_RELEASED:按键被松开 KEY_TYPED:按键被敲击KeyEvent 类的主要方法:public char getKeyChar():返回与引发事件的按键对应的 Unicode 字符。public String getKeyText():返回引发事件的按键的文本内容,如“F3”、“Home”、“A”等。与 KeyEvent 事件对应的监听者接口是 KeyListener,该接口的 3 个方法是:public void keyPressed(KeyEvent e);public void keyReleased(KeyEvent e);public void keyTyped(KeyEvent e);,画布(Canvas)-用来画图的矩形背景组件。(1)创建 Canvas myCanvas=new Canvas();myCanvas.setSize(400,300);(2)常用方法 public void paint(Grapics g):用户须覆盖该方法以实现图形绘制。(3)产生事件 可引发键盘和鼠标事件。例 7-14 TestCanvas.java 程序中使用了事件裁剪类 MouseAdapter 和 MouseMotionAdapter。使用事件裁剪类 作为父类的目的是不用实现对应监听者接口包含的所有方法。因为事件裁剪类已经用空方法体实现了对应监听者的所有方法(见 p224)。,public void paint(Graphics g)g.drawString(您在(+X+,+Y+)至+(+endX+,+endY+)画了一条线,10,20);g.drawLine(X,Y,endX,endY);void this_mousePressed(MouseEvent e)X=e.getX();Y=e.getY();showStatus(您在(+X+,+Y+)开始画线);void this_mouseReleased(MouseEvent e)endX=e.getX();endY=e.getY();showStatus(画线结束);repaint();,7.10 布局设计,组件在容器中的位置和尺寸都是由布局管理器来决定的。取消布局管理器:setLayout(null);默认布局管理器:Window,Frame和Dialog的默认布局管理器是BorderLayout。Panel和Applet的默认布局管理器是FlowLayout。,布局管理器,共5种:FlowLayout:流式边界管理器BorderLayout:边界边界管理器GridLayout:网格布局管理器CardLayout:卡片布局管理器GridBagLayout:网格包布局管理器,7.10.1 FlowLayout,FlowLayout:组件按加入顺序自左至右排列,一行排满,转下一行。特征:不限制组件的大小,允许它们有自己的最佳大小。当容器被缩放时,组件的位置可能会变化,但组件的大小不变。例子:MyFlow.java,7.10.2 BorderLayout 把容器空间划分为东、西、男、北、中五个区域。加入组件时,应指明所加区域。例 7-17TestBorderLayout.java,7.10.3 CardLayout 可在容器中加入多个组件,但各组件相互重叠,每次只能显示其中一个。使用 CardLayout 的一般步骤:(1)创建 CardLayout 对象:card=new CardLayout();(2)用容器的 setLayout()方法设置布局管理器:setLayout(card);(3)为组件分配一个字符串名,并加入组件:add(字符串名,组件);(4)调用 CardLayout 的 show()方法,根据字符串名显示组件:show(容器名,字符串),或按加入顺序显示组件,如 first(容器名)、last(容器名)、next(容器名)、previouse(容器名)等。例 7-18TestCardLayout.java,7.10.4 GridLayout 将容器空间划分为 m*n 的网格区域,并将组件加入到各网格中。步骤:(1)创建 GridLayout 对象,指定网格的行数和列数。并用 setLayout()为容器设置布局管理器:setLayout(new GridLayout(行数,列数);(2)调用 add()方法依次将各组件加入容器。如希望某一网格为空白,可在该处加入一个空标签:add(new Label();例 7-19TestGridLayout.java,有时需要结合几种布局:如计算器的界面可以用BorderLayout和GridLayout结合起来。,创建面板及复杂布局,7.14 Swing GUI 组件,在java.awt包中,有各种组件,如Frame,Panel,Button,TextField等。AWT组件的优点是简单、稳定,兼容于任何一个JDK版本,缺点是依赖本地操作系统的GUI,缺乏平台的独立性。为实现跨平台,即在不同的操作系统中保持相同的外观,从JDK1.2开始引入Swing组件,位于javax.swing包中。独立于本地平台的Swing组件称为轻量级组件,而依赖于本地平台的AWT组件称为重量级组件。,JFrame,与Frame不同点:不能用add()加入组件,也不能用setLayout()设置布局。每个JFrame都有一个与之关联的contentPane,只能针对这个contentPane设置布局,以及加入组件。例:JFrame jf=new JFrame(“Hello”);Container cp=jf.getContentPane();cp.setLayout(new GridLayout(2,1);cp.add(jLabel);cp.add(jButton);例:2007ch8SimpleSwingDemo.java,8.3.1 JApplet JApplet 类是 Applet 类的子类。特点:1)缺省布局策略为 BorderLayout;2)必须先使用 getContentPane()方法获得一个Container 对象,再调用该对象的 add()方法将各“J 组件”加入。用法同JFrame。例 8-5 TestJApplet.java,8.3.2 JButton创建图标按钮 Jbutton 对象除了拥有文本标签外,还可以拥有图标。图标可以是用户绘制的图形,也可以是 gif 图像。图标按钮的创建方式如下:Icon icon=new ImageIcon(“bIcon.gif”);/创建图标 jbtn=new Jbutton(“J 按钮”,icon);/创建图标按钮例 8-6 TestIconButton.java改变按钮图标 Jbutton 按钮可以拥有多个图标。利用 Jbutton 类的 setPressedIcon(Icon ic)和 setRolloverIcon(Icon ic)方法,可设定不同状态下的图标,并可根据按钮所处的状态自动变换。例 8-7 TestChangedIcon.java为按钮加入提示利用 Jbutton 类的 setToolTipText(String text)方法可为按钮加入提示例 8-8 TestTipButton.java,8.3.3 JSliderJSlider 也是辅助用户输入连续变化数值的 GUI 组件,并具有刻度和标注功能。例 8-9 TestJSlider.java8.3.4*JPasswordField JPassWordField 类是 JTextField 类的子类,主要用来输入口令。例 8-10TestJPasswordField.java8.3.5 JTabbedPane 这是一个容器。其作用类似于 CardLayout 布局。例 8-11 UseTabbedPane.java,