程序是为了方便用户使用的,因此实现图形化界面的程序编写是所有编程语言发展的必然趋势,在命令提示符下运行的程序可以让我们了解java程序的基本知识体系结构,现在就进入java图形化界面编程。
一、Java基本类(JFC)
Java基本类(“Java FoundationClasses”,JFC),由一些软件包组成。这些软件包主要包括下面一些应用程序接口(API):
·抽象窗口工具集(AWT)(1.1及以上版本)。
·Swing构件。
·java 2D应用程序接口(2D API)。
·兼容程序接口。
上面列出的这些应用程序接口可难会出现在多个软件包中。例如:2D API在Java.awt和Java.awt.image软件包中都存在,虽然像Java.awt.geom等一些特殊的软件包也支持2DAPI,但是大量的2D API类都存在于Java.awt软件包中。
AWT(1.1及以上版本)是JFC的核心。AWT为JFC的构成提供了以下基本结构:
·代理事件模型。
·轻量构件。
·剪贴板和数据传输。
·打印和无鼠标操作。
1、AWTAbstract Window Toolkit(AWT)抽象窗口工具包
AWT是比较旧的双介面函式库,它依然高度倚赖各作业平台自身所具备的绘图功效机能,且用一个比包容程式(Wrapper)还小的设计还去除、吸收各作业平台间的绘图功能机能差异,以致Java程式在跨平台移携后的绘图呈现不够一致,这使得AWT遭受到众多的批评。这意味着:AWT的Widget倚赖作业平台自身原有的Widget功效机能,程式设计师在开发撰写时必须去了解各作业平台在Widget方面的差异性,如此便偏离了Java程式语言最初的宗旨:跨平台一致性。
AWT由java.awt包提供,其提供了支持GUI设计的类和接口,而又AWT提供的组建一般称之为重量级组件,其是由本地方法来实现其功能的。AWT的特点:
l AWT 中的图形函数与操作系统所提供的图形函数之间有着一一对应的关系
l AWT 通过牺牲功能来实现其平台无关性
l AWT不能满足图形化用户界面发展的需要
2、Swing包
为了解决AWT组件的缺陷,特别是跨平台的问题,在JDK1.2版本后提供了新的Swing包,有javax.swing提供,Swing是在AWT的基础上构建的一套新的图形界面组件,所有组建均是由java书写,具有良好的跨平台性,由于Swing没有使用本地方法实现图形功能,因此提出把Swing组件称之为轻量级组件。
注意:Swing组建是在AWT基础上建立的,而不是替代AWT的,AWT是根基,Swing是发展。
Swing组件几乎都是轻量组件,那些顶层容器:窗体,小应用程序、窗口和对话框除外。因为轻量组件是在其容器的窗口中绘制的,而不是在自己的窗口中绘制的,所以轻量组件最终必须包含在一个重量容器中。因此,Swing的窗体、小应用程序、窗口和对话框都必须是重量组件,以便提供一个可以在其绘制Swing轻量组件的窗口。
Swing包括250多个类,其中有些是UI组件,有些是支持类。为了把UI组件和支持类区分开,Swing组件的名字以J开头。表1-1列出了Swing提供的J组件。用斜体字表示的组件是AWT组件的替代组件。
表1-1 Swing UI组件
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
组件 | 描述 |
JApplet | Java.applet.Applet类的扩展,它含有JRootPane的一个实例 |
JButton | 能显示文本和图形的按钮,它是AWT按钮组件的替代组件 |
JCheckBox | 能显示文本和图形的复选框,它是AWT选择组件的替代组件 |
JCheckBoxMenuItem | 一个复选框菜单项,它是AWT的复选框菜单项组件的替代组件 |
JComboBox | 带下拉列表的文本框,它是AWT选择组件的替代组件 |
JComponent | 所有轻量J组件的基类 |
JDesktopPane | 内部窗体的容器 |
JDialog | Swing对话框的基类,它扩展了AWT Dialot类 |
JEditorPane | 用于编辑文本的文本窗格 |
JFrame | 扩展java.awt.Frame的外部窗体 |
JInternalFrame | 在JDesktopPane中出现的内部窗体 |
JLabel | 可显示文本和图标的标签,它是AWT标签组件的替代组件 |
JLayeredPane | 能够在不同层上显示组件的容器 |
JList | 显示选项列表的组件,它是AWT列表组件的替代组件 |
JMenu | 菜单条中显示的一个菜单,它是AWT菜单组件的替代组件 |
JMenuBar | 用于显示菜单的菜单条,它是AWT菜单条组件的替代组件 |
JMenuItem | 菜单项,它是AWT菜单项组件的替代组件 |
JOptionPane | 显示标准的对话框,如:消息和问题对话框 |
JPanel | 通用容器,它是AWT面板和画布组件的替代组件 |
JPasswordfield | JTextField的扩展,使输入的字符不可见 |
JPopupMenu | 弹出式菜单,它是AWT弹出式菜单组件的替代组件 |
JProgressBar | 进度指示器 |
JRadioButton | 单选按钮,它是AWT复选框组件的替代组件 |
JRootPane | 顶层容器,它包含一个玻璃窗格,一个层窗格,一个内容窗格和一个可选的菜单条 |
JScrollBar | 滚动条,它是AWT滚动条组件的替代组件 |
JScrollPane | 滚动窗格,它是AWT滚动窗格组件的替代组件 |
JSeparator | 水平或垂直分隔条 |
JSlider | 滑杆 |
JSplitPane | 有两个分隔区的容器,这两个分隔区可以水平排列或者垂直排列且分隔区的大小能自动调整 |
JTabbedPane | 带选项卡的窗格 |
JTable | 表格 |
JTableHeader | 表格头 |
JTextArea | 用于输入多行文本的文本域,它是AWT文本域组件的替代组件 |
JTestComponent | 文本组件的基类,它替代AWT的TextComponent类 |
JTextField | 单行文本域,它替代AWT的单行文本域组件 |
JTextPane | 简单的文本编辑器 |
JToggleButton | 两种状态的按钮,它是JCheckBox和JRadioButton组件的基类 |
JToolBar | 工具条 |
JToolTip | 当光标停留在一个组件上时,该组件上显示的一行文字 |
JTree | 用于按钮层次组织数据的结构控件 |
JViesport | 用于浏览可滚动组件的视口 |
JWindow | 外部窗口,它是java.awt.Window的扩展 |
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
注:斜体字表示的是AWT的替代组件
二、AWT和Swing的区别
AWT是Abstract Window ToolKit (抽象窗口工具包)的缩写,这个工具包提供了一套与本地图形界面进行交互的接口。AWT 中的图形函数与操作系统所提供的图形函数之间有着一一对应的关系,我们把它称为peers。 也就是说,当我们利用 AWT 来构件图形用户界面的时候,我们实际上是在利用操作系统所提供的图形库。由于不同操作系统的图形库所提供的功能是不一样的,在一个平台上存在的功能在另外一个平台上则可能不存在。为了实现Java语言所宣称的"一次编译,到处运行"的概念,AWT 不得不通过牺牲功能来实现其平台无关性,也就是说,AWT 所提供的图形功能是各种通用型操作系统所提供的图形功能的交集。由于AWT 是依靠本地方法来实现其功能的,我们通常把AWT控件称为重量级控件。
Swing 是在AWT的基础上构建的一套新的图形界面系统,它提供了AWT所能够提供的所有功能,并且用纯粹的Java代码对AWT 的功能进行了大幅度的扩充。例如说并不是所有的操作系统都提供了对树形控件的支持, Swing 利用了AWT 中所提供的基本作图方法对树形控件进行模拟。由于 Swing 控件是用100%的Java代码来实现的,因此在一个平台上设计的树形控件可以在其他平台上使用。由于在Swing 中没有使用本地方法来实现图形功能,我们通常把Swing控件称为轻量级控件。
AWT和Swing之间的基本区别:AWT 是基于本地方法的C/C++程序,其运行速度比较快;Swing是基于AWT 的Java程序,其运行速度比较慢。对于一个嵌入式应用来说,目标平台的硬件资源往往非常有限,而应用程序的运行速度又是项目中至关重要的因素。在这种矛盾的情况下,简单而高效的AWT 当然成了嵌入式Java的第一选择。而在普通的基于PC或者是工作站的标准Java应用中,硬件资源对应用程序所造成的限制往往不是项目中的关键因素,所以在标准版的Java中则提倡使用Swing,也就是通过牺牲速度来实现应用程序的功能。
简要的讲:
AWT 是抽象窗口组件工具包,是 java 最早的用于编写图形节目应用程序的开发包。
Swing 是为了解决 AWT 存在的问题而新开发的包,它以 AWT 为基础的。
三、Swing基本框架
上图列举了AWT和 Swing的关系,也可以看出Swing是继承自AWT的。本文主要利用Swing来设计图形化界面程序。
四、图形化设计步骤
图形化界面程序大家都使用过,一般使用一个程序过程是:打开一个程序出现一个窗口或对话框,其中一般有菜单、工具栏、文本框、按钮、单选框、复选框等控件(组件也就是控件),用户录入相关数据,点按相关菜单、按钮,程序对数据进行相关处理,并将处理后的数据显示或者保存起来,最后关闭程序。
用java编程的相关设计步骤来分解上面的的程序运行过程如下图所示:
1、 创建顶层容器
对应于程序的初始显现窗口,窗口中放入其它菜单、工具栏、文本框、按钮等组件
顶层容器图形化界面显示的基础,其它所有的组件(控件)都是直接或间接显示在顶层容器中的。在java中顶层容器有三种,分别是JFrame(框架窗口,即通常的窗口)、JDialog(对话框)、JApplet(用于设计嵌入在网页中的java小程序)。
2、 创建中间容器、组件
对应于程序中出现的菜单、工具栏(中间容器)、文本框、按钮、单选框、复选框等控件。
有很多Swing组件可以使用,见前面的Swing UI组件表。
3、 将组件加入容器
在java中创建组件后,还需要将组件放入相应的容器,才能在顶层容器,如窗口中显示出组件。
4、 设置容器内组件的位置
组件添加到容器中,还必须设置好组件的显示位置,一般有两种方法来设置组建的显示位置,一是按照与容器的相对距离(以像素为单位),精确固定控件的位置;二是用布局管理器来管理组件在容器内的位置。
5、 处理组件所产生的事件
即用户执行选择菜单、单击按钮等操作时,就要执行相应的命令,进行相关的程序处理,这就需要设置组件的事件。
五、组件容器的使用
Java中组件容器包含顶层容器和中间容器。
在java中顶层容器有三种,分别是JFrame(框架窗口,即通常的窗口)、JDialog(对话框)、JApplet(用于设计嵌入在网页中的java小程序),顶层容器是容纳其它组件的基础,即设计图形化程序必须要有顶层容器。
Java中间容器是可以包含其它相应组件的容器,但是中间容器和组件一样,不能单独存在,必须依附于顶层容器。
常见的中间容器有:
• JPanel:最灵活、最常用的中间容器。
• JScrollPane:与 JPanel 类似,但还可在大的组件或可扩展组件周围提供滚动条。
• JTabbedPane:包含多个组件,但一次只显示一个组件。用户可在组件之间方便地切换。
• JToolBar:按行或列排列一组组件(通常是按钮)。
1、JFrame 框架窗口的使用
以上是JFrame的常用方法即说明,下面举例说明。
实例1:直接定义Jframe 类的对象创建一个窗口
// JFrameDemo1.java import javax.swing.*; //使用Swing类,必须引入Swing包 public class JFrameDemo1 { public staticvoid main(String args[]) { // 定义一个窗体对象f,窗体名称为"一个简单窗口" Jframe f = new JFrame("一个简单窗口"); /* * 设置窗体左上角与显示屏左上角的坐标, * * 离显示屏上边缘300像素,离显示屏左边缘300像素 */ f.setLocation(300, 300); // f.setLocationRelativeTo(null);本语句实现窗口居屏幕中央 f.setSize(300, 200); // 设置窗体的大小为300*200像素大小 f.setResizable(false); // 设置窗体是否可以调整大小,参数为布尔值 // 设置窗体可见,没有该语句,窗体将不可见,此语句必须有,否则没有界面就没有如何意义了 f.setVisible(true); // 用户单击窗口的关闭按钮时程序执行的操作 f.setDefaultCloseOperation(f.EXIT_ON_CLOSE); } }
程序运行结果如下图所示:
可以根据程序代码的注释,依次修改相应的方法参数查看效果。
setDefaultCloseOperation(int operation):设置用户在此窗体上发起 "close" 时默认执行的操作。方法中的参数解释如下:
l 为“0”或DO_NOTHING_ON_CLOSE:
(在 WindowConstants 中定义):不执行任何操作;要求程序在已注册的WindowListener 对象的 windowClosing 方法中处理该操作。
比如实例程序代码中更改为f.setDefaultCloseOperation(f. DO_NOTHING_ON_CLOSE);或者f.setDefaultCloseOperation(0),然后查看效果,可以发现窗口无法关闭,下面是相同用法,不再解释了。
l 为“1”或HIDE_ON_CLOSE
调用任意已注册的 WindowListener 对象后自动隐藏该窗体。此时没有关闭程序,只是将程序界面隐藏了。
可以打开任务管理器,可以看到一个叫“java.exe”的进程(如果调试运行了多个java程序,则会看到多个“java.exe”的进程),如果此时用EditPlus 测试程序,会发现当单击窗口的关闭按钮关闭窗口后,却无法再次对程序进行调试,因为程序线程没有关闭,在任务管理器中关闭java.exe(如果有多个“java.exe”的进程,则先都关闭掉,再来测试该问题)基础后,EditPlus才可以重新编译改程序。
l 为“2”或DISPOSE_ON_CLOSE
调用任意已注册 WindowListener 的对象后自动隐藏并释放该窗体。但继续运行应用程序,释放了窗体中占用的资源。
l 为“3”EXIT_ON_CLOSE(在 JFrame 中定义):使用 System exit 方法退出应用程序。仅在应用程序中使用。结束了应用程序。
默认情况下,该值被设置为 HIDE_ON_CLOSE。
当注释掉实例中的f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);语句时,起到的效果和f.setDefaultCloseOperation(f. HIDE_ON_CLOSE); 或者f.setDefaultCloseOperation(1);一样。
实例2:创建类继承JFrame类创建一个窗口
// JFrameDemo2.java importjavax.swing.*; //创建子类MyFrame继承父类JFrame class MyFrame extends JFrame { // 定义构造函数,带有四个参数,用于设置窗口位置和大小 MyFrame(int x, int y, int h, int w) { super("一个简单窗口"); // 重写父类方法,为窗口定义标题 /* * 以下的方法调用前面没有添加对象名,也不可能添加,要创建的对象名称是什么都不知道,也就不可能添加。但是创建对象后,对象自动获取这些初始值。 */ setLocation(x, y); setSize(h, w); setResizable(false); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); } } public class JFrameDemo2{ public static void main(String args[]) { // 实例化类对象,提示设置参数 MyFrame f = new MyFrame(300, 300, 300, 200); } }
上面的例子也可以不使用构造函数,可以和实例一方式一样,代码可以改为如下模式。
实例3:一个简单窗口
// JframeDemo3.java import javax.swing.*; class MyFrame extends JFrame { MyFrame(){ } } public class JframeDemo3 { public static void main(String args[]) { MyFrame f = new MyFrame(); f.setTitle("一个简单窗口"); f.setLocationRelativeTo(null); f.setSize(300, 200); f.setResizable(false); f.setVisible(true); f.setDefaultCloseOperation(3); } }