480 likes | 687 Views
第三部分 Java 语言编程应用篇. 第 6 章 Java 语言的 图形用户界面开发技术. (之一). 学习目的. 通过案例学习,理解组件、容器、布局管理器、事件源、事件、事件处理者等基本概念; 用抽象窗口工具包 AWT 和 Swing 包中来开发图形用户界面; 领悟事件处理机制,使程序能够与用户交互; 学会利用布局管理器管理来管理组件的布局; 掌握 AWT 包和 Swing 包中各容器和组件的用法; 了解 Java Applet 程序和 Java Application 应用程序创建图形用户界面的原理、联系及区别。. 主要内容.
E N D
第三部分Java语言编程应用篇 第6章 Java语言的 图形用户界面开发技术 (之一)
学习目的 • 通过案例学习,理解组件、容器、布局管理器、事件源、事件、事件处理者等基本概念; • 用抽象窗口工具包AWT和Swing包中来开发图形用户界面; • 领悟事件处理机制,使程序能够与用户交互; • 学会利用布局管理器管理来管理组件的布局; • 掌握AWT包和Swing包中各容器和组件的用法; • 了解Java Applet程序和Java Application应用程序创建图形用户界面的原理、联系及区别。
主要内容 • 应用AWT组件开发图形用户界面程序 • Java事件处理 • 图形用户界面AWT组件学习 • 应用Swing组件开发图形用户界面 • Applet应用程序与图形用户界面介绍
6.1 应用AWT组件开发图形用户界面程序 • 应用程序的图形用户界面设计在实际项目开发中具有重要作用,对用户来说比较友好,方便用户的操作,是程序设计者追求的目标,Java语言在开发图形用户界面方面具有独特优势,可以实现不同平台的一致性。
AWT支持图形用户界面编程的功能 • 抽象窗口工具包AWT(Abstract Window Toolkit) • 图形用户界面工具集GUI(Graphics User Interface) • AWT支持图形用户界面编程的功能: 用户界面组件; 事件处理模型; 图形和图像工具,包括形状、颜色和字体类; 布局管理器; 数据传送类。
【综合案例6-1 】 • 程序执行后结果如图。用户登录界面设计
程序代码 import java.awt.*; public class TestAWT1{ public static void main(String [] args){ Frame f=new Frame("用户登录"); TextField name=new TextField(20); TextField pw=new TextField(20); Label la1=new Label("用户名"); Label la2=new Label("密 码"); Button btn1 = new Button("确定"); Button btn2 = new Button("退出"); pw.setEchoChar('*'); f.setLayout(new FlowLayout()); f.add(la1); f.add(name); f.add(la2); f.add(pw); f.add(btn1); f.add(btn2); f.setSize(250,130); f.setVisible(true); } } Windows类_Frame子类_装载组件文本框、标签和按钮。 add(添加文本、标签、按钮组件到容器对象f。)
开发图形用户界面程序一般步骤 • 创建某组件的对象,设置对象属性,调用容器的add( )方法向容器中添加该组件对象。 • 使用某种布局策略,指定该基本组件对象在容器中的位置。Java中的布局管理器负责确定其容器中每个子组件的大小和布局策略。 • 将组件注册给它所能产生的事件对应的事件监听者,重载事件处理方法实现该组件对象与用户交互的功能。
6.1.1 容器的使用 • 容器是用来存放和组织其他组件的组件。 • 容器java.awt.Container是Component的子类,一个容器可以容纳多个组件,并使它们成为一个整体。容器可以简化图形化界面的设计,以整体结构来布置界面。所有的容器都可以通过add()方法向容器中添加组件。
AWTEvent Applet Font类 Panel Container类 Componet类 Scrollpane java.lang.Object Frame Window Graphics类 MenuComponent类 布局管理器类 容器之间的继承关系
Frame类的容器 • Frame类用来建立标准的窗口组件,是编写Java程序时不可缺少的类。 • Frame是Window的一个子类。它是带有标题和缩放角的窗口。 • Frame继承于Java.awt.Container,可以用add()方式来给框架添加组件。 • 框架的缺省布局管理器就是BorderLayout;它可以用setLayout()方式来改变,并且在里面加入各种可视组件。 • Frame是带标题的窗口。
6.1.2 标签、文本域、按钮组件的使用 • 基本组件是图形用户界面的最小单位之一,它里面不再包含其他的成分。 • 基本组件的作用是完成与用户的一次交互,包括接收用户的一个命令、一项选择、显示一段文字等。 • 常用的基本组件有: 复选框(Checkbox) 单选按钮(CheckboxGroup) 下拉列表(List或Choice) 标签(Label) 文本编辑区(TextField或TextArea) 按钮(Button) 菜单(Menu)等。
标签(Label) 一个标签对象显示一行静态文本。程序可以改变文本,但用户不能改变。标签没有任何特殊的边框和装饰,标签通常不处理事件。 • 文本域(Textfield) TextField组件可以用来显示一行文字,并且允许在上面编辑,它是图形用户界面经常使用的组件。因为只允许有一行,所以当按下Enter或Return键时,ActionListener可以通过actionPerformed()知道这个事件。除了注册一个ActionListener,你还可以注册一个TextListener来接收关于个别击键的通知。 • 按钮(Button) Button组件是图形用户界面设计经常用到的组件,这个组件提供了“按下并动作”的基本操作。可以构造一个带文本标签的按钮,用来告诉用户它的作用。
6.2 Java事件处理 • 【综合案例6-1 】中当用鼠标单击确定按钮时并没有响应,另外当单击关闭窗口按钮时并不能关闭窗口,这是为什么? • 主要是没有给窗口和按钮组件添加响应代码的缘故,在Java应用程序中我们称之为事件处理机制。
【综合案例6-2】 • 添加事件处理机制的应用程序用户登录界面程序设计,程序执行结果如下图所示。
程序代码 import java.awt.*; import java.awt.event.*; public class TestAWTNew2 implements ActionListener{ static TextField name=new TextField(20); static TextField pw=new TextField(20); static Label la1=new Label("用户名"); static Label la2=new Label("密 码"); static Label la3=new Label(); static Button btn1 = new Button("确定"); static Button btn2 = new Button("退出"); static Frame f=new Frame("用户登录");
public static void main(String [] args) { f.setLayout(new FlowLayout()); pw.setEchoChar('*'); f.add(la1); f.add(name); f.add(la2); f.add(pw); f.add(btn1); f.add(btn2); f.add(la3); f.setSize(250,140); f.setVisible(true); f.addWindowListener(new MyWindowListener()); btn1. addActionListener(new TestAWTNew2()); btn2. addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { f.setVisible(false); f.dispose(); System.exit(0); }}); }
public void actionPerformed(ActionEvent e) { if (pw.getText().trim().equals("123456")) la3.setText("你输入的密码已经通过验证"); else la3.setText("你输入的密码没有通过验证"); } } class MyWindowListener implements WindowListener { public void windowClosing(WindowEvent e) { e.getWindow().setVisible(false); ((Window)e.getComponent()).dispose(); System.exit(0);} public void windowActivated(WindowEvent e){} public void windowClosed(WindowEvent e){} public void windowDeactivated(WindowEvent e){} public void windowDeiconified(WindowEvent e){} public void windowIconified(WindowEvent e){} public void windowOpened(WindowEvent e){} }
6.2.1 Java事件处理机制 • 在Java应用程序中,组件的事件处理机制涉及以下三个内容: 事件源: 能够接收外部事件的载体,通常就是各个组件,例如按钮Button。 事件监听器: 能够接收事件源通知的对象。 事件处理程序: 用于接收事件对象并对其进行处理的对象。
Java事件编程一般步骤 • 第一步:程序开始装载事件包; • 第二步:实现事件监听者所对应的接口,有三种方法可以实现接口类: (1)组件所在类本身作为事件监听类 (2)用外部类作为专门的事件监听类 (3)用匿名内部类作为事件监听类 • 第三步:对事件源,即组件添加事件监听者,事件源实例化以后,必须进行授权,注册该类事件的监听器,通常用addXXXListener(XXXListener)方法来注册监听器; • 第四步,重写相应事件接口类中的方法。
6.2.2 常用事件及适配器介绍 (AWT事件及其相应的监听器接口 )
java.util.EventObject类是所有事件对象的基础父类,所有事件都是由它派生出来的。java.util.EventObject类是所有事件对象的基础父类,所有事件都是由它派生出来的。 • AWT的相关事件继承于java.awt.AWTEvent类。 • AWT事件分为两大类:低级事件和高级事件。
低级事件 • 是指基于组件和容器的事件,当一个组件上发生事件,如:鼠标的进入,点击,拖放等,或组件的窗口开关等,触发了组件事件。 常见低级事件: ComponentEvent(组件事件) ContainerEvent(容器事件) WindowEvent(窗口事件) FocusEvent(焦点事件) KeyEvent(键盘事件) MouseEvent(鼠标事件)。
高级事件 • 是基于语义的事件,它可以不和特定的动作相关联,而依赖于触发此事件的类,如在TextField中按Enter键会触发ActionEvent事件,滑动滚动条会触发AdjustmentEvent事件,或是选中项目列表的某一条就会触发ItemEvent事件。 常见高级事件: ActionEvent(动作事件) ItemEvent(选项事件) KeyEvent(按键事件) TextEvent(文字事件) WindowsEvent(窗口事件)
类的适配器 • 对于表中事件接口类中包含的方法超过二个及以上事件类,Java语言提供了相应类的适配器XXXAdapter,与上表相对应,java.awt.event包中定义的事件适配器类包括以下几个: ComponentAdapter( 组件适配器) ContainerAdapter( 容器适配器) FocusAdapter( 焦点适配器) KeyAdapter( 键盘适配器) MouseAdapter( 鼠标适配器) MouseMotionAdapter( 鼠标运动适配器) WindowAdapter( 窗口适配器)
6.3 图形用户界面AWT组件学习 • 复选框、单选框、按钮组、文本区域、面板、布局管理器组件的使用 • 下拉列表、列表、滚动面板、以及对话框组件的使用 • 菜单条、菜单、菜单项组件的使用 • AWT组件与监听器的对应关系
6.3.1 复选框、单选框、按钮组、文本 区域、面板、布局管理器组件的使用 • 复选框(Checkbox) Checkbox组件提供一种简单的“开/关”输入设备,它旁边有一个文本标 • 单选框组(CheckboxGroup) 单选框组提供了将多个复选框作为互斥的一个集合的方法,因此在任何时刻,这个集合中只有一个单选框的值是true。值为true的单选框就是当前被选中的复选框。
文本区(TextArea) TextArea 对象是显示文本的多行区域。可以将它设置为允许编辑或只读,可以把它看成是多行的TextField组件。 • Panel容器组件 Panel类是一个很简单的容器,象Frame一样,Panel提供空间,在这个空间中可以添加任何的GUI组件,包括其它的Panel。
布局管理器 布局管理器负责决定容器组件内所有其他组件的位置和大小。setLayout()用来指定要被使用的布局管理器。 (1)FlowLayout(顺序布局管理器) FlowLayout是按行来放置Component的,每当一行放满后,就新产生一行开始放。是Panel和Applet类缺省的布局管理器。 (2)BorderLayout(边界布局管理器) BorderLayout设置容器中的组件五个区域:南、北、东、西和中间区域。每个区域最多只能包含一个组件,该边界布局管理器是Window和Dialog缺省的布局管理器。 (3)GridLayout Manager(网格布局管理器) 提供了放置component的灵活手段。建立一个有多行和多列的布局管理器,然后component就可以按一定的次序(从左到右,从上到下)进行排列。
(4)CardLayout Manager(卡片布局管理器) CardLayout 对象是容器的布局管理器。它将容器中的每个组件看作一张卡片。一次只能看到一张卡片,而容器充当卡片的堆栈。当容器第一次显示时,第一个添加到 CardLayout 对象的组件为可见组件。 (5)网格包型(GridBagLayout)布局管理器 该布局管理器是AWT提供的最灵活,最复杂,最常用的布局管理器之一,类似于网格布局,但它允许你把组件放在网格中任何行或列,也允许你的组件跨多行或多列。它是通过设置GridBagConstraints对象中的变量来约束组件布局的。 (6)自定义布局管理器 自定义布局(null)管理器是通过组件本身的setBounds()方法来设置组件在容器中的位置,是比较常用的一种布局管理器,相对于网格包型布局管理器而言,还是非常简单的,只不过需要计算每个组件大小以及容器位置。
【综合案例6-3】 • 编写程序实现如下面四幅图的图形用户界面程序,当单击复选框和单选框时,在文本显示区域将显示所单击的对象。
import java.awt.*; import java.awt.event.*; public class TestCheckNew3 extends Frame{ Label lb = new Label(“文本显示区域”); //创建标签对象 TextAreata1=new TextArea(“显示选择的项目”,2,18); //创建文本区域对象 Checkbox ck1=new Checkbox("红色",true); //创建复选框对象 Checkbox ck2=new Checkbox("黄色",false); //创建复选框对象 Checkbox ck3=new Checkbox(“绿色”,true); //创建复选框对象 CheckboxGroup cg=new CheckboxGroup(); //创建单选框组对象 Checkbox ck4=new Checkbox("钢笔",true,cg); //创建单选框对象 Checkbox ck5=new Checkbox("水笔",false,cg); //创建单选框对象 Checkbox ck6=new Checkbox(“铅笔”,false,cg); //创建单选框对象 Panel p1 = new Panel(); //创建面板容器对象p1 Panel p2 = new Panel(); //创建面板容器对象p2
public TestCheckNew3(){ super("图形界面组件学习"); p1.setLayout(new FlowLayout()); //为p1设置流水线布局管理 p1.add(lb); //添加组件lb到p1 p1.add(ta1); //添加组件ta1到p1 p2.setLayout(new GridLayout(2,3)); //为p2设置表格布局管理 p2.add(ck1); p2.add(ck2); p2.add(ck3); //添加复、单选框组件到p2 p2.add(ck4); p2.add(ck5); p2.add(ck6); add(p1,"Center"); //添加面板p1到当前容器窗口 add(p2,"South"); //添加面板p2到当前容器窗口 setSize(250,130); setVisible(true); //设置窗口尺寸且为可见 setLayout(new BorderLayout()); //设置当前容器窗口布局 addWindowListener(new WindowAdapter(){ //添加窗口关闭事件 public void windowClosing(WindowEvent e){ System.exit(0); } }); ck1.addItemListener(new CheckListener ()); //添加选项事件 ck2.addItemListener(new CheckListener ()); //添加选项事件 ck3.addItemListener(new CheckListener ()); //添加选项事件 ck4.addItemListener(new CheckListener ()); //添加选项事件 ck5.addItemListener(new CheckListener ()); //添加选项事件 ck6.addItemListener(new CheckListener ()); //添加选项事件 }
class CheckListener implements ItemListener{ //选项事件处理方法 public void itemStateChanged(ItemEvent e){ String source=(String)(e.getItem()); if ( source == "红色" ) { if ( e.getStateChange() == e.SELECTED ) ta1.setText("选择的是红色"); else ta1.setText("去掉选择红色"); } else if ( source == "黄色" ) { if ( e.getStateChange() == e.SELECTED ) ta1.setText("选择的是黄色"); else ta1.setText("去掉选择黄色"); } else if ( source == "绿色" ) { if ( e.getStateChange() == e.SELECTED ) ta1.setText("选择的是绿色"); else ta1.setText("去掉选择绿色"); } if ( source == "钢笔" ) { if ( e.getStateChange() == e.SELECTED ) ta1.setText("选择的是钢笔"); } if ( source == "水笔" ) { if ( e.getStateChange() == e.SELECTED ) ta1.setText("选择的是水笔"); } if ( source == "铅笔" ) { if ( e.getStateChange() == e.SELECTED ) ta1.setText("选择的是铅笔"); } } } public static void main(String [] args){ new TestCheckNew3(); } }
6.3.2 下拉列表、列表、滚动面板、 对话框组件的使用 • 下拉列表(Choice) Choice组件,此种下拉列表选项框一次只能显示一个选项,要改变被选中的项目,可单击向下的箭头,从选项中选择一个项目。 • 列表(list) 一个列表将各个文本选项显示在一个区域中,这样就可以在同时看到若干个条目。列表可以滚动,并支持单选和多选两种模式。
滚动面板(ScrollPane) 滚动面板实现用于单个子组件的自动水平和/或 垂直滚动的容器类。 滚动条的显示策略可以有以下三种策略: • as needed创建滚动条,且只在滚动窗格需要时显示; • always创建滚动条,且滚动窗格总是显示滚动条; • never滚动窗格永远不创建或显示滚动条。 • 对话框(Dialog) Dialog组件是一个带标题和边界的顶层窗口,边界一般用于从用户处获得某种形式的输入。
【综合案例6-4】 • 在综合案例1的基础上实现更加复杂和功能更多的用户身份验证图形用户界面。执行结果如图
import java.awt.*; import java.awt.event.*; public class TestUser4 extends Frame implements ActionListener { Label Label1 = new Label("用户ID :"); TextField textfieldialog= new TextField(10); Label Label2 = new Label("用户密码:"); TextField textfield2 = new TextField(10); Label Label5 = new Label("用户地区:" ); Choice choice = new Choice(); Label Label6 = new Label("用户类别:" ); List list = new List(3,false); Button button1 = new Button("确定"); Button button2 = new Button("取消"); Dialog dialog = new Dialog(this,"提示信息",false); ScrollPane sp = new ScrollPane();
public TestUser4(){ super("用户身份验证"); add(Label1); add(textfieldialog); add(Label2); textfield2.setEchoChar('*'); add(textfield2); add(Label5); choice.addItem("广东"); choice.addItem("上海"); choice.addItem("北京"); add(choice); add(Label6); list.add("普通用户"); list.add("高级用户"); list.add("系统管理员"); sp.add(list); add(sp); add(button1); button1.addActionListener(this); add(button2); button2.addActionListener(this); setLayout(new GridLayout(5,2,5,5)); setSize(160, 220); setVisible(true); addWindowListener(new windowclose()); } public class windowclose extends WindowAdapter{ public void windowClosing(WindowEvent e){ System.exit(0); } }
public void actionPerformed(ActionEvent e){ if (e.getActionCommand().equals("确定")){ if (textfield2.getText().trim().equals("123456")){ dialog.setLayout(new FlowLayout(FlowLayout.CENTER)); Label tf = new Label("您已经通过验证,欢迎您!"); dialog.add(tf); dialog.setSize(250,60); dialog.setVisible(true); dialog.addWindowListener(new windowclose()); } else{ dialog.setLayout(new FlowLayout(FlowLayout.CENTER)); Label tf = new Label("对不起,您输入的密码不正确,请重试"); dialog.add(tf); dialog.setSize(250,60); dialog.setVisible(true); dialog.addWindowListener(new windowclose());} } else System.exit(0); } public static void main(String[] args) { new TestUser4(); } }
6.3.3 菜单条、菜单、菜单项组件的使用 • 菜单是非常重要的GUI组件 • 每个菜单组件包括一个 菜单条——MenuBar, • 每个菜单条又包括若干个 菜单项——Menu, • 每个菜单项又包括若干个 菜单子项——MenuItem, • 每个子菜单项的作用与按钮相似, 即用户点击时引发一个动作命令。
菜单条(MenuBar) 一个菜单条组件是一个水平菜单。它只能加入到一个框架中,并成为所有菜单树的根。在一个时刻,一个框架可以显示一个菜单条。然而,你可以根据程序的状态修改菜单条,这样在不同的时刻就可以显示不同的菜单。 • 菜单(Menur) 菜单组件提供了一个基本的下拉式菜单。它可以加入到一个菜单条或者另一个菜单中。 • 菜单项(MenuItem) 菜单项组件是菜单树的文本“叶”结点。它们通常被加入到菜单中,以构成一个完整的菜单。
【综合案例6-5】 • 创建窗口及菜单项,菜单打开和保存响应鼠标单击事件,在标签中显示所单击菜单对象的名称。程序执行结果如下图所示:
import java.awt.*; import java.awt.event.*; public class TestMenu5 implements ActionListener { Label tf1=new Label(); Frame f=new Frame("菜单组件"); MenuBar mb1=new MenuBar(); Menu fi = new Menu("文件"); Menu fi1 = new Menu("编辑"); Menu fi2 = new Menu("视图"); Menu fi3 = new Menu("查看"); Menu fi4 = new Menu("帮助"); MenuItem[] file={new MenuItem("打开", new MenuShortcut(KeyEvent.VK_O)), new MenuItem("保存",new MenuShortcut(KeyEvent.VK_S)), new MenuItem("退出",new MenuShortcut(KeyEvent.VK_E))};
private void TestMenu1() { f.setMenuBar(mb1); mb1.add(fi); mb1.add(fi1); mb1.add(fi2); mb1.add(fi3); mb1.add(fi4); for (int i=0;i<file.length ;i++) { fi.add(file[i]); } file[0].setActionCommand("打开"); file[0].addActionListener(this); file[1].setActionCommand("保存"); file[1].addActionListener(this); file[2].setActionCommand("退出"); file[2].addActionListener(this); f.setLayout(new BorderLayout()); f.add(tf1,BorderLayout.SOUTH); f.setSize(250,200); f.setVisible(true); f.addWindowListener(new MyWindowListener()); } MyWindowListener类与前面综合案例6-2相同,这里不重复打印显示。调试程序时必须添入到程序中。
public void actionPerformed(ActionEvent e){ MenuItem target=(MenuItem)e.getSource(); String ac=target.getActionCommand(); if(ac.equals("打开")) { tf1.setText("你选择的是打开菜单"); } else if(ac.equals("保存")) { tf1.setText("你选择的是保存菜单"); } else if(ac.equals("退出")) { f.setVisible(false); } } public static void main(String [] args){ TestMenu5 menu = new TestMenu5 (); menu.TestMenu1 (); } }
阶段复习要点 • 重点掌握知识内容: • 图形界面设计的基本步骤? ——三步(组件设计、初始化、属性设定等) • 布局管理的种类? ——六种(顺序、边界、网格、卡片、网格包、自定义) • 事件相关信息? ——三个(事件源、事件监听器、事件处理程序) • 常见组件名称、功能、属性设计?