一、引言
Java 的图形用户界面(GUI)编程为开发者提供了丰富的工具和组件,使得创建直观、交互性强的应用程序变得更加容易。本文将深入介绍 Java 基础中的 GUI,包括其概念、组件、布局管理器以及事件处理等方面的知识。
Java 的图形用户界面(GUI)是一种通过图形化的方式与用户进行交互的界面。它为用户提供了直观、便捷的操作方式,使得用户能够更加轻松地使用应用程序。在 Java 中,为 GUI 提供的对象都在java.awt和javax.swing两个包中。
(一)GUI 概述
- GUI 的定义
-
- GUI 即图形用户接口(Graphical User Interface),用图形的方式显示计算机的界面,更加方便直观。
- Java 中 GUI 的实现
-
- Java 中为 GUI 提供的对象都在java.awt和javax.swing两个包中。
-
-
- java.awt包:Abstract Window Toolkit(抽象窗口工具包),需要调用本地系统方法实现功能,属重量级控件。
-
-
-
- javax.swing包:在AWT的基础上,建立的一套图形界面系统,其中提供了更多的组件,而且完全由 Java 实现,增加了移植性,属轻量级控件。
-
-
- Container:为容器,是一个特殊的组件,该组件中可以通过add方法添加其他组件进来。
(二)布局管理器
- 布局的概念
-
- 容器中的组件的排放方式就是布局。
- 常见的布局管理器
-
- FlowLayout(流式布局管理器):组件按从左到右的顺序排列,这是Panel组件默认的布局管理器。
-
- BorderLayout(边界布局管理器):组件按东、南、西、北、中的位置排放,默认放置在中。
-
- GridLayout(网格布局管理器):组件按规则的矩阵排放。
-
- GridBagLayout(网格包布局管理器):组件按非规则的矩阵排放。
(三)Component 类
- Component 类的定义
-
- Component类是一个抽象类,是与菜单不相关的 Abstract Window Toolkit 组件的抽象超类,是一个具有图形表示能力的对象,可在屏幕上显示,并可与用户进行交互。
(四)Container 类
- Container 类的定义
-
- Container类是Component类的一个子类,是一个可包含其他 AWT 组件的容器。
- Container 类的方法
-
- add方法:该方法可以将指定组件追加到Container容器的尾部。
(五)Frame 类
- Frame 类的定义
-
- Frame是带有标题和边框的顶层窗口。其默认布局为BorderLayout。
- Frame 类的方法
-
- Frame():构造一个最初不可见的Frame新实例。
-
- Frame(String title):构造一个新的、最初不可见的、具有指定标题的Frame对象。
-
- void setVisible(Boolean b):根据参数b的值显示或隐藏此组件。
-
- void setSize(int wid,int hei):调整组件的大小,使其宽度为wid,高度为hei,单位是像素。
-
- void setLocation(int x,int y):通过此组件父级坐标空间中的x和y参数来指定新位置的左上角。
-
- void setLayout(LayoutManager mgr):设置此容器的布局管理器。
-
- void setTitle(String title):此窗体的标题设置为指定的字符串。
- 创建图形化界面步骤
-
- 创建frame窗体。
-
- 对窗体进行基本设置,如大小,位置,布局。
-
- 定义组件。
-
- 将组件通过窗体的add方法添加到窗体中。
-
- 让窗体显示,通过setVisible(true)。
- 示例
import java.awt.*;
public class AwtDemo{public static void main(String[] args){//创建一个窗体Frame f=new Frame("myframe");//设置窗体的大小f.setSize(500,400);//调整窗体的位置f.setLocation(300,200);//设置窗体的布局管理器f.setLayout(new FlowLayout());//创建一个按钮Button b=new Button("mybutton");//将按钮添加到窗体中f.add(b);//设置窗体为可见f.setVisible(true);}
}
(六)事件监听机制
- 事件监听机制组成
-
- 事件源(组件):即awt包或swing包中的那些图形界面组件。
-
- 事件(Event):每一个事件源都有自已特有的对应事件和共性事件。
-
- 监听器(Listener):将可以触发某一个事件的动作都已经封装到了监听器中。
-
- 事件处理:引发事件后处理方式。事件源、事件和监听器在 JAVA 中都已经定义好了,直接获取其对象来用就可以了,我们要做的就是对产生的动作进行处理。
- 事件监听机制流程图
-
- 用户对组件的操作就是一个事件,那么产生事件的组件就是事件源,接收并处理事件,与用户进行交互的行为就是事件处理器,这些处理方式都封装在监听器中。
(七)窗体事件
- 处理窗体事件的方法
-
- 要处理窗体事件需要添加窗口监听器以监听窗口事件,可以通过addWindowListener(WindowListener l)方法添加一个窗口监听器。
- WindowListener 接口和 WindowAdapter 类
-
- WindowListener:是一个接口,用于接收窗口事件的侦听器。旨在处理窗口事件的类要么实现此接口(及其包含的所有方法),要么扩展抽象类WindowAdapter(仅重写所需的方法)。
-
- WindowAdapter:是一个抽象类,是接收窗口事件的抽象适配器类,该类实现WindowListener接口,并覆盖了该接口的所有方法,且将方法覆盖为空。此类存在的目的是方便创建侦听器对象。扩展此类可创建WindowEvent侦听器并为所需事件重写该方法。所在在创建窗口监听器时不需要去实现WindowListener接口且覆盖该接口的所有方法,只需继承WindowAdapter类并复写其中所需要的方法即可。
- 示例
import java.awt.*;
import java.awt.event.*;
public class AwtDemo2{public static void main(String[] args){//创建一个窗体Frame f=new Frame("myframe");//设置窗体的大小f.setSize(500,400);//调整窗体的位置f.setLocation(300,200);//设置窗体的布局管理器f.setLayout(new FlowLayout());//添加窗口监听器,参数是一个`WindowAdapter`的子类对象,此处采用匿名内部类的形式//此匿名内部类中只复写了`WindowAdapter`的`windowClosing`方法f.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent e){System.exit(0);}});//设置窗体为可见f.setVisible(true);}
}
(八)Action 事件
- 处理 Action 事件的方法
-
- 处理Action事件需要添加一个ActionListener监听器。添加ActionListener监听器可以用组件的addActionListener(ActionListener l)方法。
- ActionListener 接口
-
- ActionListener:一个接口,用于接收操作事件的侦听器接口,对处理操作事件感兴趣的类可以实现此接口,而使用该类创建的对象可使用组件的addActionListener方法向该组件注册。在发生操作事件时,调用该对象的actionPerformed方法。
- actionPerformed 方法
-
- actionPerformed(ActionEvent e)方法:是ActionListener的一个方法。在发生操作时调用。
二、Java GUI 基础概念
1. GUI 与 CLI 的区别
- GUI 介绍:Graphical User Interface(图形用户接口),用图形的方式显示计算机操作界面,方便直观。相比于 Command line User Interface(命令行用户接口),GUI 无需记忆常用命令,用户通过直观的图形界面进行操作,大大提高了易用性。例如,在日常使用的操作系统中,我们可以通过鼠标点击图标、菜单等进行各种操作,而不是像 CLI 那样需要记住特定的命令才能完成任务。
- CLI 介绍:Command line User Interface(命令行用户接口),需要记忆常用命令,操作不直观。对于新用户来说,CLI 的上手难度较高,因为需要记住各种命令和语法。然而,对于一些专业人士或系统管理员来说,CLI 可能更加高效,因为可以通过键盘快速输入命令来完成复杂的任务。但对于大多数普通用户而言,GUI 更加友好和易于使用。
2. Java 中的 GUI 工具包
- AWT 和 Swing:Java 为 GUI 提供的对象都在 java.Awt 和 javax.Swing 两个包中。AWT 是抽象窗口工具包,需要调用本地系统方法实现功能,属于重量级控件;Swing 在 AWT 的基础上建立,完全由 Java 实现,增强了移植性,属轻量级控件。
AWT(Abstract Window Toolkit)是 Java 早期的图形用户界面工具包,它提供了一组基本的 GUI 组件和窗口管理功能。由于 AWT 组件是重量级控件,它们依赖于本地系统的窗口组件,因此在不同的操作系统上可能会有不同的外观和行为。
Swing 是在 AWT 的基础上构建的一套新的图形界面系统,它提供了比 AWT 更丰富的 GUI 组件,并且完全由 Java 实现。这使得 Swing 组件具有更好的移植性,在不同的平台上可以保持一致的外观和行为。
AWT 和 Swing 之间的区别主要体现在以下几个方面:
- 实现原理不同:AWT 的图形函数与操作系统提供的图形函数有着一一对应的关系,而 Swing 则是用纯粹的 Java 代码对 AWT 的功能进行了大幅度的扩充。
- 运行速度不同:AWT 是基于本地方法的 C/C++ 程序,运行速度比较快;Swing 是基于 AWT 的 Java 程序,运行速度比较慢。
- 平台表现不同:AWT 的控件在不同的平台可能表现不同,而 Swing 在所有平台表现一致。
在实际应用中,应根据具体情况选择使用 AWT 还是 Swing。对于嵌入式应用,目标平台的硬件资源有限,应用程序的运行速度至关重要,此时可以选择简单而高效的 AWT。而对于普通的基于 PC 或者工作站的标准 Java 应用,硬件资源对应用程序所造成的限制往往不是关键因素,此时可以选择功能更强大、移植性更好的 Swing。
三、布局管理器
1. 常见布局管理器介绍
Java 中的布局管理器为开发者提供了多种方式来组织和排列 GUI 组件。以下是对常见布局管理器的详细介绍:
- FlowLayout(流式布局管理器):从左到右的顺序排列,是 Panel 默认的布局管理器。FlowLayout 按照组件被添加到容器中的顺序来排列组件。先添加的组件出现在前面,随后添加的组件排在后面。它支持三种对齐方式 — 左对齐、居中对齐(默认值)和右对齐。对齐方式可以在创建 FlowLayout 实例时指定,还可以设置组件之间的水平和垂直间距。例如 new FlowLayout(FlowLayout.LEFT,10, 20) 会创建一个左对齐的 FlowLayout,其中组件之间的水平间距为 10 像素,垂直间距为 20 像素。在流式布局管理器中,容器会将组件按照添加顺序从左到右依次放置,当到达边界时会自动将组件放置到下一行开始的位置。
- BorderLayout(边界布局管理器):东、南、西、北、中,是 Frame 默认的布局管理器。BorderLayout 可以将容器划分为五个区域,分别是东、西、南、北、中,在添加组件时需要使用 add(Component comp,Object constraints) 方法。comp 表示要添加的组件,constraints 指定将组件添加到布局中的方式和位置的对象,它是一个 Object 类型,在传参数时提供 EAST,SOUTH,WEST,NORTH,CENTRE。如果在添加时,不指定添加到哪个区域,则默认添加到 CENTRE 区域,并且每个区域只能放置一个组件,如果向一个区域中添加多个组件时,后放入的组件会覆盖先放入的组件。
- GridLayout(网格布局管理器):规则的矩阵。GridLayout 可以把容器分成 n 行 m 列大小相等的网格,每个网格放置一个组件,按照从左往右,从上往下的顺序依次添加,放置在 GridLayout 布局管理器的组件将自动占据网格的整个区域。GridLayout 构造方法有多种,如 GridLayout()(默认只有一行,每个组件占一列)、GridLayout(int rows,int cols)(指定容器的行数和列数)以及可以指定容器的行数和列数以及组件之间的水平,垂直间距的构造方法。GridLayout 布局管理器的特点是组件的相应位置不随区域的缩放而改变,但组件的大小会随之改变,组件始终占据网格的整个区域,其缺点是忽略组件的最佳大小,所有组件的宽高都相同。
- CardLayout(卡片布局管理器):选项卡。卡片布局能够让多个组件共享同一个显示空间,共享空间的组件之间的关系就像一叠牌,组件叠在一起,初始时显示该空间中第一个添加的组件,通过 CardLayout 类提供的方法可以切换该空间中显示的组件。
- GridBagLayout(网格包布局管理器):非规则的矩阵。
四、监听机制
- 事件源:awt包或者swing包中的图形界面组件,如按钮、文本框等。
- 事件:每个事件源都有自己特有的对应事件和共性事件。例如,按钮可能有点击事件,窗口可能有关闭事件等。
- 监听器:将触发事件的动作封装到监听器中。监听器可以是xxxListener或者xxxAdapter的形式。
3. 事件监听机制的使用
- 确定事件源(容器或组件):首先需要确定哪个图形界面组件是事件的源头。例如,一个按钮可以是事件源,当用户点击按钮时,触发一个事件。
- 通过事件源对象的 addxxxListener () 方法将监听器注册到该事件源上:使用事件源对象的特定方法,如addActionListener()或addWindowListener()等,将监听器注册到事件源上。这样,当事件发生时,监听器就能够接收到通知。
- 接收 xxxListener 的子类对象或 xxxListener 的子类 xxxAdapter 的子类对象,一般用匿名内部类来表示:在注册监听器时,可以接收xxxListener的子类对象或者xxxListener的子类xxxAdapter的子类对象。通常使用匿名内部类的形式来实现,这样可以方便地定义监听器的行为。
- 覆盖方法时,参数一般是 xxxEvent 类型的变量接收:在实现监听器接口的方法时,参数一般是特定类型的事件对象,如ActionEvent、WindowEvent等。通过这个事件对象,可以获取与事件相关的信息。
- 事件触发后会把事件打包成对象传递给变量,可通过 getSource () 或 getComponent () 获取事件源对象:当事件被触发时,事件会被打包成一个对象,并传递给监听器的方法。在方法中,可以通过getSource()或getComponent()方法获取事件源对象,从而进行进一步的处理。
五、GUI 组件的使用
1. 窗体(Frame)
Java 中的窗体(Frame)是带有标题和边框的顶层窗口。它的默认布局是边界式布局(BorderLayout)。
1. 构造方法:
- 默认情况下,创建一个 Frame 对象时,它最初是不可见的。可以使用Frame()构造一个最初不可见的 Frame 新实例;也可以使用Frame(String title)构造一个新的、最初不可见的、具有指定标题的 Frame 对象。
2. 常用方法:
- addWindowListener():添加窗口侦听器,用于监听窗口事件。例如,可以通过这个方法添加一个监听器来处理窗口关闭事件。
- setBounds():设置位置和大小。通过指定左上角的坐标(x,y)以及宽度和高度来确定窗体在屏幕上的位置和大小。
- setSize():设置大小,仅指定窗体的宽度和高度。
- setLocation():设置位置,仅指定窗体左上角在屏幕上的坐标。
- setLayout():设置布局,用于确定窗体中组件的排列方式。
- setVisible():设置隐藏和显示,决定窗体是否可见。
- add():向窗体中添加其他组件,如按钮、文本框等。
2. 按钮(Button)
按钮(Button)在 Java 的 GUI 中是一个常用的组件,用于触发特定的操作。
1. 构造方法:
- 可以构造一个标签字符串为空的按钮,也可以带指定标签的按钮。例如JButton()创建一个没有标题的按钮对象,JButton(String s)创建一个标题为 s 的按钮对象。
2. 常用方法:
- addActionListener():添加动作监听,当按钮被点击时触发相应的动作。
- getLabel():获取按钮的标签,即按钮上显示的文本。
- setLabel():设置按钮的标签,用于更改按钮上显示的文本。
3. TextField 和 TextArea
1. TextField(单行文本框):
- TextField 是允许编辑单行文本的文本组件。
-
- 构造方法包括无参数、指定列数、指定初始化文本和指定初始化文本和列数。例如JTextField()文本框的字符长度为 1;JTextField(int columns)文本框初始值为空字符串,文本框的字符长度设为 columns;JTextField(String text)文本框初始值为 text 的字符串;JTextField(String text, int columns)文本框初始值为 text,文本框的字符长度为 columns。
-
- 常用方法有addActionListener()、addTextListener()、addKeyListener()、addMouseListener()等,可以为文本框添加不同类型的监听器。setText()用于在文本框中设置文本,getText()获取文本框中的文本。
2. TextArea(多行文本区域):
- TextArea 是显示文本的多行区域,可以设置为允许编辑或只读。
-
- 构造方法包括无参数、指定行列、指定初始化值和指定行列和初始化值。例如JTextArea()以默认的列数和行数,创建一个文本区对象;JTextArea(String s)以 s 为初始值,创建一个文本区对象;JTextArea(Strings,int x,int y)以 s 为初始值,行数为 x,列数为 y,创建一个文本区对象;JTextArea(int x,int y)以行数为 x,以列数为 y,创建一个文本区对象。
-
- 当鼠标按键在组件上单击时,可以通过添加鼠标监听器来响应这个事件。此外,setText()可以设置显示文本,同时清除原有文本;getText()获取文本区的文本;insert(String s,int x)在指定的位置插入指定的文本;replace(String s,int x,int y)用给定的一替换从 x 位置开始到 y 位置结束的文本;append(String s)在文本区追加文本;getCarePosition()获取文本区中活动光标的位置;setCarePosition(int n)设置活动光标的位置;setLineWrap(boolean b)设置自动换行,缺省情况,不自动换行。当文本区中的内容较多,不能在文本区全部显示时,可给文本区配上滚动条,如JTextArea ta = new JTextArea();JScrollPane jsp = new JScrollPane(ta);。
六、示例演示
1. 建立简单窗体
在 Java 中,创建简单窗体可以通过以下步骤实现。首先,创建一个Frame窗体对象,如Frame f = new Frame("my frame");。然后,对窗体进行基本设置,包括大小、位置和布局等。例如,可以使用f.setSize(int wid,int hei)方法设置窗体大小,f.setLocation(int x,int y)方法调整窗体位置,f.setLayout(LayoutManager mgr)设置布局管理器,这里可以选择FlowLayout、BorderLayout等常见的布局管理器。接着,定义组件,如创建一个按钮Button b = new Button("my button");。最后,将组件通过窗体的add方法添加到窗体中,即f.add(b),并通过f.setVisible(true)让窗体显示出来。
简单窗体的事件监听可以通过添加监听器来实现。例如,要处理窗体事件,可以添加窗口监听器以监听窗口事件,可以通过addWindowListener(WindowListener l)方法添加一个窗口监听器。参数是一个WindowAdapter的子类对象,此处可以采用匿名内部类的形式。比如:f.addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent e){System.exit(0);}}),这样当窗体关闭事件发生时,程序会退出。
2. 在窗体中通过按钮关闭窗体
将图形化界面和事件分离,让按钮具备退出程序的功能可以通过以下方式实现。首先,创建一个按钮对象,如Button button = new Button("关闭");。然后,为按钮添加一个动作监听器,可以使用button.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {System.exit(0);}})。这样,当用户点击按钮时,程序会退出。
选择监听器的方法需要根据具体的需求来确定。对于按钮的动作事件,可以选择ActionListener监听器。添加监听器可以用组件的addActionListener(ActionListener l)方法。在注册监听器时,可以接收xxxListener的子类对象或者xxxListener的子类xxxAdapter的子类对象。通常使用匿名内部类的形式来实现,这样可以方便地定义监听器的行为。覆盖方法时,参数一般是xxxEvent类型的变量接收。事件触发后会把事件打包成对象传递给变量,可通过getSource()或getComponent()获取事件源对象。
七、插件介绍
WindowBuilder 的安装和使用
WindowBuilder 是一个强大的插件,可用于在 Eclipse 中进行 Java GUI 编程。下面介绍其在线安装方法和使用步骤。
一、在线安装方法
- 在 Eclipse 中,依次点击 “Help”→“Eclipse Marketplace”。
- 在 “find” 中搜索 “windowBuilder”,点击 “install” 安装即可。不过需要注意的是,2014 年之前的 Eclipse 版本没有该功能。
二、使用步骤
- 在项目中使用插件创建 GUI 界面,首先需要在 Eclipse 中搜索并安装 WindowBuilder 插件。安装完成后,重启 Eclipse。
- 打开已有的项目或者创建一个新的项目。
- 在项目的包资源管理器中,右键点击项目名称,选择 “New”→“Other”。
- 在弹出的对话框中,找到 “WindowBuilder”→“Swing Designer”(如果要使用 SWT Designer 也可以,但 SWT Designer 兼容性没有 Swing Designer 好,Swing Designer 里面的控件都是 JXXXX 形式的,更适合 Java 使用)。
- 可以选择 “Application Window”,一般也就是应用窗口,点击 “Next”。类似于新建类,在后续对话框中输入 Name 和 Package。
- Finish 后,即可得到一个带有预先生成代码的空白窗体。点击代码窗口左下角新出现 “Design” 标签,可以使用 WindowBuilder Editor 可视化地查看窗体(也可以在生成的类文件上点击右键,选择 “Open With”→“WindowBuilder Editor”)。
- 在 WindowBuilder Editor 的界面中,可以使用绝对定位(点击 “Layouts” 下的 “Absolute layout”,再点击窗体),然后点击 “Components” 下的各种组件(如 “JTextField”、“JButton”、“JLabel” 等),再点击窗体进行添加,并可以修改其属性。
- 为组件添加事件监听,例如为按钮添加动作监听,可以在按钮上右键点击,选择添加监听的方式(如双击按钮,选择添加监听),然后在 “Source” 标签下的代码编辑器中会自动生成一些代码,可以在其中编写事件处理逻辑。
通过以上步骤,就可以使用 WindowBuilder 插件在 Eclipse 中轻松创建 GUI 界面。
八、总结
Java 的 GUI 编程提供了丰富的工具和组件,通过合理使用布局管理器、监听机制和各种组件,可以创建出功能强大、交互性强的图形用户界面应用程序。同时,插件的使用可以提高开发效率,让开发者更加专注于业务逻辑的实现。
在 Java 的 GUI 编程中,我们可以使用多种布局管理器来组织和排列组件,如 FlowLayout、BorderLayout、GridLayout、CardLayout 和 GridBagLayout 等。这些布局管理器各有特点,可以根据不同的需求进行选择。
监听机制是 Java GUI 编程中的重要组成部分,它由事件源、事件、监听器和事件处理组成。通过监听机制,我们可以对用户的操作进行响应,实现交互性强的图形用户界面应用程序。
在 Java 的 GUI 编程中,我们还可以使用各种组件来创建图形用户界面,如窗体(Frame)、按钮(Button)、TextField 和 TextArea 等。这些组件可以通过布局管理器进行组织和排列,实现美观、易用的图形用户界面应用程序。
此外,我们还可以使用插件来提高 Java GUI 编程的效率,如 WindowBuilder 和 JFormDesigner 等。这些插件可以提供可视化的界面设计工具,让开发者更加专注于业务逻辑的实现。
总之,Java 的 GUI 编程提供了丰富的工具和组件,通过合理使用布局管理器、监听机制和各种组件,可以创建出功能强大、交互性强的图形用户界面应用程序。同时,插件的使用可以提高开发效率,让开发者更加专注于业务逻辑的实现。