<Java>15 图形界面设计
本文最后更新于:2023年6月27日 上午
15 图形界面设计
图形用户界面(Graphical User Interface,简称 GUI)是大多数程序不可缺少的部分。
Java 的图形界面由各种组件组成。在 java.awt 和 java.swing 包中定义了多种用于创建图形用户界面的组件类。
Swing 组件和 AWT 组件最大的不同是 Swing 组件实现时不包含任何本地代码,因此不受硬件平台的限制,而具有更多的功能,并且在任何平台上运行效果都是相同的。不包含本地代码的 Swing 组件被称为 “轻量级” 组件,而 AWT 被称为 “重量级” 组件。两种组件一同使用的场合,AWT 总是显示在上面。
设计用户界面是一般有 3 个步骤:
- 选取组件
- 设计布局
- 响应事件
15.1 容器
组件分为容器组件和非容器组件。容器组件即可以包含其他组件的组件。非容器组件必须包含在容器组件中。
容器组件分为:顶层容器、一般用途容器
15.1.1 顶层容器
Swing 中提供了 4 种顶层容器:
- JFrame:带有标题行和控制按钮(最小化、恢复/最大化、关闭)的独立窗口。有时称为框架。创建程序时要使用 JFream
- JApplet:创建小应用程序时要使用 JApplet。其被包含在浏览器窗口中
- JDialog:创建对话框时使用 JDialog
- JWindow:一个不带有标题行和控制按钮的窗口。一般很少使用
构造方法:
new JFrame()
:构造一个初始不可见,无标题的新框架窗体new JFrame("Title")
:构造一个初始不可见,具有指定标题的新框架窗体
常用方法:
-
void setBounds(int x, int y, int width, int height)
:移动并调整框架大小。框架左上角位置为(x, y),框架大小为 width × height -
void setSize(int width, int height)
:设置窗口大小 -
void setBackground(Color bg)
:设置框架背景色void setForeground(Color fg)
:设置框架前景色 -
void setVisible(boolean aFlag)
:设置可见性 -
void pack()
:自适应框架大小,以符合子组件的首选大小和布局 -
void setTitle(String title)
:设置标题 -
Container getContentPane()
:返回此框架窗体的内容窗格对象Container 类是所有容器类的父类,包含容器的共有操作
void setContentPane(Container contentPane)
:把指定内容窗格设置为此框架的内容窗格对象 -
void setLayout(LayoutManager manager)
:设置布局管理器
—— 哦我的上帝啊,如果有什么名词是你不懂的,为什么不试着继续看下去呢?
15.1.2 内容窗格
4 个顶层容器每个都有 1 个内容窗格。除菜单外,顶层容器的所有组件都放在这个内容窗格内。
-
直接添加组件至内容窗格
Container contentPane = jframe.getContentPane(); //[1] 获取内容窗格对象 contentPane.add(button, BorderLayout.CENTER); //[2] 将组件添加到内容窗格
-
使用顶层容器的
getContentPane()
方法获得其内容窗格对象。 -
将组件添加到内容窗格。
其中 button 是一个按钮控件,BorderLayout.CENTER 代表位置在中间
向顶层容器内容窗格添加组件时,也可以直接调用顶层容器的 add() 方法
-
-
以新的内容窗格代替原有内容窗格
JPanel contentPane = new JPanel(); //[1] 创建 JPanel 实例 contentPane.setLayout(new BorderLayout()); //[2] 创建布局管理器 contentPane.add(button, BorderLayout.CENTER); //[3] 添加组件 jfream.setContentPane(contentPane); //[4] 添加内容窗格
-
创建 JPanel(面板)实例。JPanel 是 Container 的子类。
-
顶层容器默认的布局管理器是 BorderLayout,而 JPanel 的默认布局管理器是 FlowLayout
-
通过
setContentPane(contentPane)
方法为 jfream 设置新的内容窗格
-
15.1.3 面板
普通面板(JPanel)和滚动面板(JScrollPanel)都是用途广泛的容器。面板与顶层容器不同,不能独立存在,而必须添加到其他容器内部。面板可以嵌套,由此可以设计出复杂的图形用户界面。
#15.1.3.1 JPanel
构造方法:
new JPanel()
:创建具有 FlowLayout 布局的新面板new JPanel(LayoutManager layout)
:创建指定布局的新面板
常用方法:
Component add(Compinent comp)
:将指定组件添加至面板
#15.1.3.2 JScrollPanel
JScrollPanel 是一个带有滚动条的面板,但只能添加一个组件。添加多个组件的场合,先将那些组件添加入 JPanel 对象,再将该 JPanel 对象添加进 JScrollPanel 对象中
构造方法:
new JScrollPanel()
:创建一个空的 JScrollPanel。水平、垂直滚动条都能显示new JScrollPanel(Component view)
:创建指定组件内容的 JScrollPanel
常用方法:
-
void setHorizontalScrollBarPolicy(int policy)
:确定水平滚动条何时显示其中 policy 的可选值是以下三种:
- ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED:需要时可见
- ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER:永远不可见
- ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS:永远可见
-
void setVerticalScrollBarPolicy(int policy)
:确定垂直滚动条何时显示其中 policy 的可选值是以下三种:
- ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED:需要时可见
- ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER:永远不可见
- ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS:永远可见
#15.1.3.3 Scrollbar
AWT 中还有一个滚动条组件,提供了允许用户在一定范围的值中进行选择的便捷方式
构造器:
-
new Scrollbar()
:构造一个新的滚动条 -
new Scrollbar(int orientation)
:构造一个有指定方向的滚动条其中 orientation 的可选值是:
- Scrollbar.HORIZONTAL:水平滚动条
- Scrollbar.VERTICAL:垂直滚动条
-
new Scrollbar(int orientation, int value, int visible, int minimum, int maximun)
:构造一个有初始方向、初始值、可视量、最小/最大值的滚动条
15.2 标签和按钮
15.2.1 标签
标签(JLable)是最简单的 Swing 组件,通常用于显示提示性的文本信息或图标。其不可被编辑
构造器:
-
new JLable()
:构造一个不显示文本或图标的空标签 -
new JLable(Icon image)
:构造一个显示图标的标签 -
new JLable(String text)
:构造一个显示文本的标签 -
new JLable(Icon image, int horizontalAlignment)
:构造一个显示图标的标签,并指定水平对齐方式其中 horizontalAlignment 的取值可以是:
- JLable.LEFT:左对齐
- JLable.RIGHT:右对齐
- JLable.CENTER:居中对齐
-
new JLable(String text, int horizontalAlignment)
:构造一个显示文本的标签,并指定水平对齐方式 -
new JLable(String text, Icon image, int horizontalAlignment)
:构造一个同时显示文本和图标的标签,并指定水平对齐方式
15.2.2 按钮
按钮(JButton)是 Java 图形用户界面的基本组件之一。
经常用到的按钮有 4 种形式:按钮(JButton)、切换按钮(JToggleButton)、复选按钮(JCheckButton)、单选按钮(JRadioButton)
这些按钮类均是 AbstractButton 的子类或间接子类
#15.2.2.1 JButton
构造器:
new JButton()
:构造一个既没有文本也没有图标的按钮new JButton(Icon icon)
:构造一个有图标的按钮new JButton(String text)
:构造一个有文本的按钮new JButton(String text, Icon icon)
:构造一个有文本也有图标的按钮
常用方法:
-
void setMnemonic(int mnemonic)
:设置当前按钮的键盘助记符 -
void setText(String text)
:设置按钮的文本void setIcon(Icon icon)
:设置按钮图标 -
void setEnabled(boolean mod)
:是否启用按钮 -
String getText()
:返回按钮的文本 -
void setToolTipText()
:设置提示文本 -
void addActionListener(ActionListener l)
:为按钮添加事件监听程序void removeActionListener(ActionListener l)
:移除事件监听程序
#15.2.2.2 JToggleButton、JCheckButton、JRadioButton
JToggleButton 是有两种状态(选中状态、未选中状态)的按钮。通过点击切换这两种状态
JCheckButton、JRadioButton 是 JToggleButton 的子类,构造方法与 JToggleButton 相同。
构造器:
-
new JToggleButton()
:构造一个没有文本也没有图标的切换按钮 -
new JToggleButton(Icon icon)
:构造一个有图标的切换按钮new JToggleButton(Icon icon, boolean selected)
:构造一个有图标的切换按钮,设置其初始状态 -
new JToggleButton(String text)
:构造一个有文本的切换按钮new JToggleButton(String text, boolean selected)
-
new JToggleButton(String text, Icon icon)
:构造一个有文本也有图标的切换按钮new JToggleButton(String text, Icon icon, boolean selected)
常用方法(除 JButton 方法外):
-
boolean isSeleced()
:获取按钮的当前状态 -
void addItemListener(ItemListener l)
:为按钮添加事件侦听程序void removeItemListener(ItemListener l)
:移除事件侦听程序
15.3 布局管理器
容器中包含了组件。组件的布局,包括其位置和大小,通常由布局管理器负责安排。每个容器都有一个默认的布局管理器。
15.3.1 FlowLayout 流布局管理器
FlowLayout 定义在 java.awt 包中。
构造器:
-
new FlowLayout()
:创建默认的 FlowLayout 布局管理器。居中对齐。默认水平、垂直间距是 5 像素
-
new FlowLayout(int align)
:创建一个 FlowLayout 布局管理器。指定对齐方式。默认水平、垂直间距是 5 像素
align 的可选值有这些:
- FlowLayout.LEFT:左对齐
- FlowLayout.RIGHT:右对齐
- FlowLayout.CENTER:居中对齐
-
new FlowLayout(int align, int hgap, int vgap)
:创建一个 FlowLayout 布局管理器。指定对齐方式。指定水平、垂直间距
使用说明:
- FlowLayout 对容器中组件进行布局的方式是将组件逐个放置在容器中的一行上。一行满后,另起一行。
- 与其他布局管理器不同。FlowLayout 不会强行设定组件的大小,而是通过每个组件的 getPreferredSize() 方法获取其各自的期望大小
15.3.2 BorderLayout 边界布局管理器
BorderLayout 定义在 java.awt 包中,是顶层容器的默认布局管理器。它提供了一种较为复杂的组件布局管理方案。
构造方法:
new BorderLayout()
:一个组件间没有间距的布局管理器new BorderLayout(int hgap, int vgap)
:定义水平、垂直间距的布局管理器
使用说明:
- 每个由 BorderLayout 管理的容器被划分成 5 个区域,分别是容器的 上部(BorderLayout.NORTH)、下部(BorderLayout.SOUTH)、左部(BorderLayout.WEST)、右部(BorderLayout.EAST)、中部(BorderLayout.CENTER)
- 在 BorderLayout 布局管理器的管理下,组件必须通过 add() 方法加入容器的指定区域。不指定的场合,默认加入中部区域
- 容器的每个区域仅能加入一个组件。加入了多个组件的场合,只有最后一个生效
- 对于中部以外的 4 个边界区域,没有使用的区域的大小将变为零。此时,中部区域会扩展并占据该未用区域的位置。如果 4 个边界区域都没有使用,中部区域会占据整个窗口。
- 窗口大小改变时,按钮的相对位置不会变化。但按钮的大小会改变
15.3.3 GridLayout 网格布局管理器
GridLayout 定义在 java.awt 包中,是一种网格式的布局管理器。
构造器:
-
new GridLayout()
:创建一个一行的网格。列数根据实际需要决定 -
new GridLayout(int rows, int cols)
:指定行数、列数的网格布局rows 和 cols 中,最多有一个可以是 0,但不能都为 0。那个为 0 的场合,根据实际需要决定数量
-
new GridLayout(int rows, int cols, int hgap, int vgap)
:指定行数、列数,也指定水平、垂直间距的网格
使用说明:
-
GridLayout 将容器空间划分成若干行乘若干列的网格。组件依次放入其中,每个组件占据一格
-
网格每列宽度相同,每行高度相同。组件放入的次序决定了其位置
-
想要组件间留有空白的场合,可以添加一个空白标签
-
网格数多于组件数的场合,那些多余的格子为空白。
网格数少于组件数的场合,系统根据需要适当添加。
-
窗口大小改变时,按钮的相对位置不会变化。但按钮的大小会改变
15.3.4 CardLayout 卡片式布局管理器
CardLayout 定义在 java.awt 包中,是一种卡片式的布局管理器。
构造器:
new CardLayout()
:一个默认无间距的 CardLayout 布局管理器new CardLayout(int hgap, int vgap)
:指定水平、垂直间距的 CardLayout 布局管理器
常用方法:
-
void first(Container parent)
:翻转到容器的第一张卡片void next(Container parent)
:翻转到下一张卡片。当前是最后一张的场合,翻到第一张卡片void previous(Container parent)
:翻转到前一张卡片。当前是第一张的场合,翻到最后一张卡片void last(Container parent)
:翻转到容器的最后一张卡片 -
void show(Container parent, String name)
:翻转到卡片集中具有指定 name 的卡片。没有该卡片的场合不执行任何操作
使用说明:
- CardLayout 将容器中的组件处理为一系列卡片,每一刻只显示其中一张。
- 容器第一次显示时,显示第一个添加的组件。
15.3.5 BoxLayout 方框布局管理器
BoxLayout 定义在 javax.swing 包中,其组件横排一行或竖排一列,但宽度(高度)可以不同。
构造器:
-
new BoxLayout(Container target, int axis)
:创建一个沿给定轴放置组件的布局管理器其中 target 表明为哪个容器设置此布局管理器,axis 指明组件排列方向
axis 的值是:
- BoxLayout.X_AXIS:水平方向排列
- BoxLayout.Y_AXIS:竖直方向排列
举个例子:
JPanel jp = new JPanel(); jp.setLayout(new BoxLayout(jp, BoxLayout.X_AXXIS));
使用说明:
- BoxLayout 将容器中的组件横排一行或竖排一列。那些组件横排一行时,可以有不同宽度;竖排一列时,可以有不同的高度。
- 窗口大小改变时,按钮的相对位置不会变化。
Box 类
javax.swing 中定义了一个专门使用 BoxLayout 的容器 Box 类。
-
static Box createHorizontalBox()
:返回一个使用水平方向的 BoxLayout 的 Boxstatic Box createVerticalBox()
:返回一个使用竖直方向的 BoxLayout 的 Box -
static Component createHorizontalGlue()
:创建一个水平方向的不可视的组件(填满剩余空间)static Component createVerticalGlue()
-
static Component createHorizontalStrut()
:创建一个水平方向的不可视的组件(指定宽高)static Component createVerticalStrut()
-
static Component createRigidArea()
:创建一个不可视的组件,不大不小,尺寸真是好极了
15.3.6 空布局
其实也能不用布局管理器的,真的
- 调用容器的
setLayout(null)
将容器的布局管理器置空 - 调用组件的
setBounds(x, y, w, h)
方法设置其位置和大小。~老东西,你的布局管理器最没用啦!~
15.4 事件处理
Java 运行时,如果用户进行某个操作,程序应当做出相应。
程 · 序 · 无 · 响 · 应(噔 噔 咚)
……总之,用户在程序界面进行的操作称为用户事件,对事件的相应称为事件处理。
15.4.1 事件处理模型
Java 事件处理是采取 “委派事件模型”。当事件发生时,产生事件类对象。这里说的事件类对象实际上就是
java.awt.event
事件类库里某个类创建的对象。操作不同的场合,事件类对象不同。会把此事件类对象传递给事件侦听程序处理。它是实现了对应侦听程序接口的一个类。
事件只是一个对象,其只向注册的侦听程序报告
示范一个简单的事件处理:
import javax.seing.*;
import java.awt.*; //[0]
public class Code_15_4_1 {
public static void main(String[] args) throws InterruptedException {
Button b = new Button("Button");
b.addActionListener((e) -> System.out.println("Pressed")); //[1]
JFrame jFrame = new JFrame("Test");
jFrame.setBounds(30, 30, 100, 100);
jFrame.add(b);
jFrame.setVisible(true);
}
}
引入 java.awt.event 包
注册事件侦听程序,并实现其方法
示例中的简写其实相当于以下代码(匿名内部类):
b.addActionListener(new ActionListener() { @OverRide public void actionPerformed (ActionEvent e) { System.out.println("Pressed"); } });
—— 示例写法见 [27 Java8 新特性]
事件侦听程序可以定义在单独的类中,也可以定义在组件类中:
class MyButton extends JButton implements ActionListener{ public MyButton() { addActionListener(this); } @Override public void actionPerformed(ActionEvent e) { System.out.println("Pressed"); } }
15.4.2 事件的种类
在 java.awt.event 包和 javax.swing.event 包中定义了很多其他的事件类。每种事件类有一个对应的接口,接口中声明了一个或多个抽象的事件处理方法。
事件类 | 组件 | 方法及说明 |
---|---|---|
ActionEvent | JButton、JCheckBox、JComboBox、JMenuItem、JRaidoButton | actionPerformed(e) 单击按钮、选择菜单项或在文本框中按回车时 |
AdjustmentEvent | JScrollBar | adjustmentValueChanged(e) 当改变滚动条滑块位置时 |
ComponentEvent | JComponent 及其子类 | componentMoved(e) 组件移动时;componentHidden(e) 组件隐藏时;componenetResized(e) 组件缩时;componentShown(e) 组件显示时 |
ContainerEvent | JContainer 及其子类 | containerAdded(e) 添加组件时;containerMoved(e)移除组件时 |
FocusEvent | 同 ComponentEvent | focusGained(e) 组件获得焦点时;focusLost(e) 组件失去焦点时 |
ItemEvent | JCheckBox、JCheckboxMenuItem、JComboBox | itemStateChanged(e) 选择复选框、选项框、单击列表框、选中带复选框菜单时 |
KeyEvent | 同 ComponentEvent | keyPressed(e) 键按下时;keyReleased(e) 键释放时;keyTaped(e) 击键时 |
MouseEvent | 同 ComponentEvent | mousePressed(e) 鼠标按下时;mouseEntered(e) 鼠标进入时;mouseExited(e) 鼠标离开时;mouseClicked(e) 鼠标点击时;mouseReleased(e) 鼠标释放时 |
MouseMotionEvent | 同 ComponentEvent | mouseDragged(e) 鼠标拖放时;mouseMoved(e) 鼠标移动时 |
TextEvent | JTextField、JTextArea | textValueChanged(e) 文本框、多行文本框内容修改时 |
WindowEvent | JFrame、JWindow、JDialog | windowOpened(e) 窗口打开时;windowClosing(e) 窗口关闭时;windowClosed(e) 窗口关闭后;windowActived(e) 窗口激活时;windowDeactivated(e) 窗口失去焦点时;windowIconified(e) 窗口最小化时;WindowDeiconified(e) 窗口最小化还原时 |
使用说明:
-
XXXEvent 事件类的接口名就是 XXXListener。占地方太大,上面就没写
-
事件侦听模式允许为一个组件多次调用 addListener 方法,注册多个侦听程序。
事件发生时,单个事件的多个侦听程序的调用顺序不确定。
-
调用事件处理方法时会传入一个参数。该参数就是那些事件类实例,其中包含事件有关的重要信息。
调用这些事件类实例各自特有的方法获取这些信息。
15.4.3 事件适配器
侦听程序必须实现接口的全部抽象方法,但有时我们只关心其中的某一种方法。为了编程方便,Java 为一些声明了多个抽象方法的 Listener 接口提供了相应的适配器类。
接口名称 | 适配器名称 |
---|---|
ComponentListener | ComponentAdapter |
ContainerListener | ContainerAdapter |
FocusListener | FocusAdapter |
KeyListener | KeyAdapter |
MouseListener | MouseAdapter |
MouseMotionListener | MouseMotionAdapter |
MouseInputListener | MouseInputAdapter |
WindowListener | WindowAdapter |
这些适配器实现了接口的全部抽象方法,只是方法内容为空
这样,创建新类时可以不必实现接口,而是继承适配器类,并重写需要的方法
15.5 Java 绘图技术
Java 语言约定,显示屏上一个长方形区域为程序绘图区域,坐标原点(0, 0)位于整个区域左上角。
一个坐标点(x, y)对应一个像素,其中坐标点的 x、y 必须是非负整数。x 沿水平方向从左向右递增、y 沿竖直方向从上往下递增
15.5.1 颜色
可以使用 java.awt 包中的 Color 类来定义和管理颜色。Color 类的每个对象代表一种颜色。
Color 类有 26 个常量,代表 13 种预定义颜色:
颜色 | 对象 | ᓚᘏᗢ |
---|---|---|
黑色(#000000) | Color.black | Color.BLACK |
蓝色(#0000FF) | Color.blue | Color.BLUE |
青色(#00FFFF) | Color.cyan | Color.CYAN |
灰色(#808080) | Color.gray | Color.GRAY |
深灰色(#404040) | Color.darkGary | Color.DARKGARY |
浅灰色(#C0C0C0) | Color.lightGary | Color.LIGHTGARY |
绿色(#00FF00) | Color.green | Color.GREEN |
洋红色(#FF00FF) | Color.magenta | Color.MAGENTA |
橙色(#FFC800) | Color.orange | Color.ORANGE |
粉红色(#FFAFAF) | Color.pink | Color.PINK |
红色(#FF0000) | Color.red | Color.RED |
白色(#FFFFFF) | Color.write | Color.WRITE |
黄色(#FFFF00) | Color.yellow | Color.YELLOW |
也可以通过红、绿、蓝三原色值来组合。每种颜色由三个值组成(RGB),值的范围是 [0, 256):
Color color = new Color(102, 204, 255);
这个颜色是:天依蓝(#66CCFF)
这部分笔记恐怕是所有 Java 笔记里唯一有五颜六色的地方了,真难得
15.5.2 字体
文字有 字体、样式、字号 三个要素
基本的样式有:
-
Font.PLAIN:正常(0)
-
Font.BOLD:粗体(1)
-
Font.ITALIC:斜体(2)
样式可以组合使用,如 (Font.BOLD + Font.ITALIC) 即 粗斜体
常用的字体:Times New roman(Times New roman)、Symbol(Symbol)、宋体(宋体)、楷体(楷体)等
构造器:
new Font(String name, int style, int size)
:新建字体,指定字体、样式、字号
常用方法:
-
String getName()
:返回其字体名称int getSize()
:返回其字号大小int getStyle()
:返回其样式 -
boolean isBold()
:是否是粗体boolean isItalic()
、boolean isPlain()
15.5.3 Graphics 类
java.awt 包下的 Graohics 类是所有图形处理的基础,是所有图形上下文的抽象父类。其允许应用程序在组件及屏幕图像上进行绘制。
当先后绘制的图形不同时,确定重叠部分颜色的方法称为绘图模式。
绘图模式分为两种:
-
正常模式:
setPaintMode()
后绘制的图形覆盖先绘制的图形。
-
异或模式:
setXORMode(Color c)
当前绘制的颜色、先前绘制的颜色 及 选定的颜色 c 之间进行某种处理后,用新的颜色绘制。
这个模式下,如果使用同一颜色绘制 2 次,则相当于擦除之前绘制的图形,即恢复原本状态。
若要在某个组件中绘图,应重写该组件的 paint(Graphics g) 方法,并在重写的方法内进行绘图。
-
paint(Graphics g)
:组件被显示出来时,调用该方法以下情况该方法会被调用
- 组件第一次在屏幕显示时
- 窗口最小化/最大化
- 窗口大小发生变化
repaint
函数被调用
-
repaint()
:重绘组件该方法默认情况下会调用以下方法
-
paintCompnent(Graphics g)
:绘制组件一般情况下,要在 JComponent 子类的组件中绘图,重写该方法即可
-
paintBorder(Graphics g)
:绘制组件边框 -
paintChildren(Graphics g)
:绘制组件的子组件
-
设置画笔:
-
setColor(Color c)
:设置画笔前景色setBackgroud(Color c)
:设置背景色每个图形环境都有一种画图时正在使用的前景色。画图所在的每个表面都有背景色
-
setFont(Font f)
:设置画笔字体
绘制几何图案:
-
drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
:绘制弧线该弧线是 沿着起始点为 (x, y)、宽 width、高 height 的矩形所限定的椭圆 绘制一条弧线。
该弧线起始角度为 startAngle,弧度角度为 arcAngle
fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)
:填充扇形 -
drawLine(int x1, int y1, int x2, int y2)
:绘制线段该线段的两个端点是 (x1, y1) 和 (x2, y2)
-
drawOval(int x, int y, int width, int height)
:绘制椭圆一个起始点为 (x, y)、宽 width、高 height 的矩形所限定的椭圆
fillOval(int x, int y, int width, int height)
:填充椭圆 -
drawPolygon(int[] xPoints, int[] tPoints, int nPoints)
:绘制多边形drawPolygon(Polygon p)
:也能通过传入一个 Polygon 对象来绘制多边形该图形的端点由传入参数确定。如果最后一个端点和第一个端点不相等,那么图形可能不闭合
fillPolygon(int[] xPoints, int[] tPoints, int nPoints)
:填充多边形fillPolygon(Polygon p)
:通过传入一个 Polygon 对象来填充多边形低情商:这咋填充?高情商:留给读者们思考吧
-
drawRect(int x, int y, int width, int height)
:绘制矩形一个起始点为 (x, y)、宽 width、高 height 的矩形
fillRect(int x, int y, int width, int height)
:填充矩形 -
drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
:圆角矩形一个起始点为 (x, y)、宽 width、高 height 的矩形,其圆角形状由 arcWidth、arcHeight 确定
其实就是矩形(线段)和椭圆(圆弧)的某种拼接
fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
:填充圆角矩形 -
drawString(String str, int x, int y)
:输出字符串在 (x, y) 处输出字符串 str,向右扩展
drawChars(char[] chars, int offSet, int length, int x, int y)
:输出字符串从字符数组的 offSet 下标处起,在 (x, y) 处输出 length 个字符,向右扩展
drawBytes(byte[] data, int offSet, int length, int x, int y)
:还不是一样? -
draw3DRect(int x, int y, int width, int height, boolean raised)
:绘制 3D 矩形fill3DRect(int x, int y, int width, int height, boolean raised)
:填充 3D 矩形我感觉是和 PS 里的浮雕效果类似,生成了亮部和暗部。rasied 决定是凸起还是凹陷。
#15.5.3.1 Polygon 类
Polygon 对象封装了多边形的坐标。
构造方法:
-
new Polygon()
:构造一个空的多边形。无为太虚,无生一,一生二,二生三,三生万物。所以,空的多边形也是多边形。
-
new Polygon(int[] xs, int[] ys, int n)
:构造一个 n 点连接成的多边形
常用方法:
-
addPoint(int x, int y)
:将该点加入多边形中 -
boolean contains(int x, int y)
:如果多边形包含该点,则返回真boolean contains(Point p)
-
get Bounds()
:得到多边形的外接矩形 -
translate(int dx, int dy)
:偏移将多边形各点沿 x 轴偏移 dx,再沿 y 轴偏移 dy
15.5.4 Graphics2D 类
为了解决图形对象的局限性,Java 1.1 后 引入了 Java 2D,其包含一个继承自 Graphics 的 Graphics2D 类,增加了很多状态属性,扩展了 Java 的绘图功能
Graphics2D 拥有强大的二维图形处理能力,提供对几何形状、坐标转换、颜色管理、文字布局等更复杂的控制
#15.5.4.1 图形状态属性
通过设定和修改属性,可以指定画笔宽度和画笔连接方式、设定平移、旋转、缩放或裁剪变换图形,还能设置填充图形的颜色和图案等。
状态属性:
-
stroke 属性:
该属性控制线宽、笔形样式、线段连接方式、短划线图案。
使用
setStroke(Stroke s)
方法设置 stroke 属性。构造方法:
-
new BasicStroke(float w)
:指定线宽的 stroke -
new BasicStroke(float w, int cap, int join)
:指定线宽、端点样式 cap、线段交汇方式 join 的 stroke其中,端点样式 cap 的值可以是:
- BasicStroke.CAP_BUTT:无修饰(0)
- BasicStroke.CAP_ROUND:半圆形末端(1)
- BasicStroke.CAP_SQUARE:方形末端(2,默认值)
线段交汇方式 join 的值可以是:
- BasicStroke.JOIN_BEVEL:无修饰(2)
- BasicStroke.JOIN_MITER:尖型末端(0,默认值)
- BasicStroke.JOIN_ROUND:圆形末端(1)
-
-
paint 属性:
该属性控制填充效果。
使用
setPaint(Paint p)
方法设置 paint 属性构造方法:
-
new GradientPaint(float x1, float y1, Color c1, float x2, float y2, Color c2)
:构造一个简单的非周期性的 paint 对象。从点 (x1, y1) 至点 (x2, y2) 处,颜色由 c1 渐变至 c2
-
new GradientPaint(float x1, float y1, Color c1, float x2, float y2, Color c2, boolean cyclic)
:构造一个周期或非周期性的 paint 对象。如果希望渐变至终点又是起点的颜色,将 cyclic 设定为 true
-
-
transform 属性:
该属性用来实现常用的图形平移、缩放、斜切等
使用
setTransform(Transform t)
方法设置 transform 属性构造方法:
-
new AffineTransform()
:构造一个表示仿射变换的新的 tansform仿射变换:用我的话来讲,就是保持坐标点不变的情况下变换坐标系,能形成的变换
常用方法:
-
setToRotation(double theta)
:旋转 theta 角度setToRotation(double theta, double x, double y)
:以 (x, y) 为旋转中心旋转rotate(double theta, double x, double y)
-
setToScale(double sx, double sy)
:拉伸变换x、y 方向按照 sx、yx 比例变换
scale(double sx, double sy)
-
setToTranslation(double tx, double ty)
:平移变换translate(double tx, double ty)
-
setToShear(double shx, double shy)
:斜切变换shx、shy 分别指定 x、y 方向的斜拉度
看得出来,出版社的人写到这里应该是到了下班的点了。内容不明不白的不说,还写错了好几处。
我笔记上是改过来的。放心。
就这还 ”指定教材“ 呢。垃圾,还没我笔记写得好。
-
-
clip 属性:
该属性用于实现剪裁效果。
使用
setClip(Shape clip)
方法,确定裁剪区域的 Shape。可以连续使用该方法以得到其交集区域 -
composit 属性:
该属性设置图形重叠区域的效果
通过
Alpha.Composite.getInstance(int rule, float alpha)
得到一个实例。其中 alpha(透明度)的范围是 [0.0f, 1.0f]至于 rule 是什么……我也不知道。或许不重要吧
通过
setComposite(Composite comp)
设置混合效果
#15.5.4.2 Graphics2D 的绘图方法
Graphics2D 保留了 Graphics 的绘图方法,又增加了很多新方法
另外,在 java.awt.geom 中声明了一系列类,能用于创建各种几何图形对象,包括:Line2D 线段类、Rectangle2D 矩形类、RoundRectangle2D 圆角矩形类、Ellipse2D 椭圆类、Arc2D 圆弧类、QuadCurve2D 二次曲线类、CubicCurve2D 三次曲线类
这些类都是抽象类,但这些类包中有实现了其方法的 Double 类。
...
@OverRide
public void paintComponents(Graphics g) {
Graphics2D g2d = (Graphics2D)g; //[1]
Line2D line = new Line2D.Double(5, 5, 5, 5); //[2]
g2d.draw(line); //[3]
}
将 Graphics 对象强制转型为 Graphics2D 对象
创建几何图形对象
这里的 Line2D.Double 表示 Line2D 包下的 Double 类。此处调用了 Double 类的构造器
绘制线段
#15.5.4.3 Graphics2D 中的几何图形类
-
new Line2D.Double(int x1, int y1, int x2, int y2)
:线段从 (x1, y1) 到 (x2, y2) 的线段
-
……(略了略了。相信椭圆、矩形之类的也不用再详细说明了吧)
-
new Arc2D.Double(double x, double y, double w, double h, double start, double extent, int type)
:弧但是特别地,type 的值是以下几种:
- Arc2D.OPEN:开弧
- Arc2D.CHORD:弓弧
- Arc2D.PIE:饼弧
-
new QuadCurver2D.Double(double x1, double y1, double ctrlx, double ctrly, double x2, double y2)
:绘制二次曲线绘制二次曲线需要 3 个点,分别是起始点 (x1, y1)、终点 (x2, y2)、控制点 (ctrlx, ctrly)
-
new CubicCurve2D.Double(double x1, double y1, double ctrlx1, double ctrly1, double ctrlx2, double ctrly2, double x2, double y2)
:绘制三次曲线绘制三次曲线需要 4 个点,分别是起始点、终点、两个控制点
15.6 组合框与列表
15.6.1 JComboBox 组合框
JComboBox 是一个下拉式菜单。它有两种模式:可编辑的、不可编辑的。
对于不可编辑的 JComboBox,用户只能在现有列表中进行选择
对于可编辑的 JComboBox,用户既能在现有选项中选择,也能输入新的内容
构造方法:
-
new JComboBox<E>()
:创建一个 E 类型(泛型)的没有任何可选项的默认组合框 -
new JComboBox<E>(E[] items)
:根据 items 数组创建组合框items 数组元素即为组合框的可选项
常用方法:
-
void setEditable(boolean aFlag)
:设置可编辑性不设置的场合,默认处于不可编辑状态
-
void addItem(E item)
:在末尾添加可选项void insertItemAt(E item, int index)
:在指定下标处添加可选项 -
void removeAllItems()
:删除所有可选项void removeItem(E iten)
:删除 item 指定的可选项void removeItemAt(int index)
:删除指定下标处的可选项 -
E getItemAt(int index)
:获取指定下标的可选项 -
int getItemCount()
:获取列表项数 -
int getSelectedIndex()
:获取选中项匹配的第一个选项的索引下标E getSelectedItem()
:获取选中项
15.6.2 JList 列表
JList 是可供用户选择的一系列可选项
构造方法:
new JList<E>()
:构造一个空列表new JList<E>(E[] listData)
:构造一个列表,可选元素由 listData 指定new JList<E>(Vector<E> listData)
:构造一个列表,使其显示指定 Vector 中的元素
常用方法:
-
addListSelectionListener(ListSelectionListener l)
:添加监视器当用户在列表上选择时,会触发 ListSelectionEvent 事件。
在 ListSelectionListener 接口中,仅有一个方法:
void valueChanged(ListSelectionEvent e);
当列表的当前选项改变时,会调用该方法。
-
int getSelectedIndex()
:返回选中项第一次出现的下标索引没有选中项的场合,返回 -1
E getSelectedValue()
:返回所选的第一个值没有选中项的场合,返回 null
-
void setVisableRowCount(int count)
:设置不使用滚动条可以在列表中显示的选项行数 -
void setSelectionMode(int mode)
:设置列表的选择模式其中,mode 的值可以是以下几种:
- ListSelectionModel.SINGLE_SELECTION:仅支持单项选择(0)
- ListSelectionModel.SINGLE_INTERVAL_SELECTION:可多选,但多个选项必须是连续的(1)
- ListSelectionModel.MULTIPLE_INTERVAL_SELECTION:可多选(2,默认值)
15.7 文本组件
文本组件可以提示信息和提供用户输入功能。Swing 中提供了 JTextField(文本域)、JPasswordField(口令输入域)、JTextArea(文本区)等多个文本组件。
文本组件的共同的父类是 JTextComponent,其中定义了文本组件的共有方法:
-
String getSelectedText()
:从文本组件中提取被选中的文本内容 -
String getText()
:从文本组件中提取全部文本内容String getText(int offs, int len)
:从文本组件中提取指定范围的文本内容 -
void select(inr start, int end)
:在文本组件中选中指定范围内容void selectAll()
:在文本组件中选中全部内容 -
void setEditable(boolean b)
:设置可编辑状态 -
void setText(String t)
:设置文本组件的文本内容 -
void setDocument(Document doc)
:设置文本组件的文档 -
void copy()
:复制选中文本至剪贴板void cut()
:剪切选中文本至剪贴板void paste()
:粘贴剪贴板内容至当前位置
另外,JComponrnt 类中有如下方法:
boolean requestFocusInWindow()
:请求当前组件获得输入焦点
15.7.1 JTextField 文本域
文本域是一个单行的文本输入框,可以用于输入少量文本
构造方法:
-
new JTextField()
:构造一个空文本域 -
new JTextField(int columns)
:构造一个指定列数的空文本域由于组件大小通常由布局管理器确定,因此指定的列数可能被忽略
-
new JTextField(String text)
:构造一个显示指定初始字符的文本域 -
new JTextField(String text, int columns)
:构造一个指定列数及初始字符的文本域
常用方法:
-
void addActionListener(ActionListener l)
:添加指定侦听器void removeActionListener(ActionListener l)
:移除指定侦听器 -
void setFont()
:设置当前字体 -
void setHorizontalAlignment(int alignment)
:设置水平对齐方式有效值包括:
-
JTextField.LEFT:左对齐(2)
-
JTextField.RIGHT:右对齐(4)
-
JTextField.CENTER:居中对齐(0)
-
JTextField.LEADING:领先对齐(10)
(似乎是)识别文字前端的对齐方式……好吧,我也不太明白
-
JTextField.TRAILING:落后对齐(11)
-
-
int getColumns()
:返回文本域列数
15.7.2 JTextArea 文本区
JTextArea 是一个多行多列的文本输入框
构造方法:
new JTextArea()
:构造一个空文本区new JTextArea(int rows, int columns)
:构造一个指定行数、列数数的空文本区new JTextArea(String text)
:构造一个显示指定初始字符的文本区new JTextArea(String text, int rows, int columns)
:构造一个指定行列数及初始字符的文本区
常用方法:
-
void append(String str)
:追加文本到文本区 -
void insert(String str, int pos)
:将指定文本插入到特定位置 pos 处 -
void replaceRange(String str, int start, int end)
:用指定文本 str 替换指定范围的文本 -
void addAncestorListener(AncestorListener listener)
:添加指定侦听器特别地,用户输入文本时,按下 Enter 键的场合只是向缓冲区输入一个字符,而不能表示输入的结束。因此,需要识别用户输入完成时,通常要在文本区旁放置一个确定按钮
15.8 菜单组件
菜单是最常用的 GUI 组件之一。Swing 包中提供了多种菜单组件。
菜单有下拉式菜单和弹出式菜单两种
15.8.1 菜单栏及菜单
JMenuBar 菜单栏是窗口主菜单,用来包容一组菜单
通过容器的
setJMenuBar(JMenuBar m)
方法将菜单栏放到窗口上
菜单栏 JMenuBar 构造方法:
new JMenuBar()
:构建一个新的菜单栏
菜单栏也能注册一些事件侦听程序,但通常情况下对于这些事件我们都不进行处理
菜单构造方法:
new JMenu()
:构造没有文本的新菜单new JMenu(String str)
:构造有指定标签的菜单new JMenu(String str, boolean b)
:构造有指定标签的菜单,并指示其是否可以被分离
常用方法:
-
add(JMenu m)
:菜单可以被加入菜单栏或另一个菜单中 -
addSeparator()
:为菜单各项间加入间隔线insertSeparator(int index)
:在指定位置插入间隔线也能通过这种方式插入间隔线:
menu.add(new JSeparator()); //JSeparator 类即分割线类
15.8.2 JMenuItem 菜单项
JMenuItem 菜单项是菜单系统的最下一级
构造方法:
-
new JMenuItem()
:创建不带有设置文本或图标的菜单项 -
new JMenuItem(Icon i)
:创建只有图标的菜单项 -
new JMenuItem(String str)
:创建只有文本的菜单项 -
new JMenuItem(String str, Icon i)
:创建有图标和文本的菜单项 -
new JMenuItem(String str, int mnemonic)
:创建有文本和快捷键的菜单项那个快捷键的有效值是 KeyEvent 包下的各种常量
常用方法:
-
setMnemonic(int m)
:设置快捷键 -
setAccelerator(KeyStroke keyStroke)
:设置加速键 -
addActionListener(ActionListener l)
:加入侦听器菜单项被选中时,会触发 ActionEvent 事件
15.8.3 复选菜单项和单选菜单项
JCheckBoxMenuItem(复选菜单项)和 JRadioButtonMenuItem(单选菜单项)是两种特殊的菜单项。
JCheckBoxMenuItem 前有个小方框,以供提示复选
JRadioButtonMenuItem 前有个小圆圈,以供提示单选
复选菜单项构造器:
new JCheckBoxMenuItem()
:一个无文本图标,初始未选中的菜单项new JCheckBoxMenuItem(Icon i)
:就是有图标咯new JCheckBoxMenuItem(String str)
:就是有文本咯new JCheckBoxMenuItem(String str, boolean b)
:就是有文本,又指定初始状态咯new JCheckBoxMenuItem(String str, Icon i)
:就是有文本,又有图标咯new JCheckBoxMenuItem(String str, Icon i, boolean b)
:你猜呗
单选菜单项构造器:
单选菜单项是 JRadioButtonMenuItem,剩下的都和上面的一样
15.9 对话框
对话框是一个临时的可移动窗口,其依赖于其他窗口。当期依赖的窗口消失或最小化时,对话框消失。窗口还原时对话框恢复。
对话框分为强制型和非强制型。强制型对话框在关闭前,其他窗口不能接收任何形式的输入。也就是说,该对话过程不能中断。强制型对话框也被称为模式窗口。
15.9.1 JDialog 自定义对话框
构造方法:
-
new JDialog(Dialog owner)
:无标题无模式对话框。指定对话框为其所有者new JDialog(Frame owner)
:指定框架为其所有者 -
new JDialog(Dialog owner, boolean model)
:无标题对话框,指定所有者并指示是否为有模式 -
new JDialog(Dialog owner, String title)
new JDialog(Frame owner, String title)
new JDialog(Dialog owner, String title, boolean model)
new JDialog(Frame owner, String title, boolean model)
:这些你都懂的吧
15.9.2 JOptionalPane 标准对话框
JDialog 通常用于创建自定义对话框。此外,还有用于显示标准对话框的 JOptionalPane 类
JOptionalPane 定义了多个静态方法,分为以下 4 个类型:
-
showConfirmDialog:确认对话框。显示问题,要求用户进行确认(yes / no / cancel)
其同名方法有以下 3 种
-
int showConfirmDialog(Component parentComponent, Object message)
-
int showConfirmDialog(Component parentComponent, Object message, String title, int optionType)
-
int showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType)
-
-
showInputDialog:输入对话框。提示用户进行输入
同名方法有以下 6 种:
-
showInputDialog(Object message)
-
showInputDialog(Object message, Object initialValue)
-
showInputDialog(Component parentComponent, Object message)
-
showInputDialog(Component parentComponent, Object message, Object initialValue)
-
showInputDialog(Component parentComponent, Object message, String title, int messageType)
-
showInputDialog(Component parentComponent, Object message, String title, int messageType, Icon icon, Object[] options, Object initialValue)
-
-
showMessageDialog:信息对话框。显示信息
同名方法有以下 3 种:
-
showMessageDialog(Component parentComponent, Object message)
-
showMessageDialog(Component parentComponent, Object message, String title, int messageType)
-
showMessageDialog(Component parentComponent, Object message, String title, int messageType, Icon icon)
-
-
showOptionDialog:选项对话框,显示选项,要求用户进行选择
其只有 1 种同名方法
- showOptionDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon, Object[] options, Object initialValue)
以上各个方法的参数分别是:
-
Component parentComponent:对话框的父窗口对象。其父窗口位置决定了对话框位置
该值可以是 null,表示用默认的 Frame 作为父窗口。这个场合,对话框位置在屏幕正中
-
Object message:显示在对话框的描述信息。
该参数通常是 String 对象,但也能是一个图标、组件或对象数组
-
String title:对话框标题
-
int optionType:对话框上的按钮类型。可以是以下常量:
- JOptionalPane.DEFAULT_OPTION:默认(-1)
- JOptionalPane.YES_NO_OPTION:一组 yes / no(0)
- JOptionalPane.YES_NO_CANCEL_OPTION:一组 yes / no / cancel(1)
- JOptionalPane.OK_CANCEL_OPTION:一组 ok / cancel(2)
此外,也能通过 Object[] options 参数指定其他形式
-
Object[] options:对话框上的选项。
在输入对话框中,通常以组合框架形式显示。在选项对话框中,则是指按钮类型。
该参数通常是一个 String[] 数组,但也能是图标数组或组件数组
-
int messageType:对话框传递的信息类型。可以是以下常量:
- JOptionalPane.ERROR_MESSAGE:错误信息(0)
- JOptionalPane.INFORMATION_MESSAGE:普通信息(1)
- JOptionalPane.WARNING_MESSAGE:警告信息(2)
- JOptionalPane.QUESTION_MESSAGE:提问信息(3)
- JOptionalPane.PLAIN_MESSAGE:无格式信息(-1)
除 PLAIN_MESSAGE 外,每种类型对应于一个默认的图标
-
Object initialValue:初始选项或输入值
15.9.3 JFileChooser 文件对话框
JFileChooser 文件对话框是专门用于对文件或目录进行浏览和选择的对话框
构造方法:
new JFileChooser()
:构造一个指向客户默认目录的文件对话框new JFileChooser(File currentDirectory)
:指向指定目录的文件对话框new JFileChooser(String path)
:指向指定目录的文件对话框
常用方法:
-
showOpenDialog(Component parent)
:弹出一个 “打开” 文件对话框parent 是对话框的父窗口对象。其父窗口位置决定了对话框位置
该值可以是 null,表示用默认的 Frame 作为父窗口。这个场合,对话框位置在屏幕正中
showSaveDialog(Component parent)
:弹出一个 “保存” 文件对话框 -
getSelectedFile()
:获得用户选择的文件