文章目录
前言(转载请说明作者!)4.22~4.26编写
目标
- 如何使用Java进行图形界面的编程?
- 什么是容器?
- 什么是组件?
- 常用的布局管理器有哪些?
- Java中的事件处理机制是怎么回事?
任务导引:收银系统
自由的设计一款带有图形界面的收银软件
带有的功能是:打折计费、显示总价……
分析
根据不同的计算方式计算出每类商品应缴费用和最终总的费用。
关键:如何制造图形化界面,同时响应用户的操作。
图形界面概述
用户图形界面,简称GUI(Graphics User Interface),是程序与用户交互的机制。
相对命令行操作来说,可以给用户带来“所见即所得”的效果。
包
java.awt包
提供了大量进行GUI设计所使用的类和接口。
是进行GUI程序设计的基础,依赖底层操作系统的支持,里面的组件都属于重量级的。
显示结果可能随着操作系统的不同而发生不同。
java.swing包※
它**完全由Java实现 的**,无本地代码,不依赖操作系统的支持,因而成为轻量级组件。
如何创建用户图形界面
创建容器
容器(Container)是一个类(Component的子类),它允许组件被放在其中。
容器本身也是组件,但主要功能是放置组件和其他的子容器。
我们通常使用JFrame类来创建容器
如何构造JFrame类的对象
方法名 | 方法功能 |
---|---|
JFrame() | 构造一个JFrame的一个实例(初始时不可见)。 |
JFrame(String title) | 构造一个**初始不可见的、具有指定标题**的JFrame对象。 |
JFrame的方法
方法名 | 方法功能 |
---|---|
boolean isResizable | frame是否可以调整大小的变量,可用于判断 |
remove(MenuComponent m) | 从frame移除指定的菜单栏 |
setIconImage(Image image) | 设置frame最小化时显示的图标 |
setJMenuBar(MenuBar mb) | 将frame的菜单栏设置为指定的菜单栏 |
setResizable(boolean resizable) | 设置frame是否可以由用户调整窗口大小 |
setTitle(String title) | 设置frame的标题 |
setSize(int width,int height) | 设置frame的窗口大小 |
setLocation(int x,int y) | 设置frame的位置,x,y为程序左上角位置的坐标 |
setDefaultColseOperation(int operation) | 可传递四个值: DO_NOTHING_ON_CLOSE:关闭时不做任何事 HIDE_ON_CLOSE:关闭时隐藏窗口 DISPOSE_ON_CLOSE:关闭窗口及其窗口所占资源 EXIT_ON_CLOSE:结束窗口的整个应用程序,退出JVM |
例1
e.g. 创建宽度和高度均为屏幕的三分之,居中显示,窗口大小不可变,标题为Hello Swing的一个窗口
需要借助的类是**Toolkit类和Demension类**
Toolkit:抽象类,提供了**获取和设置本机系统设备参数和属性的方法, Toolkit获取实例使用Toolkit.getDefaultToolkit(); 方法**。
Dimension:与Toolkit一起使用,可以 获得屏幕分辨率大小:Dimension d = tk.getScreenSize();
之后可以使用 setSize方法来设定初始窗口的大小
setSize(d.width/3,d.height/3);使得窗口初始长宽像素数为屏幕分辨率所对应像素的三分之一
setLocation((d.width - d.width/3) / 2 , (d.height - d.height/3) / 2);使得窗口居中
setTitle(“Hello Swing“);设置标题
setVisible(true);设置窗口为可见(默认不可见)
setResizable(false);设置不可调整大小(默认可调整)
setIconImage(tk.getImage(“图片地址”));设置窗口的图标
布局管理、添加组件
add方法可以添加组件,例如添加一个按钮:add(new JButton(“JButton”));
当添加组件时,组件的大小、位置等都有一个被称为布局管理器(LayoutManager)控制着。Java为了实现跨平台的特性并获得动态的布局效果,将容器内的所有组件安排给一个“布局管理器”负责管理,如排列顺序、组件大小、位置等。
不同的布局管理器使用不同算法和策略容器可以通过 setLayout方法 选择不同的布局管理器 来决定布局。
Java提供了以下几种布局管理类(没有全部列出),以满足不同的需要。
布局管理类包含在java.awt或javax.swing包中。
布局 | 中文名 | 内容 | 构造方法 |
---|---|---|---|
FlowLayout | 流式布局 | JPanel 类默认的布局管理器组件放置规律: 从上到下,从左到右 | 1.FlowLayout(int align,int hgap,int vgap); 第一个参数是组件的对齐方式 第二个参数是组件之间的横向间隔 第三个参数是组件之间的纵向间隔(单位:px) PS:第二和第三个参数是可选参数 当不填时,例如new FlowLayout(FlowLayout.LEFT); 对齐方式为左对齐,水平和垂直间隙都为5px。 2.FlowLayout();居中对齐,水平垂直间隔均为5px。 |
BorderLayout | 框架/边界布局 | JFrame 类默认的布局管理器组件放置区域: North,South,East,West,Center 每个区域只能放置一个组件。 | 1.BorderLayout(int hgap,int vgap); 构造一个具有指定组件间距的边界布局 2.BorderLayout(); 构造一个组件之间没有间距的边界布局 |
CardLayout | 卡片布局 | 容器中的每个组件看作一张卡片 一次只能看到一张卡片 | 1.CardLayout(); 创建一个间距大小为0的卡片布局 2.CardLayout(int hgap,int vgap); 创建一个指定水平间距和垂直间距的卡片布局 |
GridLayout | 网格布局 | / | 1.GirdLayout(); 以默认单行、每列布局一个组件的方式构造网格布局 2.GridLayout(int rows,int cols); 以指定的行和列构造网格布局 3.GridLayout(int rows,int cols,int hgap,int vgap); 以指定的行、列、水平间距和垂直间距构造网格布局 |
BoxLayout | 盒式布局 | ||
GridBagLayout⭐ | / |
-
FlowLayout程序实例
import java.awt.FlowLayout; import javax.swing.*; public class FlowLayoutDemo extends JFrame { public FlowLayoutDemo() { super("FlowLayout布局"); FlowLayout flow = new FlowLayout(FlowLayout.LEFT, 8, 2); // 设置JFrame为流式布局 setLayout(flow); // 创建10个按钮 for (int i = 1; i <= 10; i++) { JButton b = new JButton("I'm" + i); add(b); } // 设置容器在屏幕中显示的位置、宽度和高度 setBounds(200, 200, 600, 300); setVisible(true); } public static void main(String[] args) { new FlowLayoutDemo(); } }
-
BorderLayout程序实例
import java.awt.BorderLayout; import javax.swing.*; public class BorderLayoutDemo extends JFrame { public BorderLayoutDemo() { super("BorderLayout布局"); // 指定布局方式,即使不是默认的也是 setLayout(new BorderLayout()); setBounds(100, 100, 600, 600); JButton bSouth = new JButton("我在南边"), bNorth = new JButton("我在北边"), bEast = new JButton("我在东边"), bWest = new JButton("我在西边"); JTextArea bCenter = new JTextArea("我在中心"); add(bSouth, BorderLayout.SOUTH); add(bNorth, BorderLayout.NORTH); add(bEast, BorderLayout.EAST); add(bWest, BorderLayout.WEST); add(bCenter, BorderLayout.CENTER); // BorderLayout.CENTER参数可以省略,因为默认为中心区域 setVisible(true); setDefaultCloseOperation(3); } public static void main(String[] args) { new BorderLayoutDemo(); } }
CardLayout方法
方法名 | 方法功能 |
---|---|
void first(Container parent); | 移到指定容器的第一张卡片 |
void next(Container parent); | 移到指定容器的下一张卡片 |
void previous(Container parent); | 移到指定容器的前一张卡片 |
void last(Container parent); | 移到指定容器的最后一张卡片 |
void show(Container parent,String name); | 显示指定卡片 |
import java.awt.*;
import javax.swing.*;
public class CardLayoutDemo extends JFrame {
private JButton buttonFirst, buttonLast, buttonNext;
public CardLayoutDemo() {
super("CardLayoutDemo");
CardLayout myCard = new CardLayout();
JPanel pCenter = new JPanel();
pCenter.setLayout(myCard);
for (int i = 1; i <= 20; i++) {
pCenter.add("I'm " + i, new JButton("我是第" + i + " 个按钮"));
}
// 显示指定的卡片,默认第一个
myCard.show(pCenter, "I'm 3");
JPanel pSouth = new JPanel();
buttonFirst = new JButton("First");
buttonLast = new JButton("Last");
buttonNext = new JButton("Next");
pSouth.add(buttonFirst);
pSouth.add(buttonLast);
pSouth.add(buttonNext);
add(pCenter,"Center");
add(pSouth,BorderLayout.SOUTH);
setBounds(10,10,600,590);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new CardLayoutDemo();
}
}
GridLayout方法
import java.awt.*;
import javax.swing.*;
public class GridLayoutDemo extends JFrame {
public GridLayoutDemo() {
super("网格布局Demo");
GridLayout grid = new GridLayout(12, 12);
setLayout(grid);
JLabel label[][] = new JLabel[12][12];
for (int i = 0; i < label.length; i++) {
for (int j = 0; j < label[i].length; j++) {
label[i][j] = new JLabel();
label[i][j].setOpaque(true);
// JLabel默认透明,所以要设置成不透明的,不设置颜色将无法生效
if ((i + j) % 2 == 0) {
label[i][j].setBackground(Color.black);
} else {
label[i][j].setBackground(Color.white);
}
add(label[i][j]);
}
}
setBounds(10, 10, 600, 600);
setVisible(true);
}
public static void main(String[] args) {
new GridLayoutDemo();
}
}
容器嵌套
JPanel
在复杂的图形用户界面设计中,为了使布局更加易于管理,具有简洁的整体风格,一个包含了多个组件的容器本身也可以作为一个组件加到另一个容器中去,容器中再添加容器,这样就形成了容器的嵌套
。
实现容器的嵌套,需要借助JPanel作为中间的容器。
JPanel继承表
方法名 | 方法功能 |
---|---|
JPanel(LayoutManager layout); | 创建具有指定布局管理器的JPanel容器 |
JPanel(); | 使用默认的布局管理器FlowLayout创建JPanel容器 |
例2
代码实现
import java.awt.BorderLayout;
import javax.swing.*;
public class NestedLayoutDemo extends JFrame {
public NestedLayoutDemo() {
super("容器嵌套Demo");
JPanel southPanel = new JPanel();
southPanel.add(new JButton("OK"));
southPanel.add(new JButton("Exit"));
add(southPanel, BorderLayout.SOUTH);
setBounds(300, 200, 600, 400);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new NestedLayoutDemo();
}
}
事件处理
事件四要素
- 事件源:究竟是 谁引发 了事件的发生。在面向对象编程语言中,事件源指的是引发事件发生的各个组件。
- 事件:引发了什么类型的事件发生。在Java中不同类型的事件会对应相应的事件类。
- 事件处理者:究竟谁有能力对事件进行处理。
- 注册:建立事件源和事件处理者的关联。
事件处理要素 | 珠宝店被盗 | 用户单击按钮 |
---|---|---|
事件源 | 珠宝店 | 按钮对象 |
事件 | 被盗 | 用户单机触发ActionEvent 类事件 |
事件处理者 | 保安 | 实现了ActionListener 接口的类对象 |
注册 | 珠宝店雇佣保安 | 按钮对象.addActionListener(事件处理者); |
事件
不同事件类型Java中是使用不同的类来描述的,大多数事件类包含在java.awt.event
包里,所有事件类的父类都是AWTEvent
类。
事件类型 | 触发事件的动作 |
---|---|
ActionEvent | 当用户**单击按钮、 选择菜单项或选择一个列表项时**产生ActionEvent事件 |
ItemEvent | 当用户在**组合框选择一项时**产生ItemEvent事件 |
TextEvent | 当文本域或文本框中的内容发生变化时产生TextEvent事件 |
FocusEvent | 组件得到焦点或失去焦点时产生~ |
WindowEvent | 窗口被激活、图标化、还原或关闭时产生~ |
KeyEvent | 按下或者释放一个键时产生~ |
MouseEvent | 按下、释放鼠标按钮,移动或拖动鼠标时产生~ |