GUI图形化演示
概述
Swing组件通常被称为“轻量级组件”,他完全由Java编写,不依赖操作系统语言,他的类继承关系如下:
Java.lang.Object->Java.awt.Component->Java.awt.Container->Javax.swing.JCompoment
JCompoent是swing组件存放的位置,
常用组件如下:
组件名称 | 说明 |
---|---|
JFrame | 框架 |
JDialog | 对话框 |
JOptionPane | 对话框 |
JButton | 按钮 |
JCheckBox | 复选框 |
JComboBox | 下拉框 |
JLabel | 标签 |
JRadioButton | 单选按钮 |
JList | 显示一组条目的组件 |
JTextField | 文本框 |
JPasswordField | 密码框 |
JTextArea | 文本区域 |
继承关系图:
JFrame:
JFrame是一个容器,他是各个组件的载体,在开发过程,我们通过继承java.swing.JFrame来创建给窗体。一般使用BorderLayout布局方式
一.新建JFrame对象:
- new JFrame()创建没有标题的。//也可以直接传一个字符串当作标题
- Frame(String s)创建标题为s的窗口,
二.设置JFrame的大小:
- public void setSize(int width, int height) 设置窗口的大小。
- public void setLocation(int x, int y) 设置窗口的位置,默认位置是 (0, 0) 。
- public void setBounds(int a, int b, int width, int height) 设置窗口的初始位置是 (a, b) ,窗口的宽是 width ,高是 height 。
- public void setVisible(boolean b) 设置窗口是否可见,窗口默认是不可见的。
- public void setResizable(boolean b) 设置窗口是否可调整大小,默认可调整大小。
- public void dispose() 撤销当前窗口,并释放当前窗口所使用的资源。
- public void setExtendedState(int state) 设置窗口的扩展状态,其中参数 state 取 JFrame 类中的下列类常量:
- - MAXIMIZED_HORIZ (水平方向最大化)
- - MAXIMIZED_VERT (垂直方向最大化)
- - MAXIMIZED_BOTH (水平、垂直方向都最大化)
三.设定JFrame的关闭方式
- public void setDefaultCloseOperation(int operation) 该方法用来设置单击窗体右上角的关闭图标后,程序会做出怎样的处理,其中的参数 operation 取 JFrame 类中的下列 int 型 static 常量,程序根据参数 operation 取值做出不同的处理:
- - DO_NOTHING_ON_CLOSE (什么也不做)
- - HIDE_ON_CLOSE (隐藏当前窗口)
- - DISPOSE_ON_CLOSE (隐藏当前窗口,并释放窗体占有的其他资源)
- - EXIT_ON_CLOSE (结束窗口所在的应用程序)
下面来写一下:
package pdsu__zjh;import javax.swing.*;import javax.swing.JFrame;
public class Textt {public static void main(String []args) {JFrame jf=new JFrame();jf.setSize(400,250);//设置长宽jf.setLocation(400,250);//设置位置jf.setVisible(true);//设置是否显示!!!!jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭方式}
}
结果:
布局方式:
setLayout 方法概述
在 Java 的 JFrame
中,setLayout
方法用于设置容器的布局管理器。布局管理器决定了容器中组件的排列方式。JFrame
默认使用 BorderLayout
,但可以通过 setLayout
方法更改为其他布局管理器。
好处:布局方式可以让组件的位置随着窗口的大小而改变。
常用布局管理器
-
BorderLayout(边界布局)
- 将容器分为五个区域:
NORTH
、SOUTH
、EAST
、WEST
和CENTER
。 - 示例代码:
JFrame frame = new JFrame("BorderLayout Example"); // 设置JFrame的布局管理器为BorderLayout,用于管理组件的布局 frame.setLayout(new BorderLayout()); // 创建一个按钮,按钮上的文本为"North",并将其添加到JFrame的NORTH区域 frame.add(new JButton("North"), BorderLayout.NORTH); // 创建一个按钮,按钮上的文本为"South",并将其添加到JFrame的SOUTH区域 frame.add(new JButton("South"), BorderLayout.SOUTH); // 创建一个按钮,按钮上的文本为"East",并将其添加到JFrame的EAST区域 frame.add(new JButton("East"), BorderLayout.EAST); // 创建一个按钮,按钮上的文本为"West",并将其添加到JFrame的WEST区域 frame.add(new JButton("West"), BorderLayout.WEST); // 创建一个按钮,按钮上的文本为"Center",并将其添加到JFrame的CENTER区域 frame.add(new JButton("Center"), BorderLayout.CENTER); // 设置JFrame的大小为宽度300像素,高度200像素 frame.setSize(300, 200); // 设置JFrame的默认关闭操作,当关闭窗口时退出应用程序 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置JFrame可见,即显示窗口 frame.setVisible(true);
- 将容器分为五个区域:
-
FlowLayout(流式布局)
- (组件按照添加顺序从左到右排列,当一行排满时自动换行。
- 示例代码:
JFrame frame = new JFrame("FlowLayout Example"); frame.setLayout(new FlowLayout()); frame.add(new JButton("Button 1")); frame.add(new JButton("Button 2")); frame.add(new JButton("Button 3")); frame.setSize(300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true);
-
GridLayout(网格布局)
- 将容器划分为指定行数和列数的网格,组件按顺序填充网格。
- 示例代码:
JFrame frame = new JFrame("GridLayout Example"); frame.setLayout(new GridLayout(2, 3)); // 2行3列 frame.add(new JButton("Button 1")); frame.add(new JButton("Button 2")); frame.add(new JButton("Button 3")); frame.add(new JButton("Button 4")); frame.add(new JButton("Button 5")); frame.setSize(300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true);
-
GridBagLayout
- 提供更灵活的布局方式,允许组件跨越多个行和列。
- 示例代码:
JFrame frame = new JFrame("GridBagLayout Example"); frame.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; frame.add(new JButton("Button 1"), gbc); gbc.gridx = 1; gbc.gridy = 0; frame.add(new JButton("Button 2"), gbc); gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 2; frame.add(new JButton("Button 3"), gbc); frame.setSize(300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true);
自定义布局
如果默认的布局管理器不满足需求,可以通过实现 LayoutManager
接口来自定义布局。自定义布局需要实现 LayoutManager
接口中的方法,如 addLayoutComponent
、removeLayoutComponent
、layoutContainer
等。
注意事项
- 在设置布局管理器后,添加的组件将按照新的布局管理器进行排列。
- 如果不需要布局管理器,可以将布局管理器设置为
null
,此时需要手动设置组件的位置和大小。
JFrame frame = new JFrame("Null Layout Example");
frame.setLayout(null);
JButton button = new JButton("Button");
button.setBounds(50, 50, 100, 30); // 手动设置位置和大小
frame.add(button);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
通过 setLayout
方法,可以灵活地控制 JFrame
中组件的排列方式,满足不同的界面设计需求。
面板与布局的嵌套:
我们都知道一个窗口只有一种布局方式,如果想让你的窗口既有流水布局,又有网格布局等,要怎么操作呢?这个时候就要用到面板了,面板是个很小的容器,也是组件可以添加在窗口中。
简单例子:
package pdsu__zjh;import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;public class Textt {public static void main(String[] args) {// 创建一个JFrame窗口JFrame frame = new JFrame();// 设置窗口的位置和大小(x坐标500, y坐标500, 宽度500, 高度400)frame.setBounds(500, 500, 500, 400);// 使窗口可见(注意:应在所有组件添加完成后再调用此方法)frame.setVisible(true);// 创建GridLayout布局管理器(默认2行1列)GridLayout gridLayout = new GridLayout();// 设置布局的行数为2(列数会根据添加的组件数量自动计算)gridLayout.setRows(2);// 将JFrame的布局管理器设置为GridLayoutframe.setLayout(gridLayout);// 创建第一个面板(使用AWT的Panel类)Panel panel1 = new Panel();// 设置面板背景颜色为粉色panel1.setBackground(Color.PINK);// 创建第二个面板(使用AWT的Panel类)Panel panel2 = new Panel();// 设置面板背景颜色为青色panel2.setBackground(Color.CYAN);// 将面板1添加到JFrame中(GridLayout的第一行)frame.add(panel1);// 将面板2添加到JFrame中(GridLayout的第二行)frame.add(panel2);}
}
监听器:
监听器的概念
在Java中,监听器(Listener)是一种设计模式,用于监听特定事件的发生。当事件发生时,监听器会触发相应的处理逻辑。监听器通常用于GUI编程、网络编程等场景,用于处理用户交互、数据变化等事件。
监听器的类型
Java中常见的监听器类型包括:
- ActionListener:用于处理按钮点击等动作事件。
- MouseListener:用于处理鼠标点击、移动等事件。
- KeyListener:用于处理键盘按键事件。
- WindowListener:用于处理窗口事件,如窗口打开、关闭等。
- ItemListener:用于处理复选框、下拉列表等组件的状态变化事件。
监听器的使用步骤
- 实现监听器接口:创建一个类并实现相应的监听器接口,重写接口中的方法。
- 注册监听器:将监听器对象注册到需要监听的组件上。
- 处理事件:在监听器的方法中编写事件处理逻辑。
- 还有一种是使用内部类,将1和2步骤写在一起,用匿名内部类的格式
示例代码
以下是一个使用ActionListener
的简单示例,监听按钮点击事件:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class ButtonClickListener {public static void main(String[] args) {JFrame frame = new JFrame("Button Click Example");JButton button = new JButton("Click Me");// 创建监听器对象ActionListener listener = new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("Button clicked!");}};// 注册监听器button.addActionListener(listener);frame.add(button);frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}
}
自定义监听器
除了使用Java提供的标准监听器接口,还可以自定义监听器接口和实现类。以下是一个自定义监听器的示例:
// 自定义监听器接口,定义了事件处理方法
interface MyEventListener {// 定义一个方法,用于处理事件,参数message表示事件相关的信息void onEvent(String message);
}// 事件源类,负责触发事件并通知监听器
class EventSource {// 声明一个监听器对象,用于存储注册的监听器private MyEventListener listener;// 设置监听器的方法,将传入的监听器对象赋值给成员变量listenerpublic void setEventListener(MyEventListener listener) {this.listener = listener;}// 触发事件的方法,当调用此方法时会通知已注册的监听器处理事件public void triggerEvent(String message) {// 检查是否有已注册的监听器if (listener != null) {// 如果有监听器,则调用监听器的onEvent方法,并传递事件信息messagelistener.onEvent(message);}}
}// 监听器实现类,实现了MyEventListener接口,处理具体的事件逻辑
class MyEventListenerImpl implements MyEventListener {// 实现接口中的onEvent方法,用于处理接收到的事件@Overridepublic void onEvent(String message) {// 简单地打印出接收到的事件信息System.out.println("Event received: " + message);}
}public class CustomListenerExample {public static void main(String[] args) {// 创建一个事件源对象EventSource source = new EventSource();// 为事件源设置一个监听器,这里创建了一个监听器实现类的实例并传入source.setEventListener(new MyEventListenerImpl());// 触发事件,调用事件源的triggerEvent方法并传递事件信息source.triggerEvent("Hello, Custom Listener!");}
}
使用自定义监听器
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;// 自定义监听器接口
interface MyButtonListener {void onButtonClicked(String message);
}// 自定义JFrame类,包含按钮和监听器注册机制
class MyFrame extends JFrame {private JButton button;private MyButtonListener listener;public MyFrame(String title) {super(title);setSize(300, 200);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setLayout(new FlowLayout());// 创建按钮button = new JButton("点击我");add(button);// 为按钮添加内置的ActionListenerbutton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// 当按钮被点击时,触发自定义监听器的事件if (listener != null) {listener.onButtonClicked("按钮被点击了!");}}});}// 注册自定义监听器的方法public void setMyButtonListener(MyButtonListener listener) {this.listener = listener;}
}// 主类:演示如何使用自定义监听器
public class CustomListenerInFrameExample {public static void main(String[] args) {SwingUtilities.invokeLater(() -> {// 创建自定义窗口MyFrame frame = new MyFrame("自定义监听器示例");// 注册自定义监听器frame.setMyButtonListener(new MyButtonListener() {@Overridepublic void onButtonClicked(String message) {// 实现自定义事件处理逻辑JOptionPane.showMessageDialog(frame, message, "事件通知", JOptionPane.INFORMATION_MESSAGE);}});frame.setVisible(true);});}
}
总结
Java中的监听器机制为事件驱动编程提供了强大的支持。通过实现和注册监听器,可以有效地处理各种用户交互和系统事件。无论是使用标准监听器接口还是自定义监听器,都可以根据具体需求灵活地设计和实现事件处理逻辑。
滚动面板和列表
面板:
1. Panel(AWT 组件)
- AWT 组件:属于
java.awt
包,是 AWT 库中最基本的容器组件。 - 重量级:每个
Panel
对应一个原生窗口句柄,依赖底层操作系统绘制。 - 简单功能:主要用于组织和布局其他组件,不支持复杂 UI 特性。
- 有限定制:外观由操作系统决定,难以实现自定义样式(如透明效果)。
- 事件模型:使用 AWT 事件模型,处理方式较繁琐。
核心方法:
add(Component comp)
:添加子组件。setLayout(LayoutManager mgr)
:设置布局管理器。setBackground(Color c)
:设置背景颜色。
示例代码:
java
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;public class PanelExample {public static void main(String[] args) {Frame frame = new Frame("AWT Panel示例");frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});// 创建Panel并设置布局Panel panel = new Panel();panel.setLayout(new FlowLayout());// 添加组件到Panelpanel.add(new Button("按钮1"));panel.add(new Button("按钮2"));frame.add(panel);frame.setSize(300, 200);frame.setVisible(true);}
}
2. JPanel(Swing 组件)
特点:
- Swing 组件:属于
javax.swing
包,是 Swing 库中常用的轻量级容器。 - 轻量级:不依赖原生窗口句柄,由 Java 代码绘制,跨平台一致性好。
- 丰富功能:支持双缓冲、透明效果、边框装饰等现代 UI 特性。
- 高度可定制:可自定义外观、添加事件监听器、使用 Swing 提供的各种 UI 组件。
- 事件模型:与 Swing 事件模型集成,处理更简洁(如使用匿名内部类)。
核心方法:
add(Component comp)
:添加子组件。setLayout(LayoutManager mgr)
:设置布局管理器。setOpaque(boolean isOpaque)
:设置是否透明。setBorder(Border border)
:设置边框样式。
示例代码:
java
package pdsu__zjh;import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;public class Textt {public static void main(String[] args) {JFrame frame=new JFrame("Hallow!,World");frame.setBounds(500, 500, 500, 500);frame.setAlwaysOnTop(true);//将窗口置顶ScrollPane scollPane=new ScrollPane();frame.add(scollPane);GridLayout gridLayout=new GridLayout();gridLayout.setRows(20);Panel panel=new Panel();panel.setLayout(gridLayout);for (int i = 0; i < 20; i++) {panel.add(new Button("按钮"+i));}scollPane.add(panel);frame.setVisible(true);}
}
主要区别对比
特性 | JPanel (Swing) | Panel (AWT) |
---|---|---|
包路径 | javax.swing | java.awt |
组件类型 | 轻量级(Java 纯代码实现) | 重量级(依赖原生窗口系统) |
透明效果 | 支持setOpaque(false) | 不支持,始终完全不透明 |
边框装饰 | 支持各种边框(BorderFactory ) | 无内置边框支持 |
双缓冲 | 默认启用,减少闪烁 | 不支持,可能有绘制闪烁问题 |
事件处理 | 更简洁(如匿名内部类) | 较繁琐(需实现接口) |
布局管理器 | 完全支持所有布局管理器 | 支持基本布局,但对复杂布局支持有限 |
推荐场景 | 现代 Java GUI 应用(JFrame、JDialog) | 传统 AWT 应用或简单工具 |
选择建议
-
优先使用 JPanel:
- 如果你的应用是基于 Swing 的。
- 需要透明效果、自定义边框或其他现代 UI 特性。
- 需要更好的跨平台一致性。
-
使用 Panel:
- 在纯 AWT 应用中,或需要与旧代码兼容时。
- 对 UI 要求简单,不需要复杂的视觉效果。
-
注意事项:
- 避免在同一个界面中混用 AWT 和 Swing 组件,可能导致绘制问题和性能下降。
- 使用 Swing 组件时,确保在事件调度线程(EDT)中创建和操作 UI,避免线程安全问题。
常见应用场景
-
JPanel:
- 创建复杂的表单界面(如注册页面)。
- 实现分区域布局(如左侧菜单 + 右侧内容)。
- 作为自定义组件的基类(如游戏面板)。
-
Panel:
- 简单的工具窗口(如计算器)。
- 与 AWT 绘图 API 结合使用(如
Graphics
)。 - 旧 Java 应用的维护和扩展。
2 滚动面板
Swing组件不能使用setDefaultCloseOperation()方法,如果想要关闭就要设置事件
1. JScrollPane(Swing 组件)
特点:
- Swing 组件:属于 Swing 包(
javax.swing
),支持现代 UI 特性(如双缓冲、透明效果)。 - 可定制性强:支持水平和垂直滚动条的精细控制,可自定义滚动条样式、显示策略。
- 事件驱动:与 Swing 事件模型集成,适合复杂交互场景。
- 线程安全:建议在事件调度线程(EDT)中操作,避免 UI 更新冲突。
- 轻量级:不依赖底层窗口系统,跨平台一致性好。
核心方法:
setViewportView(Component view)
:设置需要滚动显示的组件。setHorizontalScrollBarPolicy(int policy)
:设置水平滚动条的显示策略。setVerticalScrollBarPolicy(int policy)
:设置垂直滚动条的显示策略。getHorizontalScrollBar()
/getVerticalScrollBar()
:获取滚动条实例进行定制。
示例代码(修正后的版本):
java
import javax.swing.*;
import java.awt.*;public class JScrollPaneExample {public static void main(String[] args) {SwingUtilities.invokeLater(() -> {JFrame frame = new JFrame("JScrollPane示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 创建内容面板JPanel contentPanel = new JPanel();contentPanel.setLayout(new GridLayout(20, 1)); // 20行1列for (int i = 0; i < 20; i++) {contentPanel.add(new JButton("按钮" + i));}// 创建JScrollPane并设置内容面板JScrollPane scrollPane = new JScrollPane(contentPanel);scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);frame.add(scrollPane);frame.setSize(400, 300);frame.setVisible(true);});}
}
2. ScrollPane(AWT 组件)
特点:
- AWT 组件:属于 AWT 包(
java.awt
),依赖底层窗口系统绘制。 - 简单直接:功能相对基础,适合简单滚动需求。
- 重量级:每个组件对应一个原生窗口句柄,可能影响性能。
- 有限定制:滚动条样式和行为由操作系统决定,定制性差。
- 兼容性:与 AWT 事件模型集成,在纯 AWT 应用中使用更方便。
核心方法:
add(Component comp)
:添加需要滚动显示的组件(自动处理滚动)。setScrollbarDisplayPolicy(int policy)
:设置滚动条显示策略。getHAdjustable()
/getVAdjustable()
:获取滚动条的调整器(用于手动控制)。
示例代码:
java
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;public class ScrollPaneExample {public static void main(String[] args) {Frame frame = new Frame("ScrollPane示例");frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});// 创建AWT ScrollPaneScrollPane scrollPane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);// 创建内容面板Panel contentPanel = new Panel();contentPanel.setLayout(new GridLayout(20, 1));for (int i = 0; i < 20; i++) {contentPanel.add(new Button("按钮" + i)); // AWT Button}// 添加内容到ScrollPanescrollPane.add(contentPanel);frame.add(scrollPane);frame.setSize(400, 300);frame.setVisible(true);}
}
3. 主要区别对比
特性 | JScrollPane (Swing) | ScrollPane (AWT) |
---|---|---|
包路径 | javax.swing | java.awt |
组件类型 | 轻量级(Java 纯代码实现) | 重量级(依赖原生窗口系统) |
添加内容方式 | setViewportView(component) | add(component) |
滚动条定制 | 高度可定制(颜色、样式、策略) | 由操作系统决定,定制性差 |
事件处理 | 与 Swing 事件模型集成 | 与 AWT 事件模型集成 |
线程安全性 | 需要在 EDT 中操作 | 无需特殊处理(但可能有线程问题) |
布局管理器支持 | 支持复杂布局(如嵌套面板) | 简单布局,依赖容器默认布局 |
推荐场景 | 现代 Java GUI 应用(JFrame、JDialog) | 传统 AWT 应用或简单工具 |
4. 选择建议
- 优先使用 JScrollPane:如果你的应用是基于 Swing 的,需要更好的 UI 定制性和跨平台一致性。
- 使用 ScrollPane:在纯 AWT 应用中,或需要与旧代码兼容时。
- 注意事项:避免在同一个界面中混用 AWT 和 Swing 组件,可能导致绘制问题和性能下降。
列表组件:
我只介绍一下AWT中的列表组件:
在 Java AWT(Abstract Window Toolkit)中,列表组件主要提供两种:List
(下拉列表框)和Choice
(单选下拉菜单)。它们都是用户界面中常用的选择组件,但功能和使用场景略有不同。
1. List 组件
java.awt.List
是一个可滚动的多行选择列表,支持单选或多选。
特点:
- 显示多个选项,可通过滚动条浏览。
- 支持单选(默认)或多选(通过
setMultipleMode(true)
启用)。 - 用户可通过鼠标或键盘选择一个或多个项目。
核心方法:
add(String item)
:添加选项。select(int index)
:选择指定索引的选项。getSelectedIndex()
:获取选中项的索引(单选模式)。getSelectedIndexes()
:获取所有选中项的索引(多选模式)。setMultipleMode(boolean b)
:启用 / 禁用多选模式。
示例代码:
java
import java.awt.*;
import java.awt.event.*;public class ListExample {public static void main(String[] args) {Frame frame = new Frame("AWT List 示例");frame.setSize(300, 200);// 创建List组件(默认单选)List list = new List(5); // 显示5行list.add("选项1");list.add("选项2");list.add("选项3");list.add("选项4");list.add("选项5");// 添加按钮获取选中项Button button = new Button("获取选中项");button.addActionListener(e -> {int selectedIndex = list.getSelectedIndex();if (selectedIndex >= 0) {System.out.println("选中项: " + list.getItem(selectedIndex));}});frame.add(list, BorderLayout.CENTER);frame.add(button, BorderLayout.SOUTH);// 添加窗口关闭事件frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});frame.setVisible(true);}
}
2. Choice 组件
java.awt.Choice
是一个单行的下拉选择菜单,用户点击后展开选项列表。
特点:
- 只显示当前选中项,点击后弹出选项列表。
- 仅支持单选。
- 占用空间小,适合选项较多的场景。
核心方法:
add(String item)
:添加选项。select(int index)
:选择指定索引的选项。select(String item)
:选择指定文本的选项。getSelectedIndex()
:获取选中项的索引。getSelectedItem()
:获取选中项的文本。
示例代码:
java
import java.awt.*;
import java.awt.event.*;public class ChoiceExample {public static void main(String[] args) {Frame frame = new Frame("AWT Choice 示例");frame.setSize(300, 200);// 创建Choice组件Choice choice = new Choice();choice.add("红色");choice.add("绿色");choice.add("蓝色");choice.add("黄色");// 添加按钮获取选中项Button button = new Button("获取颜色");button.addActionListener(e -> {String selectedColor = choice.getSelectedItem();System.out.println("选中的颜色: " + selectedColor);});frame.add(choice, BorderLayout.NORTH);frame.add(button, BorderLayout.SOUTH);// 添加窗口关闭事件frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});frame.setVisible(true);}
}
3. List vs Choice 对比
特性 | List | Choice |
---|---|---|
显示方式 | 多行列表,可滚动 | 单行下拉菜单,点击展开 |
选择模式 | 支持单选和多选 | 仅支持单选 |
默认行为 | 直接显示所有选项(部分可见) | 仅显示当前选中项 |
适用场景 | 选项较少,需快速浏览和选择 | 选项较多,节省空间 |
常用方法 | getSelectedIndexes() (多选) | getSelectedItem() (单选) |
4. 事件处理
两者都可通过ItemListener
监听选择变化:
java
list.addItemListener(e -> {if (e.getStateChange() == ItemEvent.SELECTED) {System.out.println("选中: " + list.getSelectedItem());}
});choice.addItemListener(e -> {if (e.getStateChange() == ItemEvent.SELECTED) {System.out.println("选中: " + choice.getSelectedItem());}
});
5. 注意事项
- AWT 组件的线程安全:虽然 AWT 不是严格线程安全的,但简单应用通常无需特殊处理。对于复杂场景,建议在事件调度线程中操作 UI。
- Swing 替代方案:如果需要更现代的 UI 组件,可使用 Swing 的
JList
和JComboBox
,它们提供了更丰富的功能和更好的外观控制。
如果你需要更多自定义选项(如自定义渲染器或复杂布局),建议转向 Swing 或 JavaFX。
常见组件:
组件就是AWT为我们设置好的一些可以直接使用的界元素:按钮,文本框,标签,我们可以用这些帮我们写好的组件来快速拼凑出功能强大的程序
标签组件:
标签组件的基本概念
在Java中,标签组件通常用于在图形用户界面(GUI)中显示文本或图像。标签组件是不可编辑的,主要用于提供信息或描述其他组件。Java提供了多种标签组件,最常用的是JLabel
类,它属于javax.swing
包。
创建标签组件
使用JLabel
类可以轻松创建标签组件。可以通过构造函数传递文本或图像来初始化标签。以下是一个简单的示例,展示如何创建一个文本标签:
import javax.swing.JFrame;
import javax.swing.JLabel;public class LabelExample {public static void main(String[] args) {JFrame frame = new JFrame("Label Example");JLabel label = new JLabel("Hello, World!");frame.add(label);frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}
}
设置标签的文本和图像
JLabel
类提供了多种方法来设置标签的文本和图像。可以使用setText()
方法设置文本,使用setIcon()
方法设置图像。以下示例展示了如何同时设置文本和图像:
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;public class LabelWithImage {public static void main(String[] args) {JFrame frame = new JFrame("Label with Image");JLabel label = new JLabel("Java Logo");ImageIcon icon = new ImageIcon("java_logo.png");label.setIcon(icon);frame.add(label);frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}
}
标签的对齐方式
JLabel
类允许设置文本和图像的对齐方式。可以使用setHorizontalAlignment()
和setVerticalAlignment()
方法来控制标签内容的对齐方式。以下示例展示了如何设置标签的水平和垂直对齐方式:
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;public class LabelAlignment {public static void main(String[] args) {JFrame frame = new JFrame("Label Alignment");JLabel label = new JLabel("Centered Text", SwingConstants.CENTER);label.setVerticalAlignment(SwingConstants.CENTER);frame.add(label);frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}
}
标签的字体和颜色
可以通过setFont()
方法设置标签的字体,通过setForeground()
方法设置文本颜色。以下示例展示了如何设置标签的字体和颜色:
import java.awt.Color;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;public class LabelFontAndColor {public static void main(String[] args) {JFrame frame = new JFrame("Label Font and Color");JLabel label = new JLabel("Styled Text");Font font = new Font("Serif", Font.BOLD, 18);label.setFont(font);label.setForeground(Color.BLUE);frame.add(label);frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}
}
标签的事件处理
虽然标签组件通常不处理用户输入,但可以通过添加事件监听器来实现一些交互功能。例如,可以为标签添加鼠标点击事件监听器:
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;public class LabelClickEvent {public static void main(String[] args) {JFrame frame = new JFrame("Label Click Event");JLabel label = new JLabel("Click Me!");label.addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent e) {label.setText("Clicked!");}});frame.add(label);frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}
}
通过以上方法,可以在Java应用程序中灵活使用标签组件,实现各种界面设计需求。
小结:
在这里我调试了许久,总结的有,如果要添加标签,最好先添加在JPanel页面中,然后再将JPanel添加进入JFrame中,并且他们的布局方式也不一样,JFrame用的是BorderLayout,JPanel用的是FlowLayout布局方式,详细可以看之前写的内容。
按钮组件
在Java中,按钮组件通常通过JButton
类来实现,它是javax.swing
包的一部分。JButton
用于创建可点击的按钮,用户可以通过点击按钮来触发特定的事件。
创建按钮
要创建一个按钮,可以使用JButton
类的构造函数。最简单的形式是创建一个带有文本标签的按钮。
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.FlowLayout;public class ButtonExample {public static void main(String[] args) {JFrame frame = new JFrame("Button Example");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setLayout(new FlowLayout());JButton button = new JButton("Click Me");frame.add(button);frame.setSize(300, 200);frame.setVisible(true);}
}
添加事件监听器
按钮通常需要与用户交互,因此需要为按钮添加事件监听器。可以使用ActionListener
接口来处理按钮点击事件。
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class ButtonExample {public static void main(String[] args) {JFrame frame = new JFrame("Button Example");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setLayout(new FlowLayout());JButton button = new JButton("Click Me");button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("Button clicked!");}});frame.add(button);frame.setSize(300, 200);frame.setVisible(true);}
}
设置按钮属性
JButton
类提供了多种方法来设置按钮的属性,例如设置按钮的文本、图标、工具提示等。
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import java.awt.FlowLayout;public class ButtonExample {public static void main(String[] args) {JFrame frame = new JFrame("Button Example");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setLayout(new FlowLayout());JButton button = new JButton("Click Me");button.setToolTipText("This is a button");button.setIcon(new ImageIcon("icon.png"));frame.add(button);frame.setSize(300, 200);frame.setVisible(true);}
}
按钮布局
按钮可以放置在容器的不同位置,通常使用布局管理器来控制按钮的位置和大小。常见的布局管理器包括FlowLayout
、BorderLayout
、GridLayout
等。
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.BorderLayout;public class ButtonExample {public static void main(String[] args) {JFrame frame = new JFrame("Button Example");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setLayout(new BorderLayout());JButton button1 = new JButton("North");JButton button2 = new JButton("South");JButton button3 = new JButton("East");JButton button4 = new JButton("West");JButton button5 = new JButton("Center");frame.add(button1, BorderLayout.NORTH);frame.add(button2, BorderLayout.SOUTH);frame.add(button3, BorderLayout.EAST);frame.add(button4, BorderLayout.WEST);frame.add(button5, BorderLayout.CENTER);frame.setSize(300, 200);frame.setVisible(true);}
}
通过以上方法,可以在Java应用程序中创建和使用按钮组件,并根据需要设置其属性和事件处理逻辑。
菜单栏和弹出菜单
菜单:顾名思义就是包含各种基本操作的组件,程序中我们经常使用下拉菜单:
菜单的层级结构:
MenuBar (菜单栏)
├─ Menu (文件)
│ ├─ MenuItem (新建)
│ ├─ MenuItem (打开)
│ └─ MenuItem (保存)
├─ Menu (编辑)
│ ├─ MenuItem (复制)
│ ├─ MenuItem (粘贴)
│ └─ Menu (查找)
│ └─ MenuItem (查找下一个)
└─ Menu (帮助)└─ MenuItem (关于)
下面是AWT中的菜单介绍:
在Java中,AWT(Abstract Window Toolkit)提供了创建图形用户界面(GUI)的基本工具。AWT中的菜单、弹出菜单和菜单栏是构建用户界面的重要组件。以下是对这些组件的详细介绍。
菜单栏(MenuBar)
菜单栏是窗口顶部的水平条,通常包含多个菜单。在AWT中,MenuBar
类用于创建菜单栏。菜单栏可以添加到Frame
或Dialog
中。
import java.awt.*;public class MenuBarExample {public static void main(String[] args) {JFrame frame = new JFrame("MenuBar Example");MenuBar menuBar = new MenuBar();Menu fileMenu = new Menu("File");Menu editMenu = new Menu("Edit");menuBar.add(fileMenu);menuBar.add(editMenu);frame.setMenuBar(menuBar);frame.setSize(300, 200);frame.setVisible(true);}
}
菜单(Menu)
菜单是菜单栏中的一个下拉列表,包含多个菜单项。Menu
类用于创建菜单。菜单可以包含其他菜单(子菜单)或菜单项(MenuItem
)。
import java.awt.*;public class MenuExample {public static void main(String[] args) {JFrame frame = new JFrame("MenuBar Example");MenuBar menuBar = new MenuBar();Menu fileMenu = new Menu("File");Menu editMenu = new Menu("Edit");menuBar.add(fileMenu);menuBar.add(editMenu);frame.setMenuBar(menuBar);frame.setSize(300, 200);frame.setVisible(true);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}
}
弹出菜单(PopupMenu)
弹出菜单是用户右键点击时显示的菜单。PopupMenu
类用于创建弹出菜单。弹出菜单可以添加到任何组件中,通常与鼠标事件结合使用。
import java.awt.*;
import java.awt.event.*;public class PopupMenuExample {public static void main(String[] args) {JFrame frame = new JFrame("PopupMenu Example");PopupMenu popupMenu = new PopupMenu();MenuItem cutItem = new MenuItem("Cut");MenuItem copyItem = new MenuItem("Copy");MenuItem pasteItem = new MenuItem("Paste");popupMenu.add(cutItem);popupMenu.add(copyItem);popupMenu.add(pasteItem);frame.add(popupMenu);frame.addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent e) {if (e.getButton() == MouseEvent.BUTTON3) {popupMenu.show(frame, e.getX(), e.getY());}}});frame.setSize(300, 200);frame.setVisible(true);}
}
菜单项(MenuItem)
菜单项是菜单中的单个选项,用户可以选择执行特定操作。MenuItem
类用于创建菜单项。菜单项可以添加到菜单或弹出菜单中。
import java.awt.*;
import java.awt.event.*;public class MenuItemExample {public static void main(String[] args) {Frame frame = new Frame("MenuItem Example");MenuBar menuBar = new MenuBar();Menu fileMenu = new Menu("File");MenuItem openItem = new MenuItem("Open");MenuItem saveItem = new MenuItem("Save");openItem.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {System.out.println("Open item clicked");}});saveItem.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {System.out.println("Save item clicked");}});fileMenu.add(openItem);fileMenu.add(saveItem);menuBar.add(fileMenu);frame.setMenuBar(menuBar);frame.setSize(300, 200);frame.setVisible(true);}
}
通过以上示例,可以了解如何在Java中使用AWT创建菜单栏、菜单、弹出菜单和菜单项。这些组件是构建用户界面的基础,能够帮助用户与应用程序进行交互。
弹出对话框:
弹出窗口:
JDialog:
继承自java.awt.Dialog类,他是从一个窗体弹出来的另一个窗体,他们JFrame类似,需要调用getContentPane将窗体转换为容器,然后在容器中设置窗体的内容。
JDialog:可以当作JFrame使用,但是必须从属于JFrame
构造函数:
- JDialog();
- JDialog(Frame f); //指定父窗口
- JDialog(Frame f,String title); //指定父窗口+标题
- JDialog关闭窗口的时候不能用DISPOSE_ON_CLOS,所以关闭大窗口会连着小的一起关闭,因为JDialog从属于JFrame.
下面演示:
package pdsu__zjh;
import javax.swing.*;
import javax.swing.JFrame;
public class Textt {public static void main(String []args) {JFrame jf=new JFrame();jf.setBounds(400,250,600,550);//设置位置,长,宽;jf.setVisible(true);//设置是否显示jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭方式JDialog jDialog=new JDialog();jDialog.setBounds(400,250,400,250);jDialog.setVisible(true);jDialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);}
}
效果演示:
弹出对话框
使用JOptionPane创建弹出对话框
Java中可以通过JOptionPane
类来创建各种类型的弹出对话框。JOptionPane
提供了多种静态方法来显示消息对话框、确认对话框、输入对话框等。
import javax.swing.JOptionPane;public class DialogExample {public static void main(String[] args) {// 显示消息对话框JOptionPane.showMessageDialog(null, "这是一个消息对话框", "消息", JOptionPane.INFORMATION_MESSAGE);// 显示确认对话框int response = JOptionPane.showConfirmDialog(null, "你确定要继续吗?", "确认", JOptionPane.YES_NO_OPTION);if (response == JOptionPane.YES_OPTION) {System.out.println("用户选择了是");} else {System.out.println("用户选择了否");}// 显示输入对话框String input = JOptionPane.showInputDialog(null, "请输入你的名字:", "输入", JOptionPane.QUESTION_MESSAGE);if (input != null) {System.out.println("你输入的名字是:" + input);}}
}
自定义对话框
如果需要更复杂的对话框,可以继承JDialog
类来创建自定义对话框。这种方式允许完全控制对话框的布局和行为。
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class CustomDialog extends JDialog {public CustomDialog(JFrame parent) {super(parent, "自定义对话框", true);setLayout(new FlowLayout());add(new JLabel("这是一个自定义对话框"));JButton closeButton = new JButton("关闭");closeButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {dispose();}});add(closeButton);pack();setLocationRelativeTo(parent);}public static void main(String[] args) {JFrame frame = new JFrame("主窗口");frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);CustomDialog dialog = new CustomDialog(frame);dialog.setVisible(true);}
}
使用JFileChooser选择文件
JFileChooser
类可以用于创建文件选择对话框,允许用户选择文件或目录。
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileNameExtensionFilter;public class FileChooserExample {public static void main(String[] args) {JFileChooser fileChooser = new JFileChooser();FileNameExtensionFilter filter = new FileNameExtensionFilter("文本文件", "txt");fileChooser.setFileFilter(filter);int returnValue = fileChooser.showOpenDialog(null);if (returnValue == JFileChooser.APPROVE_OPTION) {System.out.println("选择的文件是:" + fileChooser.getSelectedFile().getAbsolutePath());}}
}
使用JColorChooser选择颜色
JColorChooser
类可以用于创建颜色选择对话框,允许用户选择颜色。
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import java.awt.Color;public class ColorChooserExample {public static void main(String[] args) {Color selectedColor = JColorChooser.showDialog(null, "选择颜色", Color.WHITE);if (selectedColor != null) {System.out.println("选择的颜色是:" + selectedColor);}}
}
通过以上方法,可以在Java应用程序中轻松创建各种类型的弹出对话框,满足不同的用户交互需求。
窗口修饰和自定义形状
一、窗口修饰(去除标题栏、边框)
步骤:
frame.setUndecorated(true)
移除默认修饰- 手动添加标题栏 / 按钮
- 实现窗口拖动逻辑
示例代码:
java
JFrame frame = new JFrame();
frame.setUndecorated(true); // 先移除默认修饰// 添加自定义标题栏和关闭按钮
JPanel titleBar = new JPanel();
titleBar.add(new JLabel("自定义标题"));
titleBar.add(new JButton("X"));// 实现拖动功能(略,见之前示例)
二、自定义窗口形状
步骤:
setUndecorated(true)
setShape(shape)
设置形状- 确保内容绘制与形状一致
示例代码(圆形窗口):
java
JFrame frame = new JFrame();
frame.setUndecorated(true); // 必须先移除默认修饰// 创建圆形面板
JPanel panel = new JPanel() {@Overrideprotected void paintComponent(Graphics g) {g.fillOval(0, 0, getWidth(), getHeight());}
};frame.setContentPane(panel);
frame.pack();// 设置窗口形状为圆形(在pack之后)
frame.setShape(new Ellipse2D.Double(0, 0, frame.getWidth(), frame.getHeight()));
三、透明窗口
步骤:
setUndecorated(true)
setOpacity(0.5f)
设置透明度(0.0-1.0)- 内容面板设为透明
示例代码:
java
frame.setUndecorated(true);
frame.setOpacity(0.8f); // 80%透明度JPanel panel = new JPanel();
panel.setBackground(new Color(255, 255, 255, 100)); // 半透明白色
frame.setContentPane(panel);
四、关键注意事项
- 顺序:必须先
setUndecorated(true)
,再设置形状 / 透明度 - 系统检查:使用前检查系统支持:
java
boolean supportsShape = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().isWindowTranslucencySupported(WindowTranslucency.PERPIXEL_TRANSPARENT);
- 性能:复杂形状 / 透明度可能影响性能
- 拖动逻辑:移除修饰后需手动实现窗口拖动(见之前示例中的
WindowDragListener
)
多面板和分割面板:
在 Java 的 Swing GUI 编程里,多面板和分割面板是组织和管理界面的重要组件。下面为你详细介绍它们的概念、用法和区别。
多面板(Multi-Panel)
多面板并非 Java 的标准术语,不过在实际应用中,它指的是将多个面板组合到一个容器里的布局方式。这种方式能够让界面结构清晰,便于管理。
常见实现方式
- 嵌套 JPanel:可以把多个 JPanel 添加到一个父容器中,每个子面板负责管理特定区域的组件。
- 卡片布局(CardLayout):这是一种特殊的布局管理器,它能让多个组件共享同一显示空间,组件之间可以像卡片一样切换。
- 选项卡面板(JTabbedPane):它会创建带有选项卡的界面,每个选项卡下面都可以放置不同的面板。
示例代码
下面是一个嵌套 JPanel 的例子:
import javax.swing.*;
import java.awt.*;public class MultiPanelExample {public static void main(String[] args) {JFrame frame = new JFrame("多面板示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(400, 300);// 创建主面板,使用边界布局JPanel mainPanel = new JPanel(new BorderLayout());// 顶部面板 - 包含按钮JPanel topPanel = new JPanel();topPanel.add(new JButton("按钮1"));topPanel.add(new JButton("按钮2"));// 中部面板 - 包含文本区域JPanel centerPanel = new JPanel();centerPanel.add(new JTextArea(10, 30));// 将子面板添加到主面板mainPanel.add(topPanel, BorderLayout.NORTH);mainPanel.add(centerPanel, BorderLayout.CENTER);// 将主面板添加到窗口frame.setContentPane(mainPanel);frame.setVisible(true);}
}
分割面板(JSplitPane)
JSplitPane 是 Swing 提供的标准组件,其主要功能是创建一个可调整的分割线,把容器分为两个区域。用户能够通过拖动分割线来改变两个区域的大小。
关键特性
- 方向支持:支持水平分割(HORIZONTAL_SPLIT)和垂直分割(VERTICAL_SPLIT)。
- 连续重绘:在拖动分割线时,可以选择实时重绘界面或者在拖动结束后再重绘。
- 固定比例:能够设置分割线的位置,既可以使用像素值,也可以使用相对于容器大小的比例。
示例代码
下面是一个使用 JSplitPane 的例子:
java
import javax.swing.*;
import java.awt.*;public class SplitPaneExample {public static void main(String[] args) {JFrame frame = new JFrame("分割面板示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);// 创建左侧面板JPanel leftPanel = new JPanel();leftPanel.add(new JList<>(new String[]{"项目1", "项目2", "项目3"}));// 创建右侧面板JPanel rightPanel = new JPanel();rightPanel.add(new JTextArea(20, 30));// 创建水平分割面板JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,leftPanel,rightPanel);// 设置分割线位置(相对于容器宽度的比例)splitPane.setDividerLocation(0.3);// 设置连续重绘,使拖动更流畅splitPane.setContinuousLayout(true);// 将分割面板添加到窗口frame.setContentPane(splitPane);frame.setVisible(true);}
}
多面板与分割面板的主要区别
特性 | 多面板(嵌套 JPanel) | 分割面板(JSplitPane) |
---|---|---|
布局方式 | 需要手动管理每个面板的大小和位置 | 自动管理两个区域,可通过拖动分割线调整 |
用户交互 | 面板大小固定,用户无法动态调整 | 用户可以实时调整两个区域的大小 |
应用场景 | 适合界面布局固定的情况,例如表单、工具栏 | 适合需要动态调整空间分配的场景,如图文混排、资源管理器 |
实现复杂度 | 需要处理多个面板的布局,相对复杂 | 只需设置一次,自动处理大部分布局逻辑 |
SWing和Awt的区别
1. 历史与定位
-
AWT(1995 年):
- Java 最早的 GUI 库,属于 Java 基础类库(JRE)的一部分。
- 称为 “重量级” 组件,依赖底层操作系统的原生窗口系统(如 Windows 的 Win32 API)。
-
Swing(1997 年):
- 作为 AWT 的扩展,属于 Java Foundation Classes (JFC)。
- 称为 “轻量级” 组件,完全由 Java 代码实现,不依赖原生窗口系统。
2. 核心架构差异
特性 | AWT(重量级) | Swing(轻量级) |
---|---|---|
组件实现 | 依赖原生窗口系统(如 Windows/Linux) | 纯 Java 实现,跨平台一致性好 |
渲染方式 | 由操作系统负责绘制 | 由 Java 虚拟机(JVM)负责绘制 |
内存占用 | 高(每个组件对应一个原生窗口句柄) | 低(共享一个窗口句柄) |
性能 | 受限于操作系统绘制效率 | 通常更高,但复杂 UI 可能有性能开销 |
外观一致性 | 与操作系统风格一致 | 可定制外观(如 Nimbus、Metal) |
3. 组件对比
组件类型 | AWT 类 | Swing 等效类 |
---|---|---|
窗口 | Frame , Dialog | JFrame , JDialog |
面板 | Panel | JPanel |
按钮 | Button | JButton |
标签 | Label | JLabel |
文本框 | TextField | JTextField |
滚动面板 | ScrollPane | JScrollPane |
菜单 | MenuBar , Menu , MenuItem | JMenuBar , JMenu , JMenuItem |
对话框 | FileDialog | JFileChooser |
4. 功能特性对比
特性 | AWT | Swing |
---|---|---|
透明效果 | 不支持 | 支持(如setOpaque(false) ) |
自定义边框 | 无内置支持 | 丰富的边框选项(BorderFactory ) |
双缓冲 | 需手动实现 | 默认启用,减少闪烁 |
事件处理 | 基于接口(如ActionListener ) | 支持匿名内部类和 Lambda 表达式 |
数据模型 | 无统一数据模型 | 支持 MVC 模式(如TableModel ) |
组件丰富度 | 基础组件 | 提供更多高级组件(如JTable , JTree ) |
主题支持 | 依赖操作系统 | 支持多种主题(如 Nimbus、Windows 风格) |
5. 线程安全性
-
AWT:
- 非线程安全,但早期 Java 版本允许在任意线程更新 UI(可能导致绘制异常)。
-
Swing:
- 严格要求在事件调度线程(Event Dispatch Thread, EDT)中操作 UI,否则可能出现竞态条件。
- 使用
SwingUtilities.invokeLater()
或SwingUtilities.invokeAndWait()
确保线程安全。
java
// 示例:在EDT中创建Swing UI
SwingUtilities.invokeLater(() -> {JFrame frame = new JFrame("线程安全示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.add(new JLabel("Hello, Swing!"));frame.pack();frame.setVisible(true);
});
6. 应用场景
-
选择 AWT:
- 开发简单工具或小程序。
- 需要与操作系统原生组件深度集成。
- 维护旧 Java 项目(如 JDK 1.1 时代的代码)。
-
选择 Swing:
- 开发跨平台的桌面应用。
- 需要丰富的 UI 组件(如表格、树状结构)。
- 需要自定义外观或动画效果。
- 开发复杂的企业级应用(如 IDE、数据可视化工具)。
7. 现代替代方案
虽然 Swing 和 AWT 仍被广泛使用,但 Java 的 GUI 生态已发展出更现代的框架:
-
JavaFX(自 Java 8 引入):
- 官方推荐的下一代 GUI 框架,支持 FXML、CSS 样式、3D 图形和多媒体。
- 逐渐取代 Swing 成为 Java 桌面应用的首选。
-
第三方框架:
- Apache Pivot:基于 Batik 的轻量级框架,支持多种 UI 风格。
- MigLayout:增强的布局管理器,简化复杂布局的实现。
- JGoodies Forms:提供更灵活的表单布局解决方案。
总结
维度 | AWT | Swing |
---|---|---|
年代 | 早期(JDK 1.0) | 后期(JDK 1.2+) |
技术路线 | 重量级,依赖原生系统 | 轻量级,纯 Java 实现 |
外观控制 | 受限(与系统一致) | 高度可定制 |
性能 | 低(原生调用开销) | 高(Java 优化) |
学习曲线 | 简单(基础 API) | 较复杂(更多概念) |
推荐场景 | 简单工具、原生集成 | 复杂 UI、跨平台应用 |