Java图形用户界面
Java API中提供了AWT和Swing包(类库)支持编写图形用户界面。一个图形用户界面是屏幕上的一个程序窗口。窗口的组成:
窗口标题:位于窗口上方,用于显示程序名称或功能。
菜单栏:位于窗口标题下方,通常,一个菜单栏会包含多个菜单,每个菜单会包含多个菜单项,图形用户界面程序将程序功能通过菜单组织起来,用户通过菜单选择程序功能(注:菜单栏可以省略)。
内容面板:内容面板是窗口的主体,是程序为用户提供的工作区,程序可以在内容面板上摆放图形组件,实现输入原始数据、查看处理结果、选择程序操作等功能。
组件是Java API预先定义好的,可提供不同功能的图形零件。主要包括:按钮、标签。文本框等。
先给出一个简单例子:
例 、一个用JFrame类创建窗口的Java应用程序。窗口只有一个按钮,代码如下:
import javax.swing.*;
public class ExampleA {
public static void main(String[] args) {
// 1. 创建一个顶层容器(窗口)
JFrame jf = new JFrame("测试窗口"); // 创建窗口
jf.setSize(250, 250); // 设置窗口大小
jf.setLocationRelativeTo(null); // 把窗口位置设置到屏幕中心
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // 当点击窗口的关闭按钮时退出程序(没有这一句,程序不会退出)
// 2. 创建中间容器(面板容器)
JPanel panel = new JPanel(); // 创建面板容器,使用默认的布局管理器
// 3. 创建一个基本组件(按钮),并添加到 面板容器 中
JButton btn = new JButton("测试按钮");
panel.add(btn);
// 4. 把 面板容器 作为窗口的内容面板 设置到 窗口
jf.setContentPane(panel);
// 5. 显示窗口,前面创建的信息都在内存中,通过 jf.setVisible(true) 把内存中的窗口显示在屏幕上。
jf.setVisible(true);
}
运行之,显示为:
AWT和Swing
在Java 1.0时代便有设计GUI(图形用户界面程,Graphical User Interface)的基本类库Abstract Window Toolkit,简称AWT。AWT库工作原理是将处理用户界面元素的任务委派给目标平台(操作系统)的本地GUI工具箱,由本地GUI工具箱负责用户界面元素的创建和动作,包(类库)java.awt。不久又创建了名为Swing的用户界面库,包(类库)javax.swing 。Swing没有完全取代AWT的原因是:Swing是基于AWT的架构之上,Swing仅仅是提供了能力更强大的用户界面组件。Swing可以看作是AWT的改良版,而不是代替AWT,是对AWT的提高和扩展。所以,在写GUI程序时,Swing和AWT都要作用。它们共存于Java基础类(Java Foundation Class,JFC)中。
Swing组件类都以“J”开头,如 JButton,JFrame等,AWT组件不带“J"。
尽管AWT和Swing都提供了构造图形界面元素的类,但它们的重要方面有所不同:AWT依赖于主平台绘制用户界面组件;而Swing有自己的机制,在主平台提供的窗口中绘制和管理界面组件。Swing与AWT之间的最明显的区别是界面组件的外观,AWT在不同平台上运行相同的程序,界面的外观和风格可能会有一些差异。然而,一个基于Swing的应用程序可能在任何平台上都会有相同的外观和风格。
Swing是基于AWT的架构之上,Swing仅仅是提供了能力更强大的用户界面组件。在Swing编写的程序中,还是需要AWT进行事件处理。简单说就是,Swing是用户界面类,AWT是底层机制。使用Swing设计图形界面,主要引入两个包:
javax.swing包:包含Swing的基本类;
java.awt.event包:包含与处理事件相关的接口和类。
组件和容器
组件(component)是图形界面的基本元素,用户可以直接操作,例如按钮。容器(Container)是图形界面的的复合元素,容器可以包含组件。
Java语言为每种组件都预定义类,程序通过它们或它们的子类各种组件对象,如,Swing中预定义的按钮类JButton是一种类,程序创建的JButton对象,或JButton子类的对象就是按钮。Java语言也为每种容器预定义类,程序通过它们或它们的子类创建各种容器对象。例如,Swing中预定义的窗口类JFrame是一种容器类,程序创建的JFrame或JFrame子类的对象就是窗口。
为了统一管理组件和容器,为所有组件类定义超类,把组件的共有操作都定义在Component类中。同样,为所有容器类定义超类Container类,把容器的共有操作都定义在Container类中。例如,Container类中定义了add()方法,大多数容器都可以用add()方法向容器添加组件。
Component、Container和Graphics类是AWT库中的关键类。为能层次地构造复杂的图形界面,容器被当作特殊的组件,可以把容器放入另一个容器中。例如,把若干按钮和文本框分放在两个面板中,再把这两个面板和另一些按钮放入窗口中。这种层次地构造界面的方法,能以增量的方式构造复杂的用户界面。
Swing组件
一个 Java 的图形界面,由各种不同类型的“元素”组成,例如: 窗口、菜单栏、对话框、标签、按钮、文本框等等,这些“元素”统一被称为 组件(Component)。
组件按照不同的功能,可分为 顶层容器、中间容器、基本组件。一个简单窗口的组成,如下层级结构所示:
- 顶层容器
- 菜单栏
- 中间容器
- 基本组件
- 基本组件
组件类型的继承关系:
- 顶层容器 属于窗口类组件,继承自java.awt.Window;
- 中间容器 和 基本组件 继承自javax.swing.JComponent。
顶层容器
顶层容器属于窗口类组件,可以独立显示,一个图形界面至少需要一个窗口,例如:
# | 组件 | 描述 |
1 | JFrame | 一个普通的窗口(绝大多数 Swing 图形界面程序使用 JFrame 作为顶层容器) |
2 | JDialog | 对话框 |
中间容器
中间容器充当基本组件的载体,不可独立显示。中间容器可以添加若干基本组件(也可以嵌套添加中间容器),对容器内的组件进行管理,类似于给各种复杂的组件进行分组管理。最顶层的一个中间容器必须依托在顶层容器(窗口)内。
常用的中间容器(面板):
# | 组件 | 描述 |
1 | JPanel | 一般轻量级面板容器组件 |
2 | JScrollPane | 带滚动条的,可以水平和垂直滚动的面板组件 |
3 | JSplitPane | 分隔面板 |
4 | JTabbedPane | 选项卡面板 |
5 | JLayeredPane | 层级面板 |
特殊的中间容器:
# | 组件 | 描述 |
1 | JMenuBar | 菜单栏 |
2 | JToolBar | 工具栏 |
3 | JPopupMenu | 弹出菜单 |
4 | JInternalFrame | 内部窗口 |
基本组件
基本组件是直接实现人机交互的组件。
常用的简单的基本组件:
# | 组件 | 描述 |
1 | JLabel | 标签 |
2 | JButton | 按钮 |
3 | JRadioButton | 单选按钮 |
4 | JCheckBox | 复选框 |
5 | JToggleButton | 开关按钮 |
6 | JTextField | 文本框 |
7 | JPasswordField | 密码框 |
8 | JTextArea | 文本区域 |
9 | JComboBox | 下拉列表框 |
10 | JList | 列表 |
11 | JProgressBar | 进度条 |
12 | JSlider | 滑块 |
下面对基本组件的进一步介绍。
☆按钮(JButton)
JButton是我们常用的一个组件,其表现形式为一个按钮。
方法 | 说明 |
JButton() | 创建不带有设置文本或图标的按钮 |
JButton(Action a) | 创建一个按钮,其属性从所提供的 Action 中获取 |
JButton(Icon icon) | 创建一个带图标的按钮 |
JButton(String text) | 创建一个带文本的按钮 |
JButton(String text, Icon icon) | 创建一个带初始文本和图标的按钮 |
☆按钮(JToggleButton)
JToggleButton与JButton的区别在于JToggleButton有两个状态:按下和弹起。
方法 | 说明 |
JToggleButton() | 创建最初未选定的切换按钮,不设置文本或图像 |
JToggleButton(Action a) | 创建一个切换按钮,其属性从所提供的 Action 获取 |
JToggleButton(Icon icon) | 创建一个最初未选定的切换按钮,该按钮具有指定的图像但是没有文本 |
JToggleButton(Icon icon, boolean selected) | 创建具有指定图像和选择状态但没有文本的切换按钮 |
JToggleButton(String text) | 创建具有指定文本的未选定的切换按钮 |
JToggleButton(String text, boolean selected) | 创建具有指定文本和选择状态的切换按钮 |
JToggleButton(String text, Icon icon) | 创建一个最初未选定的切换按钮,该按钮具有指定的文本和图像。 |
JToggleButton(String text, Icon icon, boolean selected) | 创建具有指定文本、图像和选择状态的切换按钮 |
☆标签(JLabel)
用于短文本字符串或图像或二者的显示区。
构造方法
方法 | 说明 |
JLabel() | 创建无图像并且其标题为空字符串的 JLabel |
JLabel(Icon image) | 创建具有指定图像的 JLabel 实例 |
JLabel(Icon image, int horizontalAlignment) | 创建具有指定图像和水平对齐方式的 JLabel 实例 |
JLabel(String text) | 创建具有指定文本的 JLabel 实例 |
JLabel(String text, Icon icon, int horizontalAlignment) | 创建具有指定文本、图像和水平对齐方式的 JLabel 实例 |
JLabel(String text, int horizontalAlignment) | 创建具有指定文本和水平对齐方式的 JLabel 实例 |
☆复选框(JCheckBox)
复选框的实现,复选框是一个可以被选定和取消选定的项,它将其状态显示给用户。
方法 | 说明 |
JCheckBox() | 创建一个没有文本、没有图标并且最初未被选定的复选框 |
JCheckBox(Action a) | 创建一个复选框,其属性从所提供的 Action 获取 |
JCheckBox(Icon icon) | 创建有一个图标、最初未被选定的复选框 |
JCheckBox(Icon icon, boolean selected) | 创建一个带图标的复选框,并指定其最初是否处于选定状态 |
JCheckBox(String text) | 创建一个带文本的、最初未被选定的复选框 |
JCheckBox(String text, boolean selected) | 创建一个带文本的复选框,并指定其最初是否处于选定状态 |
JCheckBox(String text, Icon icon) | 创建带有指定文本和图标的、最初未选定的复选框 |
JCheckBox(String text, Icon icon, boolean selected) | 创建一个带文本和图标的复选框,并指定其最初是否处于选定状态 |
☆单选按钮(JRadioButton)
实现一个单选按钮,此按钮项可被选择或取消选择,并可为用户显示其状态。与 ButtonGroup 对象配合使用可创建一组按钮,一次只能选择其中的一个按钮。
方法 | 说明 |
JRadioButton() | 创建一个初始化为未选择的单选按钮,其文本未设定 |
JRadioButton(Action a) | 创建一个单选按钮,其属性来自提供的 Action |
JRadioButton(Icon icon) | 创建一个初始化为未选择的单选按钮,其具有指定的图像但无文本 |
JRadioButton(Icon icon, boolean selected) | 创建一个具有指定图像和选择状态的单选按钮,但无文本 |
JRadioButton(String text) | 创建一个具有指定文本的状态为未选择的单选按钮 |
JRadioButton(String text, boolean selected) | 创建一个具有指定文本和选择状态的单选按钮 |
JRadioButton(String text, Icon icon) | 创建一个具有指定的文本和图像并初始化为未选择的单选按钮 |
JRadioButton(String text, Icon icon, boolean selected) | 创建一个具有指定的文本、图像和选择状态的单选按钮 |
☆文本框(JTextField)
JTextField 是一个轻量级组件,它允许编辑单行文本。
方法 | 说明 |
JTextField() | 构造一个新的 TextField |
JTextField(Document doc, String text, int columns) | 构造一个新的 JTextField,它使用给定文本存储模型和给定的列数 |
JTextField(int columns) | 构造一个具有指定列数的新的空 TextField |
JTextField(String text) | 构造一个用指定文本初始化的新 TextField |
JTextField(String text, int columns) | 构造一个用指定文本和列初始化的新 TextField |
☆密码框(JPasswordField)
JPasswordField 是一个轻量级组件,允许编辑单行文本,其视图指示键入内容,但不显示原始字符。
方法 | 说明 |
JPasswordField() | 构造一个新 JPasswordField,使其具有默认文档、为 null 的开始文本字符串和为 0 的列宽度 |
JPasswordField(Document doc, String txt, int columns) | 构造一个使用给定文本存储模型和给定列数的新 JPasswordField |
JPasswordField(int columns) | 构造一个具有指定列数的新的空 JPasswordField |
JPasswordField(String text) | 构造一个利用指定文本初始化的新 JPasswordField |
JPasswordField(String text, int columns) | 构造一个利用指定文本和列初始化的新 JPasswordField |
☆文本域(JTextArea)
JTextArea 是一个显示纯文本的多行区域。
方法 | 说明 |
JTextArea() | 构造新的 TextArea |
JTextArea(Document doc) | 构造新的 JTextArea,使其具有给定的文档模型,所有其他参数均默认为 (null, 0, 0) |
JTextArea(Document doc, String text, int rows, int columns) | 构造具有指定行数和列数以及给定模型的新的 JTextArea |
JTextArea(int rows, int columns) | 构造具有指定行数和列数的新的空 TextArea |
JTextArea(String text) | 构造显示指定文本的新的 TextArea。 |
JTextArea(String text, int rows, int columns) | 构造具有指定文本、行数和列数的新的 TextArea |
选取器组件:
# | 组件 | 描述 |
1 | JFileChooser | 文件选取器 |
2 | JColorChooser | 颜色选取器 |
其他较为复杂的基本组件:
# | 组件 | 描述 |
1 | JTable | 表格 |
2 | JTree | 树 |
布局管理器
把 Swing 的各种组件(JComponent)添加到面板容器中(JPanel),需要给面板容器指定布局管理器(LayoutManager),明确容器(Container)内的各个组件之间的排列布局方式。
常用的布局管理器:
# | 布局管理器 | 描述 |
1 | FlowLayout | 流式布局,按组件加入的顺序,按水平方向排列,排满一行换下一行继续排列。 |
2 | GridLayout | 网格布局,把Container按指定行列数分隔出若干网格,每一个网格按顺序放置一个控件。 |
3 | GridBagLayout | 网格袋布局,按网格划分Container,每个组件可占用一个或多个网格,可将组件垂直、水平或沿它们的基线对齐。 |
4 | BoxLayout | 箱式布局,将Container中的多个组件按 水平 或 垂直 的方式排列。 |
5 | GroupLayout | 分组布局,将组件按层次分组(串行 或 并行),分别确定 组件组 在 水平 和 垂直 方向上的位置。 |
6 | CardLayout | 卡片布局,将Container中的每个组件看作一张卡片,一次只能显示一张卡片,默认显示第一张卡片。 |
7 | BorderLayout | 边界布局,把Container按方位分为 5 个区域(东、西、南、北、中),每个区域放置一个组件。 |
8 | SpringLayout | 弹性布局,通过定义组件四条边的坐标位置来实现布局。 |
9 | null | 绝对布局,通过设置组件在Container中的坐标位置来放置组件。 |
框架窗口(JFrame):这是通常意义上的窗口,它支持窗口周边的框架、标题栏,以及最小化、最大化和关闭按钮;用Swing中的JFrame类或它的子类创建的对象就是JFrame窗口。
JFrame类的主要构造方法:
☆JFrame():创建无标题的窗口对象;
☆JFrame(String s):创建一个标题名是字符串s的窗口对象。
JFrame类的其他常用方法:
☆setBounds(int x,int y,int width,int height):参数x,y指定窗口出现在屏幕的位置;参数width,height指定窗口的宽度和高度。单位是像素。
☆setSize(int width,int height):设置窗口的大小,参数width和height指定窗口的宽度和高度,单位是像素。
☆setBackground(Color c):以参数 c设置窗口的背景颜色。
☆setVisible(boolean b):参数b设置窗口是可见或不可见。JFrame默认是不可见的。
☆pack():用紧凑方式显示窗口。如果不使用该方法,窗口初始出现时可能看不到窗口中的组件,当用户调整窗口的大小时,可能才能看到这些组件。
☆setTitle(String name):以参数name设置窗口的名字。
☆getTitle():获取窗口的名字。
☆setResiable(boolean m):设置当前窗口是否可调整大小(默认可调整大小)。
Swing里的容器都可以添加组件,除了JPanel及其子类(JApplet)之外,其他的Swing容器不允许把组件直接加入。其他容器添加组件有两种方法:
一种是用getContentPane()方法获得内容面板,再将组件加入。例如:
mw.getContentPane().add(button);
该代码的意义是获得容器的内容面板,并将按钮button添加到这个内容面板中。
另一种是建立一个JPanel对象的中间容器,把组件添加到这个容器中,再用setContentPane()把这个容器置为内容面板。例如,把contentPane置成内容面板的代码:
JPanel contentPane = new JPanel();
mw.setContentPane(contentPane);
大多数的Swing 应用程序都是构建在基础的Jframe 中,JFrame 起到了Swing 窗口的作用,其他一切的组件都在它的包含之内。拥有了窗口以后,就可以在窗口中添加内容了,包括:按钮(Button )、文本框(Text)、滚动条(Scroll Bar)、标签(Label )等。有了这些内容以后,窗口就可以变得互动起来。
JFrame 的使用主要有以下几个步骤:
(1)用new 语句创建JFrame 对象,可以通过构造方法传入视窗标题参数。
(2)设置窗口关闭时的行为,一般是结束进程。
(3)设置视窗的外观,例如,尺寸、可见与否等。
(4)为窗口设置布局格式,添加其他的组件,例如,标签、按钮等。
(5)必要时还可以添加一些事件。组件对象的addXXXListener()方法,为该组件添加某监听器。
注意
(1)如果没有设置布局格式,JFrame中是无法直接加入组件(如按钮JButton)的,即使调用了add()方法,界面上也是空白的。
(2)如果一个图形用户界面程序光有一些组件是远远不够的,如何让这些组件联系和互动起来才是关键。这个互动性主要就体现为事件模型。这一点后面还将介绍。
以下为一个用JFrame 类创建一个视窗的示例:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class HelloEvent {
//创建一个文本框对象
private static JTextField text = new JTextField(10);
public static void main(String[] args) { //主方法
JFrame jf = new JFrame("Helll Text"); //创建JFrame对象
jf.setLayout(new FlowLayout()); //设置布局格式
//为窗口添加一个文本框
jf.add(text); //添加到窗口中
//为窗口添加一个按钮
JButton btn = new JButton("my button"); //创建一个按钮对象
jf.add(btn); //添加到窗口中
btn.addActionListener(new ActionListener(){ //添加事件
//定义事件回调方法
public void actionPerformed(ActionEvent e) {
HelloEvent.text.setText("按钮被点击了"); //动作
}
});
showMe(jf);
}
private static void showMe(JFrame jf){
//设置窗口在关闭时,程序的响应
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(300, 200); //设置窗口大小
jf.setVisible(true); //是否可见
}
}
Swing 的大多数组件类的类名都是以J 字母开头,示例代码中的setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)方法是必须要调用的,否则默认情况下,视窗关闭时是不会结束程序的。
此示例代码中,定义了一个文本框组件和一个按钮组件,当按钮被单击时则文本框中出现一段文字“按钮被点击了”。监听器类是用一个匿名内部类来完成的,它实现的接口是 ActionListener,该接口可用于监听按钮被单击的事件,通过调用JButton 组件的addActionListener() 方法来添加该监听器。如下图 所示:
下面再给出几个例子。
例1、创建一个面板p1放置三个按钮,创建p2放置两个标签,按钮jbtLeft的背景色设置为白色,按钮jbtCenter的前景色设置为绿色.按钮jbtRight的工具提示设置,在面板p1和p2上设置标题边界,而在标签上设置线边界。
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class TestSwingCommonFeatures extends JFrame {
public TestSwingCommonFeatures() {
// Create a panel to group three buttons
JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 2));
JButton jbtLeft = new JButton("Left");
JButton jbtCenter = new JButton("Center");
JButton jbtRight = new JButton("Right");
jbtLeft.setBackground(Color.WHITE);
jbtCenter.setForeground(Color.GREEN);
jbtRight.setToolTipText("This is the Right button");
p1.add(jbtLeft);
p1.add(jbtCenter);
p1.add(jbtRight);
p1.setBorder(new TitledBorder("Three Buttons"));
// Create a font and a line border
Font largeFont = new Font("TimesRoman", Font.BOLD, 20);
Border lineBorder = new LineBorder(Color.BLACK, 2);
// Create a panel to group two labels
JPanel p2 = new JPanel(new GridLayout(1, 2, 5, 5));
JLabel jlblRed = new JLabel("Red");
JLabel jlblOrange = new JLabel("Orange");
jlblRed.setForeground(Color.RED);
jlblOrange.setForeground(Color.ORANGE);
jlblRed.setFont(largeFont);
jlblOrange.setFont(largeFont);
jlblRed.setBorder(lineBorder);
jlblOrange.setBorder(lineBorder);
p2.add(jlblRed);
p2.add(jlblOrange);
p2.setBorder(new TitledBorder("Two Labels"));
// Add two panels to the frame
setLayout(new GridLayout(2, 1, 5, 5));
add(p1);
add(p2);
}
public static void main(String[] args) {
// Create a frame and set its properties
JFrame frame = new TestSwingCommonFeatures();
frame.setTitle("TestSwingCommonFeatures");
frame.setSize(300, 250);
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
运行之,显示为:
例2、Swing 常见组件使用示例,本例有两个文件ComponentFile.java和ComponentFileTest.java
ComponentFile.java文件中的代码如下:
import java.awt.FlowLayout;
import javax.swing.*;
public class ComponentFile extends JFrame{
JTextField text; //文本框
JButton button;
JCheckBox checkBox1, checkBox2, checkBox3; //选择框
JRadioButton radio1, radio2; //单选按钮
ButtonGroup group;
JComboBox<String> comBox; //下拉列表
JTextArea area; //文本区
public ComponentFile() {
init();
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void init() {
setLayout(new FlowLayout()); //流水式布局
add(new JLabel("文本框")); //添加标签
text = new JTextField(10);
add(text);
add(new JLabel("按钮:"));
button = new JButton("确定");
add(button);
add(new JLabel("选择框"));
checkBox1 = new JCheckBox("音乐");
checkBox2 = new JCheckBox("文学");
checkBox3 = new JCheckBox("游泳");
add(checkBox1);
add(checkBox2);
add(checkBox3);
add(new JLabel("单选按钮:"));
group = new ButtonGroup(); //单选按钮所在的组
radio1 = new JRadioButton("理科"); //创建单选按钮,右面的文本是“理科”
radio2 = new JRadioButton("文科");
group.add(radio1);
group.add(radio2);
add(radio1);
add(radio2);
add(new JLabel("下拉列表:"));
comBox = new JComboBox<String>(); //创建下拉列表
comBox.addItem("一季度");
comBox.addItem("二季度");
comBox.addItem("三季度");
comBox.addItem("四季度");
add(comBox);
area = new JTextArea("这是一个文本区,可以自动换行。内容行数较多时带有滚动条",3, 20);
add(new JScrollPane(area)); //添加带有滚动条的文本区
area.setLineWrap(true);//设置自动换行
}
}
ComponentFileTest.java文件中的代码如下:
public class ComponentFileTest {
public static void main(String args[]) {
ComponentFile win = new ComponentFile();
win.setBounds(100, 100, 500, 300);
win.setTitle("常见组件");
}
}
运行之,显示为:
布局管理器
FlowLayout管理器
FlowLayout 是最简单的布局管理器。按照组件添加的顺序,从左到右地将组件排列在容器中。当放满一行时,就开始新的一行。可以使用三个常量FlowLayout.RIGHT,FlowLayout.CENTER和FlowLayout.LEFT之一来指定组件的对齐方式。还可以指定组件之间以像素为单位的间隔。例子:
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JFrame;
import java.awt.FlowLayout;
public class ShowFlowLayout extends JFrame
{
public ShowFlowLayout()
{
//Set FlowLayout,aligned left with horizontal gap 10
//and vertical gap 20 between components
setLayout(new FlowLayout(FlowLayout.LEFT,10,20));
//Add labels and text fields to the frame
add(new JLabel("登录账号"));
add(new JTextField(10));
add(new JLabel("登录密码"));
add(new JTextField(10));
}
public static void main(String[] args)
{
ShowFlowLayout frame = new ShowFlowLayout();
frame.setTitle("登录");
frame.setSize(220,200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
运行之,显示为:
GridBagLayout管理器
GridBagLayout(网格布局)管理器这个功能最强大,但也比较麻烦。
GridBagLayout是类的布局管理器,GridBagConstraints是其辅助类,用来定义添加到容器中组件的各种属性,如大小、位置、边框。
GridBagConstraints类如下public成员变量用来控制和操纵组件在容器中的排列
(1) int anchor :该变量设置布局管理器组件在表格空间中的位置
(2) int fill : 如果显示区域比组件区域大,该变量可以用来控制组件的行为。控制组件是垂直填充,还是水平填充,或者两个方向都填充。
(3) int gridx : 表示组件的横向坐标,以网格的行数为单位。
(4) int gridy : 表示组件的纵向坐标,以网格的列数为单位。
例如:
GridBagConstraints gbs = new GridBagConstraints()
gbc.gridx = 0;
gbc.gridy = 0;
(5) gridWidth :表示组件的横向宽度,即指组件占用的列数,类似于HTML的colspan标记
(6) gridheight : 表示组件的纵向长度. 下面语句设置组件占用宽度为1列,高度为2行的单元格
GridBagConstraints gbs = new GridBagConstraints()
gbc.gridwidth = 1;
gbc.gridheight = 2;
(7) Insets Insets :该变量指组件与表格空间四周边缘的空白区域大小。
(8) int ipadx :该变量表示组件间的横向间距,组件的宽度就是这个组件的最小宽度加上ipadx值.
(9) int ipady :该变量表示组件间的纵向间距,组件的高度就是这个组件的最小高度加上ipady值.
(10) double weightx : 该变量为行的权重,指示布局管理器如何分配额外的水平空间。
(11) double weighty : 该变量为列的权重,指示布局管理器如何分配额外的垂直空间。
创建GridBagLayout布局容器的一般步骤
(1)创建网格袋布局管理器
Frame frame = new Frame("网格袋布局");
frame.setLayout(new GridBagLayout());
(2)创建GridBagConstraints
GridBagConstraints gbc = new GridBagConstraints ();
(3)创建组件并设置GridBagConstraints
Button a = new Button("a");
gbc.gridx = 0 ;
gbc.gridy = 0 ;
gbc.gridwidth = 1 ;
gbc.gridheight = 1 ;
(4)添加组件
frame.add(a,gbc);
(5)显示窗体
frame.setSize(200,200);
frame.setVisible(true);
GridBagLayout测试代码如下:
import javax.swing.*;
import java.awt.*;
public class GridBagLayoutTest{
public static void main(String[] args){
JButton button;
JFrame frame = new JFrame();
frame.setSize(320, 250);
frame.setTitle("GridBagLayout测试");
frame.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
button = new JButton("Button 1");
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
c.ipady = 50;
frame.add(button, c);
button = new JButton("Button 2");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridx = 1;
c.gridy = 0;
frame.add(button, c);
button = new JButton("Button 3");
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridx = 2;
c.gridy = 0;
frame.add(button, c);
button = new JButton("Long-Named Button 4");
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 40; // 在原来的基础上又加了40个单位
c.gridwidth = 3;
c.gridx = 0;
c.gridy = 1;
frame.add(button, c);
button = new JButton("5");
/* 在这里可以把垂直改成水平看效果*/
c.fill = GridBagConstraints.VERTICAL;
c.ipady = 0;
c.weighty = 0.5;
/*weight是比重,即分配空白的部分,前面所有的组件均没有设置weighty,所以这里的weighty设置成任何值,都是填满空白部分*/
c.anchor = GridBagConstraints.PAGE_END;
c.insets = new Insets(10, 0, 0, 0);
c.gridx = 1;
c.gridwidth = 2;
c.gridy = 2;
frame.add(button, c);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
}
运行之,显示为:
使用面板作为子容器
假设要在框架中放置是个按钮和一个文本域。按钮以网格形式放置,文本域单独占一行。如果将所由这些组件放在一个单独的容器中,是很难达到要求的视觉效果的。使用Java图形用户界面进行程序设计,可以将一个窗口分成几个面板。面板的作用就是分组放置用户界面组件的子容器。可以将这些按钮添加到一个面板中,然后再将这个面板添加到框架中。
面板的Swing版本是JPanel.可以使用new JPanel()创建一个带默认FlowLayout管理器的面板,也可以使用new JPanel(LayoutManager)创建一个带特定布局管理器的面板。使用add(Component)方法可以向面板添加一个组件。例如,下面的代码创建了一个面板并且给他添加一个按钮:
JPanel p = new JPanel();
p.add(new JButton("OK"));
面板可以放到一个框架中或者放在另一个面板中。下面的语句将面板p放到框架f中:
p.add(p);
使用面板作为子容器的例子。程序创建了一个微波炉的用户界面的源码:
import java.awt.*;
import javax.swing.*;
public class TestPanels extends JFrame
{
public TestPanels()
{
//Create panel p1 for the buttons and set GridLayout
JPanel p1 = new JPanel();
p1.setLayout(new GridLayout(4,3));
//Add buttons to the panel
for(int i = 1; i <= 9; i++)
{
p1.add(new JButton("" + i));
}
p1.add(new JButton("" + 0));
p1.add(new JButton("Start"));
p1.add(new JButton("Stop"));
//Create panel p2 to hold a text field and p1
JPanel p2 = new JPanel(new BorderLayout());
p2.add(new JTextField("Time to be displayed here"),BorderLayout.NORTH);
p2.add(p1,BorderLayout.CENTER);
//add contents into frame
add(p2,BorderLayout.EAST);
add(new JButton("Food to be placed here"),BorderLayout.CENTER);
}
public static void main(String[] args)
{
TestPanels frame = new TestPanels();
frame.setTitle("The Front View of a MicroWave Oven");
frame.setSize(400,250);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
运行之,显示为:
Java事件处理机制
如果一个图形用户界面程序光有一些组件是远远不够的,如何让这些组件联系和互动起来才是关键。这个互动性主要就体现为事件模型。
那么,什么是事件?就是一个对象(对象A )的状态改变了的时候,通知其他的对象(对象B )发生了这么一件事,让它做出某种反应。
在一次事件模型中,往往包含了3 种角色,事件发生的主体(例如,按钮)、监听器(例如,监听按钮状态的监听器)和事件(例如,按钮被单击)。事件发生的主体是事件的起源地,它们的状态一般是随着用户的操作而改变;监听器是一个类,这些类往往都会继承自某个接口;事件代表了一种动作,通过它可以获取到一些用户操作的信息。在Swing编程的过程中,一般通过以下步骤来使用事件模型。
完整的事件处理程序包括:
1)定义事件监听器类,必须实现XxxListener接口。
2)完成事件处理器中方法的填写,规定特定的事件发生时执行的动作。
3)创建事件监听器类的实例并添加进组件(事件源)。
例、按钮的事件
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MouseEventDemo {
public static void main(String[] args) {
JButton jbtn = new JButton("这是按钮");
// 3. 创建事件监听器,并添加进组件(事件源)(注册监听器)
BtnMouseListener btnML = new BtnMouseListener();
jbtn.addMouseListener(btnML);
JFrame jf = new JFrame("事件处理");
jf.add(jbtn);
jf.setSize(400, 300);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
}
}
// 1. 定义事件监听器类,必须实现MouseListener接口
class BtnMouseListener implements MouseListener {
// 2. 事件处理器,用于响应特定的事件
public void mouseClicked(MouseEvent e) {
System.out.println("鼠标点击");
}
}
使用bluej编译运行之,单击按钮试试,效果如下:
图像图标
图标是一个大小固定的图片;通常情况下,他都比较小,用来装饰组件。头像通常存储在图像文件中。Java目前支持三种头像格式:GIF(图像交换格式),JPEG(联合图像专家组),以及PNG(便携网络图片).为了使用一个图像图标,首先使用new java.swing.ImageIcon(filename)创建一个ImageIcon对象.例如,下面的语句使用当前路径下的image目录的图像文件us.gif来创建一个图标:
ImageIcon icon = new ImageIcon("image/us.gif");
使用new JLabel(imageIcon)或new JButton(imageIcon)在标签或按钮上显示图像图标。
例、创建两个带图标的标签和两个带图标的按钮
import javax.swing.*;
import java.awt.*;
public class TestImageIcon extends JFrame {
private ImageIcon usIcon = new ImageIcon("image/us.gif");
private ImageIcon myIcon = new ImageIcon("image/my.jpg");
private ImageIcon frIcon = new ImageIcon("image/fr.gif");
private ImageIcon ukIcon = new ImageIcon("image/uk.gif");
public TestImageIcon() {
setLayout(new GridLayout(1, 4, 5, 5));
add(new JLabel(usIcon));
add(new JLabel(myIcon));
add(new JButton(frIcon));
add(new JButton(ukIcon));
}
/** Main method */
public static void main(String[] args) {
TestImageIcon frame = new TestImageIcon();
frame.setTitle("TestImageIcon");
frame.setSize(500, 125);
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
附录
1、Java Swing 图形界面开发(目录)https://blog.csdn.net/xietansheng/article/details/72814492
2、JavaFX 简介
一提到Java的图形界面库,我们通常听到的都是Swing,或者更老一点的AWT,但这部是全部,JavaFX就是Java在编写图形界面程序的最新技术。
Oracle官网关于JavaFX的资源和文档 https://docs.oracle.com/javase/8/javafx/get-started-tutorial/jfx-overview.htm
只要你安装了JDK 8,那么就可以使用JavaFX库了。从 JDK 11 开始,JavaFX 将作为独立模块从 JDK 中分离出来,JavaFX官网: https://openjfx.io/index.html
快速上手,第一个例子
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HelloJavaFX extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
Button btn = new Button();
btn.setText("你好啊,世界");
btn.setOnAction(event -> {
System.out.println("你好,世界!");
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
编译运行之,,效果如下:
JavaFX中文文档 http://www.javafxchina.net/blog/docs/
JavaFX易百教程 https://www.yiibai.com/javafx