510 likes | 769 Views
4. Java 的图形用户界面. 清华大学计算中心 2000,4. 主要内容. Java 的 GUI 简介 自定义图形设计 图形、文字、图象 Java 的标准组件 容器和组件 GUI 的布局 Java1.1 事件处理. 图形用户界面( GUI). 字符界面 用字符串、命令行的方式与用户交互 图形用户界面: Graphics User Interface 用直观的图形来表示数据 用直观、方便的 GUI 标准组件来接收命令 GUI 组成成分的标准化 Java 的图形用户界面编程: java.awt 包. 图形用户界面简介. 图形用户界面的构成
E N D
4 Java的图形用户界面 清华大学计算中心 2000,4
主要内容 • Java的GUI简介 • 自定义图形设计 • 图形、文字、图象 • Java的标准组件 • 容器和组件 • GUI的布局 • Java1.1事件处理 Java的图形用户界面
图形用户界面(GUI) • 字符界面 • 用字符串、命令行的方式与用户交互 • 图形用户界面:Graphics User Interface • 用直观的图形来表示数据 • 用直观、方便的GUI标准组件来接收命令 • GUI组成成分的标准化 • Java的图形用户界面编程: • java.awt包 Java的图形用户界面
图形用户界面简介 • 图形用户界面的构成 • 容器:布局、安排 • 标准组件 • 用户自定义成分 • 设计&实现图形用户界面的工作 • 创建GUI各组成成分,并安排从属位置关系 • 定义GUI各成分对不同事件的响应,实现与用户的交互功能 Java的图形用户界面
AWT包 • GUI的组成 • 用户自定义成分 • GUI标准组件、事件处理 • Abstract Windows Toolkit • 提供各种构成GUI的标准构件 • 抽象:抽取不同软硬件平台中所实现的窗口的公共特性,针对一个只具有上述公共特性的虚窗口操作 • 依赖于具体平台系统实现:显示效果可能不同 Java的图形用户界面
从一个简单窗口开始 • 创建GUI应用程序 • Frame必不可少 • 先来建一个空的窗口应用:Empty.java • 注意:一定要处理关闭窗口的事件 Java的图形用户界面
import java.awt.*; //must import to use GUI //must extends Frame in an application public class Empty extends Frame{ //暂时采用1.0.2的事件处理方法,关闭窗口 public boolean handleEvent(Event evt){ if(evt.id==Event.WINDOW_DESTROY) System.exit(0); return super.handleEvent(evt); } public static void main(String[] args){ Frame f=new Empty(); f.setSize(300,200); f.setVisible(true); } } Java的图形用户界面
绘制用户自定义成分 • 用户自定义成分属于构成GUI的非标准部分 • 无法响应用户事件 • 一般仅仅起背景装饰、输出效果突出的作用 • Java中的用户自定义成分 • 显示文字 • 绘制图形 • 显示图片 Java的图形用户界面
原点(0,0) X轴 Y轴 绘制用户自定义成分(续) • 使用awt包中的Graphics类的相关方法 • 获得Graphics类的实例:画到哪里 • 使用paint(Graphics g)方法 • Java程序图形界面的坐标设置 Java的图形用户界面
显示文字 • 字体显示效果类:Font Font mf = new Font(String 字体,int 风格,int 字号); • 字体:TimesRoman, Courier, Arial等 • 风格:三个常量 • Font.PLAIN, Font.BOLD, Font.ITALIC • 字号:字的大小(磅数) • 设置当前使用的字体:setFont(Font fn) • 获取当前使用的字体:getFont() • 例:UseFonts.java Java的图形用户界面
String FontName[] = {"TimesRoman","Courier","Arial"}; int FontStyle[] = {Font.PLAIN, Font. BOLD, Font.ITALIC}; String StyleName[] = { "PLAIN", "BOLD", "ITALIC" }; public void paint( Graphics g) { for ( int i=0; i<3; i++) { for ( int j=0; j<3; j++) { //set a new font and draw a string with the new font g.setFont(new Font(FontName[i], FontStyle[j], 12)); g.drawString( "ABEXYZ " + FontName[i] + " " + StyleName[j], 10,20*(i*3+j+2)); } } }//end of paint Java的图形用户界面
绘制图形及其相关方法 • 从(x1,y1)到(x2,y2)画直线 • drawLine(x1,y1,x2,y2) 均为int • 以(x,y)为左上角、w为宽度、h为高度画矩形 • drawRect(x,y,w,h) 均为int • fillRect()、clearRect() Java的图形用户界面
绘制图形及相关方法(续) • 画圆或椭圆 • drawOval(x,y,w,h) • x,y,w,h确定了圆或椭圆的矩形范围 • 画实心圆或椭圆 • fillOval(x,y,w,h) • 画多边形 • drawPolygon(X坐标数组,Y坐标数组,个数) Java的图形用户界面
绘制图形及相关方法(续) 例子: sanmao.java Java的图形用户界面
//画头部,椭圆方法drawOval g.setColor(Color.black); //setColor用来设置要使用的颜色 g.drawOval(40,40,120,150); ……... //画头发,直线方法drawLine,画弧方法drawArc g.drawLine(100,10,100,60); g.drawArc(110,20,100,80,90,90); ……... //画嘴巴,填充画弧方法fillArc g.fillArc(60,130,80,40,180,180); ……... //画耳朵,填充椭圆方法fillOval,复制图形方法copyArea g.fillOval(25,92,15,30); g.copyArea(25,92,15,30,136,0); //拷贝某区域的图形至另一区域 ……... //画身体,多边形方法fillPolygon g.fillPolygon(polygon_x,polygon_y,polygon_pt_num); Java的图形用户界面
编程控制 repaint() 调用 update() 2. 调用paint() paint( ) 第一次绘制 当某些操作破坏了显示,需重新绘制时 paint()与update() • 某组件的paint()和update()为系统自动调用的有关图形绘制的方法,不可人为编程调用;但可编程重新定义其操作内容 • 使用repaint()方法可以触发update()方法 1. 擦除并填充成背景色 Java的图形用户界面
显示图象 • 图形与图象,java支持gif和jpeg格式 • 保存二进制图象的java.awt.Image类 • 获取Image对象的方法 getImage(图象文件所在的URL) getImage(图象文件所在的URL,图象文件名) • Applet类以及java.awt.Toolkit中均有方法的定义 • 注意:在application中只能使用Toolkit,而在Applet中,两者均可使用 Java的图形用户界面
显示图象(续) • 显示图象的方法 drawImage(Image对象,x,y,背景色, ImageObserver); • java.awt.Graphics类中定义了此方法 • ImageObserver为一个接口,java的组件类实现了此接口,此处可理解为观察/显示Image对象容器,编程时一般可使用this • 表示颜色的类Color:含有各种颜色常量 • Color(red,green,blue)来创建非缺省色 • 例:DrawMyImage.java Java的图形用户界面
public class DrawMyImage extends Frame { //获得Toolkit实例的方法getDefaultToolkit() Toolkit toolkit=Toolkit.getDefaultToolkit(); Image myImage ; public DrawMyImage() { //获得Image对象, 图象文件在当前目录下时 myImage = toolkit.getImage("Invntory.gif"); } //在paint方法中绘制图象 public void paint(Graphics g) { g.drawImage(myImage, 0, 40, Color.orange, this ); } …………….. } Java的图形用户界面
显示图象(续) • 深入使用 • MediaTracker的使用 • addImage()、 waitForAll/ID() • 动画消除闪烁 • 重写(覆盖)update方法 • 利用双缓冲 • 动画要用到多线程技术 Java的图形用户界面
课下练习(一) • 修改第三讲中多态例子程序Shapes.java,在draw()方法中真正实现画园、正方形、和三角形的功能,erase()实现擦除。随机画出10个颜色和形状均不同的图形,并用文字在各图形上方注明图形性质。 • 显示一幅图片。 注:以上两题使用Application实现,上交时请上交源文件和可以正确执行的类文件。 Java的图形用户界面
GUI标准组件 • Component:大部分组件类的祖先(除菜单) • 显示功能:paint(), update(), repaint() • 显示效果控制:字体、颜色、位置、尺寸 • 图象处理:一般利用Canvas和Container来显示图像 • 事件处理机制(java 1.1): • addXXXListener( ) • removeXXXListener( ) Java的图形用户界面
GUI标准组件(续) • 简单构件:人机交互的基本工具(控制) • Button,Checkbox, Label等 • TextComponent(TextArea,TextField) • Canvas • 复杂构件: • Container(安放排列其他构件的容器) • Panel • Window Java的图形用户界面
Component Button TextComponent MenuComponent Checkbox Container TextArea MenuItem MenuBar TextField Panel Window Menu Applet Frame Dialog AWT构件层次关系图 Java的图形用户界面
GUI基本组件类(一) • Checkbox(检测盒) • 创建时指定检测盒的标签 • Checkbox cb = new Checkbox(“registered”, true); • 获取和设置检测盒的状态 • cb.setState(true);boolean b=cb.getState(); • CheckboxGroup(单选按钮组) • 单选按钮组是一组Checkbox的集合 • 首先创建CheckboxGroup,再加入单个按钮 • 例:new Checkbox(“male”, 组名, false); Java的图形用户界面
GUI基本组件类(二) • List(列表) • 首先创建List对象,再调用add ()方法加入List列表的各选项 List list1 = new List(0,false); list1.add (“class A”); list1.add (“class B”); list1.add (“class C”); • 构造函数的参数:(显示项数,是否复选) Java的图形用户界面
GUI基本组件类(三) • TextArea (String, int, int) • TextArea ta1 = new TestArea(10,45); • 建10行、45列的文本区域 • TextField (String, int) • TextField tf1 = new TextField(30); • 接受用户的输入:ta1.getText()返回String • 设置文本区域的显示:ta1.setText(“O”) Java的图形用户界面
GUI基本组件类(四) • Label(标签) • Label myl = new Label(“标签内容”); • 设置标签内容:myl.setText(“新内容”); • Button(按钮) • Button myB = new Button(“Cancel”); Java的图形用户界面
Container(容器) • 排列其中包容的构件 • 定位布局策略 set/getLayout() • 包容其他基本构件 • 增加构件: add( ) • 删除构件: remove( ) • 控制是否显示容器及其中组件 • setVisible(true/false) • setVisible()为Component的方法 Java的图形用户界面
Container(容器)(续) • Panel(面板) • Applet类 • Window:无边框、菜单的空白窗口 • Frame:用于Application 含边框、菜单的 独立窗口,与 Applet平级 • Dialog 依赖于 Frame的非 独立窗口 Java的图形用户界面
布局管理 • 布局管理器 • 用于控制组件在容器中的布局 • 种类: • FlowLayout: 组件在一行中从左至右水平排列,排满后折行 • BorderLayout:北、南、东、西、中 • CardLayout:每一个组件作为一个卡片,容器仅显示多个卡片中的某一个 Java的图形用户界面
布局管理(续) • GridLayout:以行和列的网格形式安排组件 • GridBagLayout:使用复杂、功能灵活 • 缺省的布局管理器 • FlowLayout:缺省的Panel布局管器 • BorderLayout:缺省的窗口容器的管理器 • 改变缺省布局管理器的方法; 例:BorderLayout B=new BorderLayout(); C1.setLayout(B); C1.setLayout(new BorderLayout()); Java的图形用户界面
利用AWT创建自己的GUI • GUI外观设计 • 设计标准构件层次关系:构件层次结构关系树 • 设置容器布局策略:setLayout() • 生成标准构件 • 向容器中添加组成构件:add()方法 • 构件事件处理 • 例:AWTComponent.java Java的图形用户界面
public class AWTComponent extends Frame { ... ... ... public AWTComponent() { setSize(450,300); //设置Frame大小 setLayout(new FlowLayout());//设置布局 ... ... ... //创建组件 Group1 = new CheckboxGroup(); radioButton1 = new Checkbox("male", Group1, false); add(radioButton1); //把组件加入容器 radioButton2 = new Checkbox("female", Group1, false); add(radioButton2); ... ... ... setVisible(true); //显示容器及组件 } ... ... ... } 还缺什么吗? Java的图形用户界面
Java1.0.2的事件处理 • 使用单一的java.awt.Event类来接受所有类型的事件; • 使用action(), handleEvent( )以及其他的一些事件处理方法(如鼠标事件、键盘事件、焦点事件)来进行相应事件的事件处理。 • 缺点:造成长if分支语句组,不利于面向对象的编程 Java的图形用户界面
Java1.1 UI的改进 • 引入java.awt.event包 • 更加面向对象,易于理解 • 定义了事件的“发生者”和“监听者”对象 • 事件以类层次来表达,取代了1.0.2中的单一的类,并可以自定义事件类型 Java的图形用户界面
事件监听者 点击, ActionListener Button 1 触发ActionEvent e 接收事件e,并做处理 事件发生者 事件处理机制 • 组件(事件发生者)触发一个相应类型的事件 • 此事件由相应类型的Listener(事件监听者)接收并处理 Java的图形用户界面
几个有用的概念 • 事件 - 在java.awt.event包中定义了若干类型的事件类 • 监听者接口 - 特定类型的Listener接口,用于监听特定类型的事件 • 监听者类 - 是实现了某种监听者接口的类,由编程者定义 • 事件监听者 - 是某个监听者类的对象,由编程者使用new创建 Java的图形用户界面
实现步骤 • 根据需要定义相应类型的监听者类,在类的定义中完成事件的处理(建议使用inner class定义); • 创建事件监听者对象; • 为将会触发事件的组件C注册相应的事件监听者对象(使用C的addXXXListener()方法)。 • 举例:ButtonAct.java Java的图形用户界面
public class ButtonAct extends Frame { ... ... ... public ButtonAct() { ... ... ... //为b1注册事件监听者B1 b1.addActionListener(new B1()); add(b1); ... ... ... } //利用inner class结构定义监听者类 class B1 implements ActionListener { //利用actionPerformed方法进行事件处理 public void actionPerformed(ActionEvent e){ who.setText("Button 1"); } } ... ... ... } ///:~ Java的图形用户界面
事件与监听者类型 • XXXListener接口与XXXEvent • XXX为特定类型 • 常用类型: Action, Focus,Key, Window, MouseEvent vs. Mouse/MouseMotionListener • 注册与取消:组件包含的新方法addXXXListener()与removeXXXListener() • 参考:eventtables.html Java的图形用户界面
监听者接口中有什么? • 每种Listener接口均定义了一套abstract方法,编程者必须在监听者类中实现这些方法来做事件处理; • 例: ActionListener actionPerformed() WindowListener windowOpened/Closing/Closed/Activated/Deactivated/Iconified/Deiconified() Java的图形用户界面
使用Listener Adapter • 由于接口中的方法为abstract方法,所以在监听者类中要实现所有的方法,较为烦琐。 • 为了简化编程,引入了Adapter。具有两个以上方法的监听者接口均对应一个XXXAdapter类,提供了接口中每个方法的缺省实现。 Java的图形用户界面
使用Listener Adapter(续) • 例: class MyWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } • 例:DoubleClick.java(相应鼠标事件) • 参考:Listener.html Java的图形用户界面
public class DoubleClick extends Frame { Vector m_vLocs; //保存鼠标单击过的各点, 用以绘制各点连线 Point m_CursorLoc; //跟踪当前鼠标位置, 用以绘制十字光标 public DoubleClick() { m_vLocs = new Vector(); m_CursorLoc = new Point(100,100); setSize(400, 400); //为Frame注册3个事件监听者 addMouseListener(new click()); addMouseMotionListener(new move()); addWindowListener(new wd()); } public void paint(Graphics g) {… //绘制十字光标, 连接各点 } Java的图形用户界面
class click extends MouseAdapter { //鼠标事件监听者类 public void mouseClicked(MouseEvent e) {//响应点击 if(e.getClickCount()>1) //双击时清除向量中各点 m_vLocs.removeAllElements(); else //单击时在向量中增加一点 m_vLocs.addElement(e.getPoint()); repaint(); //重新绘制一次 } } class move extends MouseMotionAdapter{//鼠标移动监听者类 public void mouseMoved(MouseEvent e) {//响应移动 m_CursorLoc = new Point(e.getX(),e.getY()); repaint(); //重新绘制一次 } } … … … … } Java的图形用户界面
Component Button TextComponent MenuComponent Checkbox Container TextArea MenuItem MenuBar TextField Panel Window Menu Applet Frame Dialog AWT构件层次关系图 Java的图形用户界面
菜单 • 菜单须依附于一个实现了MenuContainer接口的对象:Frame, MenuBar, Menu • 构建菜单结构:创建菜单的步骤 • 创建菜单条(MenuBar) • 创建菜单(Menu),加入相应菜单条 • 创建菜单项(MenuItem),加入相应菜单 • 使菜单条依附于拥有它的对象:setMenuBar() • 编写响应菜单操作的代码(ActionEvent) • 例:MenuFrame.java Java的图形用户界面
class MenuFrame extends Frame { Label lb=new Label(“here comes command”);//模拟菜单命令 MenuBar m_MenuBar=new MenuBar(); //创建菜单条 Menu menuFile = new Menu(“File”); //创建菜单 MenuItem[] file={new MenuItem(“Open”), //创建各菜单项 new MenuItem("Close"), new MenuItem("Exit") }; MenuFrame() { m_MenuBar.add(menuFile); //把菜单加入菜单条 menuFile.add(file[0]); //把各菜单项加入菜单 menuFile.add(file[1]); menuFile.add(file[2]); setMenuBar(m_MenuBar); //把菜单条加入Frame Java的图形用户界面
setLayout(new FlowLayout()); add(lb); //加入Label, 用于输出菜单项命令 ActionListener ml=new ML(); for(int i=0;i<3;i++){ //为每个菜单项注册监听者 file[i].addActionListener(ml); //此例多个菜单项 } //对应一个监听者, 但实际编程时建议使用一对一结构 addWindowListener(new WL()); } class ML implements ActionListener { //Action事件监听者类 public void actionPerformed(ActionEvent e) { lb.setText(e.getActionCommand()); //输出菜单命令 } } … … … … } Java的图形用户界面