1、第八章 GUI(图形用户界面)布局管理器常用事件AWT事件处理机制常用Swing组件掌握布局管理器、AWT事件处理机制以及常用事件13 了解GUI开发的相关原理和技巧2熟悉Swing组件的使用掌握了解熟悉学习目标8.18.1AWT概述8.28.2布局管理器8.38.3AWT事件处理8.48.4常用事件分类8.58.5AWT绘图8.68.6Swing【任务任务8-18-1】水果超市管理系统点击查看本小节知识架构点击查看本小节知识架构点击查看本小节知识架构点击查看本小节知识架构目录返回目录8.2.18.2.2FlowLayoutBorderLayout8.2.3GridLayout8.2.4Gri
2、dBagLayout8.2.5CardLayout8.2.6不使用布局管理器8.2 布局布局管理器管理器知识架构返回目录8.3.18.3.28.3.3事件处理机制事件适配器用匿名内部类实现事件处理8.3 AWT事件处理事件处理知识架构8.4 常用常用事件事件分类分类返回目录8.4.18.4.28.4.3窗体事件鼠标事件键盘事件8.4.4动作事件知识架构返回目录8.6 Swing8.6.18.6.28.6.38.6.48.6.58.6.68.6.78.6.8JframeJDialog中间容器文本组件按钮组件JComboBox菜单组件JTable知识架构 GUI全称是Graphical User
3、Interface,即图形用户界面。顾名思义,就是应用程序提供给用户操作的图形界面,包括窗口、菜单、按钮、工具栏和其他各种图形界面元素。目前,图形用户界面已经成为一种趋势,几乎所有的程序设计语言都提供了GUI设计功能。Java中针对GUI设计提供了丰富的类库,这些类分别位于java.awt和javax.swing包中,简称为AWT和Swing。其中,AWT是SUN公司最早推出的一套API,它需要利用本地操作系统所提供的图形库,属于重量级组件,不跨平台,它的组件种类有限,可以提供基本的GUI设计工具,却无法实现目前GUI设计所需的所有功能。随后,SUN公司对AWT进行改进,提供了Swing组件,
4、Swing组件由纯Java语言编写,属于轻量级组件,可跨平台,Swing不仅实现了AWT中的所有功能,而且提供了更加丰富的组件和功能,足以满足GUI设计的一切需求。Swing会用到AWT中的许多知识,掌握了AWT,学习Swing就变成了一件很容易的事情,因此本章将从AWT开始学习图形用户界面。GUI(图形用户界面) AWT是用于创建图形用户界面的一个工具包,它提供了一系列用于实现图形界面的组件,如窗口、按钮、文本框、对话框等。在JDK中针对每个组件都提供了对应的Java类,这些类都位于java.awt包中,接下来通过一个图例来描述这些类的继承关系,如图所示。 从图的继承关系可以看出,在AWT中
5、组件分为两大类,这两类的基类分别是Component和MenuComponent。其中,MenuComponent是所有与菜单相关组件的父类,Component则是除菜单外其他AWT组件的父类,它表示一个能以图形化方式显示出来,并可与用户交互的对象。8.1 AWT概述 Component类通常被称为组件,根据Component的不同作用,可将其分为基本组件类和容器类。基本组件类是诸如按钮、文本框之类的图形界面元素,而容器类则是通过Component的子类Container实例化的对象。Container类表示容器,它是一种特殊的组件,可以用来容纳其他组件。Container容器又分为两种类型,
6、分别是Window和Panel,接下来对两种类型进行详细讲解。1Window Window类是不依赖其他容器而独立存在的容器,它有两个子类,分别是Frame类和Dialog类。Frame类用于创建一个具有标题栏的框架窗口,作为程序的主界面,Dialog类用于创建一个对话框,实现与用户的信息交互,如图所示。8.1 AWT概述2Panel Panel也是一个容器,但是它不能单独存在,只能存在其他容器(Window或其子类)中,一个Panel对象代表了一个长方形的区域,在这个区域中可以容纳其他组件。在程序中通常会使用Panel来实现一些特殊的布局。 了解了AWT组件的相关类后,为了使读者对GUI有一
7、个更直观的认识,接下来通过一个案例来创建一个简单的图形界面,请查看教材文件8-1。 案例代码8.1 AWT概述 8.1小节提到过,组件不能单独存在,必须放置于容器当中,而组件在容器中的位置和尺寸是由布局管理器来决定的。在java.awt包中提供了五种布局管理器,分别是FlowLayout(流式布局管理器)、BorderLayout(边界布局管理器)、GridLayout(网格布局管理器)、GridBagLayout(网格包布局管理器)和CardLayout(卡片布局管理器)。每个容器在创建时都会使用一种默认的布局管理器,在程序中可以通过调用容器对象的setLayout()方法设置布局管理器,通
8、过布局管理器来自动进行组件的布局管理。例如把一个Frame窗体的布局管理器设置为FlowLayout,代码如下所示:8.2 布局管理器 流式布局管理器(FlowLayout)是最简单的布局管理器,在这种布局下,容器会将组件按照添加顺序从左向右放置。当到达容器的边界时,会自动将组件放到下一行的开始位置。这些组件可以左对齐、居中对齐(默认方式)或右对齐的方式排列。FlowLayout对象有三个构造方法,如表所示。 表中,列出了FlowLayout的三个构造方法,其中,参数align决定组件在每行中相对于容器边界的对齐方式,可以使用该类中提供的常量作为参数传递给构造方法,其中FlowLayout.L
9、EFT用于表示左对齐、FlowLayout.RIGHT用于表示右对齐、FlowLayout.CENTER用于表示居中对齐。参数hgap和参数vgap分别设定组件之间的水平和垂直间隙,可以填入一个任意数值。FlowLayout8.2 布局管理器接下来通过一个添加按钮的案例来学习一下FlowLayout布局管理器的用法,请查看教材文件8-2。 案例代码8.2 布局管理器 BorderLayout(边界布局管理器)是一种较为复杂的布局方式,它将容器划分为五个区域,分别是东(EAST)、南(SOUTH)、西(WEST)、北(NORTH)、中(CENTER)。组件可以被放置在这五个区域中的任意一个。Bo
10、rderLayout布局的效果如图所示。 从图可以看出BorderLayout边界布局管理器,将容器划分为五个区域,其中箭头是指改变容器大小时,各个区域需要改变的方向。也就是说,在改变容器时NORTH和SOUTH区域高度不变长度调整,WEST和EAST区域宽度不变高度调整,CENTER会相应进行调整。BorderLayout8.2 布局管理器 当向BorderLayout布局管理器的容器中添加组件时,需要使用add(Component comp,Object constraints)方法。其中参数comp表示要添加的组件,constraints指定将组件添加到布局中的方式和位置的对象,它是一个
11、Object类型,在传参时可以使用BorderLayout类提供的5个常量,它们分别是EAST、SOUTH、WEST、NORTH和CENTER。 接下来通过一个案例来演示一下BorderLayout布局管理器对组件布局的效果,请查看教材文件8-3。 案例代码8.2 布局管理器 GridLayout(网格布局管理器)使用纵横线将容器分成n行m列大小相等的网格,每个网格中放置一个组件。添加到容器中的组件首先放置在第1行第1列(左上角)的网格中,然后在第1行的网格中从左向右依次放置其他组件,行满后,继续在下一行中从左到右放置组件。与FlowLayout不同的是,放置在GridLayout布局管理器中
12、的组件将自动占据网格的整个区域。 接下来学习下GridLayout的构造方法,如表所示。 表中,列出了GridLayout的三个构造方法,其中,参数rows代表行数,cols代表列数,hgap和vgap规定水平和垂直方向的间隙。水平间隙指的是网格之间的水平距离,垂直间隙指的是网格之间的垂直距离。GridLayout8.2 布局管理器 接下来通过一个案例演示GridLayout布局的用法,请查看教材文件8-4。 案例代码8.2 布局管理器 GridBagLayout(网格包布局管理器)是最灵活、最复杂的布局管理器。与GridLayout布局管理器类似,不同的是,它允许网格中的组件大小各不相同,而
13、且允许一个组件跨越一个或者多个网格。 使用GridBagLayout布局管理器的步骤如下:(1)创建GridbagLayout布局管理器,并使容器采用该布局管理器(2)创建GridBagContraints对象(布局约束条件),并设置该对象的相关属性GridBagLayout8.2 布局管理器(3)调用GridBagLayout对象的setConstraints()方法建立GridBagConstraints对象和受控组件之间的关联 (4)向容器中添加组件 GridBagConstraints对象可以重复使用,只需要改变它的属性即可。如果要向容器中添加多个组件,则重复(2)、(3)、(4)步骤
14、。 从上面的步骤可以看出,使用GridBagLayout布局管理器的关键在于GridBagConstraints对象,它才是控制容器中每个组件布局的核心类,在GridBagConstraints类中有很多表示约束的属性,下面对GridBagConstraints类的一些常用属性进行介绍,如表所示。8.2 布局管理器 表8-3中,列出了GridBagConstraints的常用属性,其中,gridx和 gridy用于设置组件左上角所在网格的横向和纵向索引,gridwidth和gridheight用于设置组件横向、纵向跨越几个网格,fill用于设置是否及如何改变组件大小,weightx和weigh
15、ty用于设置组件在容器中的水平方向和垂直方向的权重。 需要注意的是,如果希望组件的大小随着容器的增大而增大,必须同时设置GridBagConstraints对象的fill属性和weightx、weighty属性。8.2 布局管理器 接下来通过一个案例来演示GridBagLayout的用法,请查看教材文件8-5。 案例代码8.2 布局管理器 在操作程序时,经常会遇到通过选项卡按钮来切换程序中的界面,这些界面就相当于一张张卡片,而管理这些卡片的布局管理器就是卡片布局管理器(CardLayout)。卡片布局管理器将界面看做是一系列卡片,在任何时候只有其中一张卡片是可见的,这张卡片占据容器的整个区域。
16、 在CardLayout布局管理中经常会用到下面几个方法,如表所示。CardLayout8.2 布局管理器 接下来通过一个案例来演示这些方法的使用,请查看教材文件8-6。 案例代码8.2 布局管理器 当一个容器被创建后,它们都会有一个默认的布局管理器。Window、Frame和Dialog的默认布局管理器是BorderLayout,Panel的默认布局管理器是FlowLayout。如果不希望通过布局管理器来对容器进行布局,也可以调用容器的setLayout(null)方法,将布局管理器取消。在这种情况下,程序必须调用容器中每个组件的setSize()和setLocation()方法或者是set
17、Bounds()方法(这个方法接收四个参数,分别是左上角的x、y坐标和组件的长、宽)来为这些组件在容器中定位。不使用布局管理器 接下来通过一个案例来演示不使用布局管理器对组件进行布局,请查看教材文件8-7。 案例代码8.2 布局管理器 8.1小节中的文件8-1实现了一个图形化窗口,单击窗口右上角的关闭按钮会发现窗口无法关闭,这说明该按钮的单击功能没有实现。按理说Frame对象应该实现这个按钮的功能,之所以没有实现,是因为Frame的设计者无法确定用户关闭Frame窗口的方式,例如,是直接关闭窗口还是需要弹出对话框询问用户是否关闭。如果想要关闭窗口,就需要通过事件处理机制对窗口进行监听。 事件处
18、理机制专门用于响应用户的操作,比如,想要响应用户的单击鼠标、按下键盘等操作,就需要使用AWT的事件处理机制。在学习如何使用AWT事件处理机制之前,首先向读者介绍几个比较重要的概念,具体如下所示: 事件对象(Event):封装了GUI组件上发生的特定事件(通常就是用户的一次操作)。事件处理机制8.3 AWT事件处理 事件源(组件):事件发生的场所,通常就是产生事件的组件。 监听器(Listener):负责监听事件源上发生的事件,并对各种事件做出相应处理的对象(对象中包含事件处理器)。 事件处理器:监听器对象对接收的事件对象进行相应处理的方法。 上面提到的事件对象、事件源、监听器、事件处理器在整个
19、事件处理机制中都起着非常重要的作用,它们彼此之间有着非常紧密的联系。接下来用一个图例来描述事件处理的工作流程,如图所示。8.3 AWT事件处理 在程序中,如果想实现事件的监听机制,首先需要定义一个实现了事件监听器接口的类,例如Window类型的窗口需要实现WindowListener。接着通过addWindowListener()方法为事件源注册事件监听器对象,当事件源上发生事件时,便会触发事件监听器对象,由事件监听器调用相应的方法来处理相应的事件。 接下来,通过一个案例来实现对文件8-1中的窗口关闭的功能,请查看教材文件8-8。 案例代码8.3 AWT事件处理 文件8-8中的MyWindow
20、Listener类实现WindowListener接口后,需要实现接口中定义的7个方法,然而在程序中需要用到的只有windowClosing()一个方法,其他六个方法都是空实现,没有发挥任何作用,这样代码的编写明显是一种多余但又必需的工作。针对这样的问题,JDK提供了一些适配器类,它们是监听器接口的默认实现类,这些实现类中实现了接口的所有方法,但方法中没有任何代码,程序可以通过继承适配器类来达到实现监听器接口的目的。事件适配器 接下来通过继承适配器类来实现与文件8-8相同的功能,请查看教材文件8-9。 案例代码8.3 AWT事件处理 文件8-9通过继承适配器类对事件源对象实现了监听,但在实际开
21、发中,为了代码的简洁,经常通过匿名内部类来创建事件的监听器对象,针对所发生的事件进行处理。用匿名内部类实现事件处理 接下来通过案例来演示如何为窗口添加一个具有单击事件的按钮,请查看教材文件8-10。 案例代码8.3 AWT事件处理 大部分GUI应用程序都需要使用Window窗体对象作为最外层的容器,可以说窗体对象是所有GUI应用程序的基础,应用程序中通常都是将其他组件直接或者间接地置于窗体中。 当对窗体进行操作时,比如窗体的打开、关闭、激活、停用等,这些动作都属于窗体事件,JDK中提供了一个类WindowEvent用于表示这些窗体事件。在应用程序中,当对窗体事件进行处理时,首先需要定义一个实现
22、了WindowListener接口的类作为窗体监听器,然后通过addWindowListener()方法将窗体对象与窗体监听器绑定。窗口事件 接下来通过一个案例来实现对窗体事件的监听,请查看教材文件8-11。 案例代码8.4 常用事件分类 在图形用户界面中,用户会经常使用鼠标来进行选择、切换界面等操作,这些操作被定义为鼠标事件,其中包括鼠标按下、鼠标松开、鼠标单击等。JDK中提供了一个MouseEvent类用于表示鼠标事件,几乎所有的组件都可以产生鼠标事件。处理鼠标事件时,首先需要通过实现MouseListener接口定义监听器(也可以通过继承适配器MouseAdapter类来实现),然后调用
23、addMouseListener()方法将监听器绑定到事件源对象。鼠标事件 接下来通过一个案例来学习如何监听鼠标事件,请查看教材文件8-12。 案例代码8.4 常用事件分类 读者可能会问,鼠标的操作分为左键单击双击和右键单击双击,而且还有滚轮。上面只给出这些事件的处理,能满足实际需求吗?答案是肯定的,MouseEvent类中定义了很多常量来标识鼠标动作。如下面的代码所示: 从上面的代码可以看出,MouseEvent类中针对鼠标的按键都定义了对应的常量,可以通过MouseEvent对象的getButton()方法获取被操作按键的常量键值,从而判断是哪个按键的操作。另外,鼠标的单击次数也可以通过M
24、ouseEvent对象的getClickCount()方法获取到。因此,在鼠标事件中,可以根据不同的操作,做出相应的处理。8.4 常用事件分类 键盘操作也是最常用的用户交互方式,例如键盘按下、释放等,这些操作被定义为键盘事件。JDK中提供了一个KeyEvent类表示键盘事件,处理KeyEvent事件的监听器对象需要实现KeyListener接口或者继承KeyAdapter类。键盘事件 接下来通过一个案例来学习如何监听键盘事件,请查看教材文件8-13。 案例代码8.4 常用事件分类 动作事件与前面三种事件有所不同,它不代表某个具体的动作,只是表示一个动作发生了。例如,在关闭一个文件时,可以通过键
25、盘关闭,也可以通过鼠标关闭。在这里读者不需要关心使用哪种方式对文件进行关闭,只要是对关闭按钮进行操作,即触发了动作事件。 在Java中,动作事件用ActionEvent类表示,处理ActionEvent事件的监听器对象需要实现ActionListener接口。监听器对象在监听动作时,不会像鼠标事件一样处理鼠标的移动和单击的细节,而是去处理类似于“按钮按下”这样“有意义”的事件。动作事件8.4 常用事件分类 关于动作事件的案例将在后面的小节进行详细讲解,这里,只演示一种可以通过动作事件实现的情况。如图所示。 要想关闭上图的记事本程序,可以通过鼠标单击【退出】选项或者在【文件】选项下通过键盘的方向
26、键将蓝色选中条移动至【退出】选项处单击回车键,这两个操作均可触发当前【退出】选项的动作事件ActionEvent。8.4 常用事件分类 很多GUI程序都需要在组件上绘制图形,比如实现一个五子棋的小游戏,就需要在组件上绘制棋盘和棋子。在java.awt包中专门提供了一个Graphics类,它相当于一个抽象的画笔,其中提供了各种绘制图形的方法,使用Graphics类的方法就可以完成在组件上绘制图形。表中列出了Graphics类中常用的方法。AWT绘图8.4 常用事件分类 表中,列出了Graphics的常用方法,为了更好的理解和使用它们,下面对这些方法进行详细的说明。setColor()方法方法 用
27、于指定上下文颜色,方法中接收一个Color类型的参数。在AWT中,Color类代表颜色,其中定义了许多代表各种颜色的常量,比如Color.RED,Color.BLUE等,这些常量都是Color类型的,可以直接作为参数传递给setColor()方法。setFont()方法方法 用于指定上下文字体,方法中接收一个Font类型的参数。Font类表示字体,可以使用new关键字创建Font对象。Font的构造方法中接收三个参数,第一个是String类型,表示字体名称,如“宋体”、“微软雅黑”等,第二个参数是int类型,表示字体的样式,参数接收Font类的三个常量Font.PLAINT、Font.ITAL
28、IC和Font.BOLD,第三个参数为int类型,表示字体的大小。8.4 常用事件分类drawRect()方法和方法和drawOval()方法方法 用于绘制矩形和椭圆形的边框fillRect()和和fillOval()方法方法 用于使用当前的颜色填充绘制完成的矩形和椭圆形。drawString()方法方法 用于绘制一段文本,第一个参数str表示绘制的文本内容,第二个和第三个参数x、y为绘制文本的左下角坐标。 接下来通过一个案例来演示如何使用Graphics在组件中进行绘图,请查看教材文件8-14。 案例代码8.4 常用事件分类 在本章的一开始就提到过JDK中针对GUI提供的API包括AWT和S
29、wing。前面的小节都是针对AWT组件进行讲解,接下来针对Swing组件进行讲解。相对于AWT来说,Swing包中提供了更加丰富、便捷、强大的GUI组件,而且这些组件都是Java语言编写而成的,因此,Swing组件不依赖于本地平台,可以真正做到跨平台运行。通常来讲,把依赖于本地平台的AWT组件称为重量级组件,而把不依赖本地平台的Swing组件称为轻量级组件。 学习Swing组件的过程和学习AWT差不多,大部分的Swing组件都是JComponent类的直接或者间接子类,而JComponent类是AWT中java.awt.Container的子类,说明Swing组件和AWT组件在继承树上形成了一
30、定的关系。接下来通过一张继承关系图来描述一下AWT和Swing大部分组件的关联关系,如图所示。8.5 Swing 图中,展示了一些常用的Swing组件,不难发现,这些组件的类名和对应的AWT组件类名基本一致,大部分都是在AWT组件类名的前面添加了“J”,但也有一些例外,比如Swing的JComboBox组件对应的是AWT中的Choice组件(下拉框)。 通过图中还可以看出,Swing中有三个组件是继承了AWT的Window类,而不是继承自JComponent类,它们分别是JWindow、JFrame、和JDialog,这三个组件是Swing中的顶级容器,它们都需要依赖本地平台,因此被称为重量级
31、组件。其中,JWindow和AWT中的Window一样很少被使用,一般都是用JFrame和JDialog。8.5 Swing 在Swing组件中,最常见的一个就是JFrame,它和Frame一样是一个独立存在的顶级窗口,不能放置在其他容器之中,JFrame支持通用窗口所有的基本功能,例如窗口最小化、设定窗口大小等。JFrame 接下来通过一个案例来演示一下JFrame的效果,请查看教材文件8-15。 案例代码8.5 Swing JDialog是Swing的另外一个顶级窗口,它和Dialog一样都表示对话框。JDialog对话框可分为两种:模态对话框和非模态对话框。所谓模态对话框是指用户需要等到
32、处理完对话框后才能继续与其他窗口交互的对话框,而非模态对话框是允许用户在处理对话框的同时与其他窗口交互的对话框。 对话框是模态或者非模态,可以在创建JDialog对象时为构造方法传入参数来设置,也可以在创建JDialog对象后调用它的setModal()方法来进行设置。JDialog常见的构造方法如表所示。JDialog8.5 Swing 表中,列举了JDialog三个常用的构造方法,在这三个构造方法中都需要接收一个Frame类型的对象,表示对话框所有者,如果该对话框没有所有者,参数owner可以传入null。第三个构造方法中,参数modal用来指定JDialog窗口是模态还是非模态,如果mo
33、dal值设置为true,对话框就是模态对话框,反之则是非模态对话框,如果不设置modal的值,其默认值为false,也就是非模态对话框。 接下来通过一个案例来学习如何使用JDialog对话框,请查看教材文件8-16。 案例代码8.5 Swing Swing组件中不仅具有JFrame和JDialog这样的顶级窗口,还提供了一些中间容器,这些容器不能单独存在,只能放置在顶级窗口中。其中最常见的中间容器有两种:JPanel和JScrollPane,接下来分别来介绍这两种容器。 JPanel:JPanel和AWT中的Panel组件使用方法基本一致,它是一个无边框,不能被移动、放大、缩小或者关闭的面板,
34、它的默认布局管理器是FlowLayout。当然也可以使用JPanel带参数的构造函数JPanel(LayoutManager layout)或者它的setLayout()方法为其制定布局管理器。 JScrollPane:与JPanel不同的是,JScrollPane是一个带有滚动条的面板容器,而且这个面板只能添加一个组件,如果想在JScrollPane面板中添加多个组件,应该先将组件添加到JPanel中,然后将JPanel添加到JScrollPane中。中间容器8.5 Swing 接下来学习一下JScrollPane的常用构造方法,如右表所示。 右表中,列出了JScrollPane的三个构造方
35、法,其中,第一个构造方法用于创建一个空的JScrollPane面板,第二个构造方法用于创建显示指定组件的JScrollPane面板,这两个方法都比较简单。第三个构造方法,是在第二个构造方法的基础上指定滚动条策略。如果在构造方法中没用指定显示组件和滚动条策略,也可以使用JScrollPane提供的方法进行设置,如下表所示。8.5 Swing 接下来通过一个案例来演示一下向中间容器添加按钮,请查看教材文件8-17。 案例代码8.5 Swing 文本组件用于接收用户输入的信息或向用户展示信息,其中包括文本框(JTextField)、文本域(JTextArea)等,它们都有一个共同父类JTextCom
36、ponent。JTextComponent是一个抽象类,它提供了文本组件常用的方法,如表所示。 表中列出了几种对文本组件进行操作的方法,其中包括选中文本内容、设置文本内容以及获取文本内容等。由于JTextField和JTextArea这两个文本组件都继承了JTextComponent类,因此它们都具有表中的方法,但它们在使用上还有一定的区别。接下来就对这两个文本组件进行详细讲解。文本组件8.5 SwingJTextField:JTextField称为文本框,它只能接收单行文本的输入。JTextField常用的构造方法,如下表所示。 表中,列出了四个JTextField的构造方法,在创建JTex
37、tField文本框时,通常使用第二个或者第四个构造方法,指定文本框的列数。 JTextField有一个子类JPasswordText,它表示一个密码框,只能接收用户的单行输入,但是在此框中不显示用户输入的真实信息,而是通过显示指定的回显字符作为占位符。新创建的密码框默认的回显字符为“*”。JPasswordText和JTextField的构造方法相似,这里就不再介绍了。8.5 SwingJTextArea:JTextArea称为文本域,它能接收多行的文本的输入,使用JTextArea构造方法创建对象时可以设定区域的行数、列数。接下来,介绍一下JTextArea常用的构造方法,如下表所示。 表中
38、,列出了四个JTextArea的构造方法,在创建文本域时,通常会使用最后两个构造方法,指定文本域的行数和列数。 接下来编写一个聊天窗口,演示一下文本组件JTextField和JTextArea的使用,请查看教材文件8-18。 案例代码8.5 Swing 在Swing中,常见的按钮组件有JButton、JCheckBox、JRadioButton等,它们都是抽象类AbstractButton类的直接或间接子类。在AbstractButton类中提供了按钮组件通用的一些方法,如表所示。1JCheckBox JCheckBox组件被称为复选框,它有选中(是)/未选中(非)两种状态,如果用户想接收的输
39、入只有“是”和“非”,则可以通过复选框来切换状态。如果复选框有多个,则用户可以选中其中一个或者多个。按钮组件8.5 Swing 下表列举了创建JCheckBox对象的常用的构造方法。 表中,列出了用于创建JCheckBox对象的三个构造方法。其中,第一个构造方法没有指定复选框的文本信息以及状态,如果想设置文本信息,可以通过调用JCheckBox从父类继承的方法来进行设置。例如调用setText(String text)来设置复选框文本信息,调用setSelected(boolean b)方法来设置复选框状态(是否被选中),也可以调用isSelected()方法来判断复选框是否被选中。第二个和第
40、三个构造方法都指定了复选框的文本信息,而且第三个构造方法还指定了复选框初始化状态是否被选中。8.5 Swing 接下来通过一个案例来演示一下JCheckBox组件的用法,请查看教材文件8-19。 案例代码8.5 Swing2JRadionButton JRadioButton组件被称为单选按钮,与JCheckBox复选框不同的是,单选按钮只能选中一个。就像随身听上的播放和快进按钮,当按下一个,先前按下的按钮就会自动弹起。对于JRadioButton按钮来说,当一个按钮被选中时,先前被选中的按钮就会自动取消选中。 由于JRadioButton组件本身并不具备这种功能,因此若想实现JRadioBu
41、tton按钮之间的互斥,需要使用javax.swing.ButtonGroup类,它是一个不可见的组件,不需要将其增加到容器中显示,只是在逻辑上表示一个单选按钮组。将多个JRadioButton按钮添加到同一个单选按钮组对象中,就能实现按钮的单选功能。表列举了创建JRadioButton对象常见的构造方法。8.5 Swing 接下来通过一个案例来演示一下JRadioButton组件的用法,请查看教材文件8-20。 案例代码8.5 Swing JComboBox组件被称为组合框或者下拉列表框,它将所有选项折叠收藏在一起,默认显示的是第一个添加的选项。当用户单击组合框时,会出现下拉式的选择列表,用
42、户可以从中选择其中一项并显示。 JComboBox组合框组件分为可编辑和不可编辑两种形式,对于不可编辑的组合框,用户只能在现有的选项列表中进行选择,而对于可编辑的组合框,用户既可以在现有的选项中选择,也可以自己输入新的内容。需要注意的是,自己输入的内容只能作为当前项显示,并不会添加到组合框的选项列表中。表中列举JComboBox类的常用构造方法。JComboBox组件8.5 Swing 在使用JComboBox时,需要用到它的一些常用方法,如表所示。 通过上面的两个表简单认识了JComboBox类的构造方法和常用方法,接下来通过一个案例来演示一下该组件的具体用法,请查看教材文件8-21。 案例
43、代码8.5 Swing 在GUI程序中,菜单是很常见的组件,利用Swing提供的菜单组件可以创建出多种样式的菜单。接下来重点对下拉式菜单和弹出式菜单进行介绍。1下拉式下拉式菜单菜单 对于下拉式菜单,读者肯定很熟悉,因为计算机中很多文件的菜单都是下拉式的,如记事本的菜单。在GUI程序中,创建下拉式菜单需要使用三个组件:JMenuBar(菜单栏)、JMenu(菜单)和 JMenuItem(菜单项),以记事本为例, 这三个组件在菜单中对应的位置如图 所示。菜单组件8.5 Swing 图中,分别指出了菜单的三个组件,接下来针对这三个组件进行详细的讲解。(1)JMenuBar:JMenuBar表示一个水
44、平的菜单栏,它用来管理菜单,不参与同用户的交互式操作。菜单栏可以放在容器的任何位置,但通常情况下会使用顶级窗口(如JFrame、JDialog)的setJMenuBar(JMenuBar menuBar)方法将它放置在顶级窗口的顶部。JMenuBar有一个无参构造函数,创建菜单栏时,只需要使用new关键字创建JMenuBar对象即可。创建完菜单栏对象后,可以调用它的add(JMenu c)方法为其添加JMenu菜单。(2)JMenu:JMenu表示一个菜单,它用来整合管理菜单项。菜单可以是单一层次的结构,也可以是多层次的结构。大多情况下,会使用构造函数JMenu(String text)创建J
45、Menu菜单,其中参数text表示菜单上的文本。8.5 Swing JMenu中还有一些常用的方法,如表所示。(3)JMenuItem:JMenuItem表示一个菜单项,它是菜单系统中最基本的组件。和JMenu菜单一样,在创建JMenuItem菜单项时,通常会使用构造方法JMenumItem(String text)为菜单项指定文本内容。 由于JMenuItem类是继承自AbstractButton类的,因此可以把它看成是一个按钮。如果使用无参的构造方法创建了一个菜单项,则可以调用从AbstractButton类中继承的setText(String text)方法和setIcon()方法为其设
46、置文本和图标。8.5 Swing 介绍完创建菜单所需的三个基本组件后,接下来通过一个案例来学习一下菜单的创建和使用,请查看教材文件8-22。 案例代码8.5 Swing2弹出式菜单弹出式菜单 对于弹出式菜单,相信大家也不会陌生,在Windows桌面单击鼠标右键会出现一个菜单,那就是弹出式菜单。在Java的Swing组件中,弹出式菜单用JPopupMenu表示。 JPopupMenu弹出式菜单和下拉式菜单一样,都通过调用add()方法添加JMenuItem菜单项,但它默认是不可见的。如果想要显示出来,则必须调用它的show(Component invoker,int x,int y)方法,该方法
47、中参数invoker表示JPopupMenu菜单显示位置的参考组件,x和y表示invoker组件坐标空间中的一个坐标,显示的是JPopupMenu菜单的左上角坐标。 接下来通过案例来演示一下JPopup组件的用法,请查看教材文件8-23。 案例代码8.5 Swing 表格也是GUI程序中常用的组件,表格是一个由多行、多列组成的二维显示区。Swing的JTable以及相关类提供了对这种表格的支持。使用了JTable以及相关类,程序既可以使用简单代码创建出表格来显示二维数据,也可以开发出功能丰富的表格,还可以为表格定制各种显示外观、编辑特性。 使用JTable来创建表格是非常容易的事情,它可以把一
48、个二维数据包装成一个表格,这个二维数据既可以是一个二维数组,也可以是集合元素Vector对象(Vector里面包含Vector形成二维数据)。除此之外,为了给该表格的每一列指定列标题,还需要传入一个一维数据作为列标题,这个一维数据既可以是一维数组,也可以是Vector对象。JTable8.5 Swing 在使用JTable以前,先看一下它的构造函数有哪些,如表所示。 在表中,TableModel是用来存储列表数据的,数据包括表头的标题数据与表体的实体数据。TableModel为功能接口,通常使用其具体的实现类DefaultTableModel,其构造方法如下:8.5 Swing 在上述代码中,
49、tbody表示表体,为一个二维数组;thead表示表头,为一个一维数组。其具体描述如下。 表体:是一个Object类型的二维数组,由于多态的自动类型提升,可以直接使用String来存储数据。 表头:是一个Object类型的一维数组,同样,可以直接使用String来存储所有的标题字符串。 了解了JTable的构造函数后,接下来通过一个案例来学习如何使用JTable来创建一个简单表格,请查看教材文件8-24。 案例代码8.5 Swing任务案例案例代码接下来,通过一个水果超市管理系统来熟悉本阶段的知识点,请查看教材【任务8-1】。【任务8-1】水果超市管理系统 本章主要向读者讲解了GUI的一些基本
50、原理和开发技巧及思想,主要包括AWT创建GUI的基本方法,AWT的事件处理机制,事件的原理、常用事件的监听和处理方法、五种布局管理器,介绍了一些常用的Swing组件,其中包括JFrame、JDialog、JTextField、JComboBox等。 本章对GUI的学习只是告诉读者如何开发GUI程序,重点在向读者讲解一些基本的原理和开发技巧以及思想,不可能将所有的组件都拿出来介绍,Swing中的某些组件使用上与AWT的组件还有些不同,所以读者如果想进一步了解GUI,建议查阅JDK文档中的一些Demo程序,或者下载相关资料来了解其他组件的使用方法,这才是读者对GUI组件甚至其他编程语言的学习之道。