第三部分 Java语言编程应用篇 第6章 Java语言的 图形用户界面开发技术 (之二)
学习目的 通过案例学习,理解组件、容器、布局管理器、事件源、事件、事件处理者等基本概念; 用抽象窗口工具包AWT和Swing包中来开发图形用户界面; 领悟事件处理机制,使程序能够与用户交互; 学会利用布局管理器管理来管理组件的布局; 掌握AWT包和Swing包中各容器和组件的用法; 了解Java Applet程序和Java Application应用程序创建图形用户界面的原理、联系及区别。
主要内容 应用AWT组件开发图形用户界面程序 Java事件处理 图形用户界面AWT组件学习 应用Swing组件开发图形用户界面 Applet应用程序与图形用户界面介绍
6.4 应用Swing组件开发图形用户界面 Swing组件正是从AWT组件基础上发展而来的,AWT是Swing的基础。 Swing组件提供一组“轻量级”组件,由100%纯Java语言实现的。 Swing胜过AWT的主要优势在于MVC体系结构(模型-视图-控制 )的普遍使用。
【综合案例6-6】 创建一个如图6-24所示,用Swing组件实现的图形用户界面,当每次单击按钮时,标签提示已经单击次数。
import java.awt.event.*; public class TestSwingWindow6 extends JFrame implements ActionListener { String title[]={"编 号","姓 名","性 别","出生日期","婚 否","籍 贯","家庭地址","个人简历"}; JTextField txtNo=new JTextField(10); //定义单行文本 JTextField txtName=new JTextField(10); //定义单行文本 JTextField txtBirthDate=new JTextField(8); //定义单行文本 JTextField txtAddress=new JTextField(30); //定义单行文本 JTextArea txtResume=new JTextArea(); //定义文本区 ButtonGroup group=new ButtonGroup(); //定义组 JRadioButton rabSexM=new JRadioButton("男",true); //定义单选钮 JRadioButton rabSexF=new JRadioButton("女",false); //定义单选钮 JCheckBox chbMember=new JCheckBox("",false); //定义复选钮 JComboBox cobSpeciality=new JComboBox(); //定义下拉列表 JButton next=new JButton("添加"); //定义按钮 JButton prev=new JButton("修改"); //定义按钮 JButton first=new JButton("删除"); //定义按钮 JButton last=new JButton("退出"); //定义按钮 JLabel jlbInterest = new JLabel("兴趣爱好"); //定义标签 JList list; //定义列表
JPanel jpanelJLabel = new JPanel(new FlowLayout());//定义面板容器 JPanel jpanelList = new JPanel(); //定义面板容器 JPanel centereast = new JPanel(); //定义面板容器 DefaultListModel listModel=new DefaultListModel(); //创建ListModel对象 public TestSwingWindow6(){ super("客户信息录入窗口"); Container con =this.getContentPane(); //活动容器框架 con.setLayout(new BorderLayout()); //设置边界布局 setSize(450,420); cobSpeciality.addItem("江苏"); //向组合框中添加条目 cobSpeciality.addItem("上海"); //向组合框中添加条目 cobSpeciality.addItem("浙江"); //向组合框中添加条目 cobSpeciality.addItem("北京"); //向组合框中添加条目 cobSpeciality.setSelectedIndex(0); group.add(rabSexM); group.add(rabSexF); //为单选钮分组 listModel.addElement("计算机编程"); //添加列表对象 listModel.addElement("中外小说"); listModel.addElement("外出旅游"); listModel.addElement("电影电视"); listModel.addElement("唱歌跳舞");
list=new JList(listModel); //利用ListModel对象建立列表 list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); //设/置模式为多选 JScrollPane jsp=new JScrollPane(list,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); //为列表添加滚动条,通过建立滚动面版实现 jsp.setPreferredSize(new Dimension(150,80)); //预设大小 jpanelList.add(jsp); //添加滚动面板到面板组件
JPanel p[]=new JPanel[7]; //建立面板数组 for(int i=0;i<7;i++){ p[i]=new JPanel(new FlowLayout(FlowLayout.LEFT)); //建立面板 p[i].add(new JLabel(title[i])); } //建立并添加标签 p[0].add(txtNo); //添加组件到面板 p[1].add(txtName); //添加组件到面板 p[2].add(rabSexM);p[2].add(rabSexF); //添加组件到面板 p[3].add(txtBirthDate); //添加组件到面板 p[4].add(chbMember); //添加组件到面板 p[5].add(cobSpeciality); //添加组件到面板 p[6].add(txtAddress); //添加组件到面板 centereast.setLayout(new BorderLayout()); //设置流式布局 jpanelJLabel.add(jlbInterest); centereast.add(jpanelJLabel,"West"); centereast.add(jpanelList,"Center"); JPanel top=new JPanel(); //建立面板top,用于放置p[0]~p[6] top.setLayout(new GridLayout(7,1)); //面板top设置网格布局 for(int i=0;i<7;i++) //将面板p[0]~p[6]添加到top top.add(p[i]); JPanel center=new JPanel(); //该面板用于放置enterleft,centerright center.setLayout(new BorderLayout()); //设置center为边界布局 JPanel centerleft=new JPanel(new FlowLayout()); //用于放置简历标签 centerleft.add(new JLabel(title[7])); JPanel centerright=new JPanel(); //用于放置简历文本区
JScrollPane jp=new JScrollPane(txtResume,JScrollPane JScrollPane jp=new JScrollPane(txtResume,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); //为文本区添加滚动条,通过建立滚动面版实现 jp.setPreferredSize(new Dimension(150,80)); //预设大小 centerright.add(jp); //将滚动面板添加到centerright JPanel bottom=new JPanel(); //建立面板bottom,用于放置按钮 last.addActionListener(this); bottom.add(next); bottom.add(prev); bottom.add(first); bottom.add(last); //添加组件到面板 center.add(centerleft,"West"); center.add(centerright,"Center"); //添加组件到面板 center.add(centereast,"East"); //添加组件到面板 con.add(top,"North"); //添加组件到面板 con.add(center,"Center"); //添加组件到面板 con.add(bottom,"South"); //添加组件到面板 setVisible(true); } public void actionPerformed(ActionEvent e){ System.exit(0); } public static void main(String args[]){new TestSwingWindow6(); } }
构建图形用户界面一般步骤 引入Swing包 设置顶层容器及其布局 设置组件 向容器中添加组件 进行组件事件处理
类间层次关系图 Swing包是JFC (Java Foundation Classes)的一部分, 由许多包组成,Swing组件都是AWT的Container类的直接子类和间接子类。
6.4.1 图形用户界面Swing组件概述 顶层容器 中间层组件 基本组件 Swing包是JFC(Java Foundation Classes)的一部分,由许多包组成,Swing组件都是AWT的Container类的直接子类和间接子类,类之间层次关系如下图 Java语言包Swing定义了三种类型的组件: 顶层容器 (JFrame,JApplet,JWindow,和JDialog) 中间层组件 (JPanel, JScrollPane, JSplitPane, JToolBar) 基本组件 (Jbutton, JLable, JList, JMenu, JSlider, JtextField)
与AWT组件不同,Swing组件虽有顶层容器,但是我们不能把组件直接加到顶层容器中。 Swing窗体中含有一个称为内容面板的容器(ContentPane),在顶层容器上放置内容面板,然后把组件加入到内容面板中。 在Swing中,设置布局管理器是针对于内容面板。
6.4.2 Swing高级组件使用__分隔板、表格、 工具栏、树、布局管理器等 分隔板(JSplitPane) JSplitPane用于分隔两个Component。两个Component图形化分隔以外观实现为基础,并且这两个 Component可以由用户交互式调整大小。
组件分隔板程序段学习: import java.awt.event.*; import javax.swing.*; public class TestJSplitPane extends WindowAdapter { JFrame frame; JPanel cp=new JPanel(); JScrollPane jsp=new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); JLabel ImagL=new JLabel(); JTextArea ta=new JTextArea(); JSplitPane jsplitpane =new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); //分隔组件类对象声明
public void Test() { } frame = new JFrame("JSplitPane组件"); ImageIcon icon=new ImageIcon("test.jpg"); ImagL.setIcon(icon); jsp.setViewportView(ImagL); jsplitpane.setBorder(BorderFactory.createEtchedBorder()); jsplitpane.setOneTouchExpandable(true); jsplitpane.setDividerLocation(100); jsplitpane.setDividerSize(20); jsplitpane.setLeftComponent(ta); jsplitpane.setRightComponent(jsp); cp.add(jsplitpane); frame.setSize(400,400); frame.add(cp); frame.setVisible(true); } public static void main(String [] args){ TestJSplitPane JSP1 = new TestJSplitPane(); JSP1.Test(); public void windowClosing(WindowEvent e) { System.exit(0); }
利用JSplitPane实现JTextArea和JScrollPane两个组件的分割 创建一个配置为指定方向且无连续布局的JSplitPane对象jsplitpane; 然后调用该类setDividerSize(int newSize)方法-设置分隔条的大小, getRightComponent()方法-返回分隔条右边, getLeftComponent()方法-返回分隔条左边的组件, 其他方法来设置该组件相关属性。 程序运行结果:
表格(JTable) 表格(JTable) JTable组件主要功能是把数据以二维表格的形式显示出来。 通常由TableModel来控制JTable组件显示的数据,因此在创建JTable前,应先创建一个TableModel。 可以全部地执行TableModel接口,但它从helper类的AbstractTableModel处简单地继承。
组件实现表格程序段学习: import java.awt.*; import javax.swing.*; import java.awt.event.*; public class TestJTable extends JFrame { JPanel cp=new JPanel(); JTable jtable1; JScrollPane jscrp1=new JScrollPane(); public TestJTable() public static void main(String[] args) { TestJTable JTable1 = new TestJTable(); JTable1.setVisible(true); } protected void processWindowEvent(WindowEvent e) { if(e.getID()==WindowEvent.WINDOW_CLOSING) System.exit(0); }
public TestJTable() { cp=(JPanel)this.getContentPane(); this.setTitle("JTable组件"); this.setSize(500,200); cp.setLayout(new FlowLayout()); Object[][] data= {{"张茜","女","Java程序设计",new Integer(90),"优秀"},{"王萌","男","高等数学",new Integer(80),"良好"},{"李斯","女","大学语文",new Integer(65),"合格"} }; Object[] columnNames={"姓名","性别","科目","成绩","等第"}; jtable1=new JTable(data,columnNames); jtable1.setRowHeight(20); jscrp1.getViewport().add(jtable1); cp.add(jscrp1); }
利用JTable组件实现表格 首先创建Object对象的二维数组data,为JTable组件提供数据源。 创建Object对象的一维数组columnNames,为表格标题。 然后利用构造方法JTable(object[][]rowData,object[] columnNams)。 创建一个JTable对象jtable1,用来显示二维数组Data中的值,其列名称为一维数组columnNames的内容。 运行结果
树(JTree) 要显示一个层次关系分明的一组数据,用树状图表示能给用户一个直观而易用的感觉。 JTree类如同Windows的资源管理器的左半部,通过点击可以 “打开”、“关闭”文件夹,展开树状结构的图表数据。 JTree是依据M-V-C的思想来设计的,Jtree的主要功能是把数据按照树状进行显示,其数据来源于其它对象。
组件实现树程序段学习: import java.awt.*; import javax.swing.*; import javax.swing.tree.*; import java.awt.event.*; public class TestJtree extends JFrame { JPanel cp=new JPanel(); JTree jtree; DefaultMutableTreeNode root; public TestJtree() { this.setSize(300,300); this.setTitle("JTree组件"); cp=(JPanel)this.getContentPane(); cp.setLayout(new BorderLayout()); root=new DefaultMutableTreeNode("质量管理"); createTree(root); jtree=new JTree(root); cp.add(jtree,BorderLayout.CENTER); } public static void main(String[] args) { TestJtree TestJtree = new TestJtree(); TestJtree.setVisible(true);
private void createTree(DefaultMutableTreeNode root) { DefaultMutableTreeNode classroom=null; DefaultMutableTreeNode number=null; classroom=new DefaultMutableTreeNode("课程建设"); root.add(classroom); number=new DefaultMutableTreeNode("一般课程"); classroom.add(number); number=new DefaultMutableTreeNode("重点课程"); number=new DefaultMutableTreeNode("精品课程"); number.add(new DefaultMutableTreeNode("国家精品课程")); number.add(new DefaultMutableTreeNode("市级精品课程")); number.add(new DefaultMutableTreeNode("校级精品课程")); number=new DefaultMutableTreeNode("其他课程"); classroom.add(number); } protected void processWindowEvent(WindowEvent e) { if(e.getID()==WindowEvent.WINDOW_CLOSING) System.exit(0); }
首先利用构造方法,JTree(TreeNode root),返回一个 JTree,指定TreeNode 作为其根,它显示根节点。 再传递参数root给构造类createTree(DefaultMutableTreeNode root){……},来创建各个树节点。 各级层次树型节点的组装,主要是调用了JTree类继承的一个常用方法add(Component comp)。 运行结果
工具栏(JToolBar) JtoolBar是用于显示常用工具控件的容器。用户可以拖拽出一个独立的可显示工具控件的窗口。 创建一个如图所示显示工具栏组件的窗口。
组件实现工具栏程序段学习: import java.awt.*; import javax.swing.*; import java.awt.event.*; public class TestJtoolBar extends JFrame { JPanel cp=new JPanel(); JToolBar jtb=new JToolBar(); JButton jb1=new JButton(); JButton jb2=new JButton(); JButton jb3=new JButton(); JLabel jl=new JLabel("工具栏"); public TestJtoolBar() { setTitle("JToolBar组件"); setSize(300,300); cp=(JPanel)this.getContentPane(); cp.setLayout(new BorderLayout()); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e){ System.exit(0); } });
ImageIcon icon1=new ImageIcon("help.gif"); ImageIcon icon2=new ImageIcon("mmc.gif"); ImageIcon icon3=new ImageIcon("print.gif"); jb1.setIcon(icon1); jb2.setIcon(icon2); jb3.setIcon(icon3); jtb.add(jl); jtb.addSeparator(); jtb.add(jb1); jtb.add(jb2); jtb.add(jb3); jtb.setFloatable(true); cp.add(jtb,BorderLayout.NORTH); } public static void main(String[] args) { TestJtoolBar TestJtoolBar = new TestJtoolBar(); TestJtoolBar.setVisible(true); }
布局管理器 除了可以继续使用AWT介绍的布局管理器外,Swing包中新增加了一个BoxLayout布局管理器,允许纵向或横向布置多个组件的布局管理器。用横向组件和纵向组件不同组合的嵌套多面板的作用类似于GridBagLayout,但不复杂。 利用BoxLayout布局管理实现如图所示的窗口。
布局管理程序段学习: import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TestBoxLayout { private JFrame f; private JPanel p1 ; private JPanel p2 ; public static void main(String args[]) { TestBoxLayout testBoxL = new TestBoxLayout(); testBoxL.test(); } public void test() { f = new JFrame("布局管理器-BoxLayout"); f.setLayout(new GridLayout(1,2,10,10)); p1 = new JPanel(); p1.setLayout(new BoxLayout(p1,BoxLayout.X_AXIS)); p2 = new JPanel(); p2.setLayout(new BoxLayout(p2,BoxLayout.Y_AXIS)); p1.add(new JButton("Button1")); p1.add(new JButton("Button2")); p2.add(new JButton("Button3")); p2.add(new JButton("Button4")); p2.add(new JButton("Button5")); f.add(p1); f.add(p2); f.setSize(300,120); f.setVisible(true); f.addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e){ System.exit(0); } } ); }
6.5 Applet应用程序与图形用户界面介绍 Java Applet应用程序是一种不适合单独运行但可嵌入在其他应用程序中的小程序。 Applet类必须是任何嵌入在Web页中或用AppletViewer命令查看包含Applet标签的网页文件。 当用户访问包含Applet类的网页时, Applet被下载到用户的计算机上执行,前提是用户使用的是支持Java的网络浏览器。 由于Applet是在用户计算机上执行的,因此它的执行速度不受网络带宽存取速度的限制。
【综合案例6-7】 用Java Applet应用程序实现用户登录验证窗口,运行该程序结果如图
import java.awt.*; //引入AWT包 import java.applet.*; //引入applet包 import java.awt.event.*; //引入事件包 public class TestApplet extends Applet implements ActionListener{ TextField name=new TextField(20); //创建文本按钮 TextField password=new TextField(20); //创建文本按钮 Label label1=new Label(); //创建标签 Label label2=new Label(); //创建标签 Label label3=new Label(); //创建标签 Button btn1 = new Button("确定"); //创建按钮 Button btn2 = new Button("退出"); //创建按钮
public void init() { //Applet程序初始化方法 this.setLayout(new FlowLayout()); //设置Applet程序窗口布局管理模式 label1.setText(" 姓名:"); //设置标签文本 this.add(label1); //添加标签组件 this.add(name); //添加文本组件 label2.setText(" 密码:"); //设置标签文本 this.add(label2); //添加标签组件 password.setEchoChar('*'); //设置密码域显示字符 this.add(password); //添加密码域组件 this.add(btn1); //添加按钮组件 this.add(btn2); //添加按钮组件 this.add(label3); //添加标签组件 btn1. addActionListener(this); //为btn1注册事件监听器 btn2. addActionListener(new ActionListener(){ //为btn2注册事件监听器 public void actionPerformed(ActionEvent e){ System.exit(0);}}); } public void actionPerformed(ActionEvent e){ //事件方法实现 label3.setText(" 姓名"+name.getText()+" 密码"+password.getText( ));}
Applet程序先要用java编译器编译成为字节码文件; 编写相应的HTML文件才能够正常执行; ——TestApplet.html内容如下: <html><head><meta http-equiv="Content-Type" content="text/html; charset=GBK"> <title>TestApplet </title> </head><body> <applet codebase = "." code = " TestApplet.class" name = "TestApplet" width = "400" height = "300" hspace = "60" vspace = "0" align = "TOP" param name = " " > </applet> </body> </html>
网页文件中Applet标签包含的主要属性含义 code和codebase:code指明了Applet的类文件名,如果code使用时没有带一个相应的codebase,这个类文件就会从包含这个Applet的网页的同一个地方载入。 align:定义Applet与网页其他部分的位置关系,可以取的值有:LEFT,RIGHT,TEXTTOP,TOP,ABSMIDDLE,MIDDLE,BASELINE,BOTTOM,ABSBOTTOM。 hspace和vspace:定义Applet与周围文本的间距。 width和height:applet的初始显示空间 param:将参数传递给Applet。在Applet程序中通过getParameter()方法获得参数值。
从案例可以看出,一般 Java Applet与Java Application应用程序的图形用户界面的开发过程有相似的地方。Applet可以利用AWT组件或Swing组件来开发图形用户界面程序,利用用户计算机的GUI组件,可以建立标准的图形用户界面,如窗口、按钮、滚动条等等。 在Java Applet中,还可以实现图形绘制,字体和颜色控制,动画和声音的插入,人机交互及网络交流等功能。
Applet的生命周期 Applet的生命周期中有四个状态: 初始态、运行态、停止态和消亡态。 当程序执行完init()方法以后,Applet程序就进入了初始态;然后马上执行start()方法,Applet程序进入运行态;当Applet程序所在的浏览器最小化或是转入其他页面时,该Applet程序马上执行stop()方法,Applet程序进入停止态;在停止态中,如果浏览器又重新装载该Applet程序所在的页面,或者是浏览器从最小化复原,则Applet程序马上调用start()方法,进入运行态;当然,在停止态时,如果浏览器关闭,则Applet程序调用destroy()方法,进入消亡态。
Applet与Application的区别主要在于其执行方式的不同。 Application 是从其中的main() 方法开始运行的;而Applet 是在浏览器中运行的,必须创建一个HTML 文件,通过编写HTML 语言代码告诉浏览器载入何种Applet 以及如何运行。
6.6 本章小结 基本概念小结 组件 容器 布局管理器 事件源 事件监听器 事件处理程序
6.6 本章小结 知识点的学习与要求 本章学习时,要注意Swing组件和AWT组件的比较,要掌握AWT和Swing包中的一些基本概念,特性、方法、组件及容器等。 理解Java事件机制,学会在Java Application及Java Applet程序中开发图形用户界面。 理解和掌握一般组件的使用规律,在API的帮助下,可以自学一些新的组件或组件新的方法,并能应用到实际开发中。 本章内容实践性很强,学习时要注意多动手,勤思考,能够举一反三。
习题6 一、简答题 3 二、填空题 1~8 三、选择题 1~10 四、编程题 1,2