当前位置: 首页 > news >正文

Java Swing 编程全面解析:从 AWT 到 Swing 的进化之路

目录

前言

一、AWT 简介

1. 什么是 AWT?

2. AWT 的基本组件

3. AWT 编程示例

二、Swing 的诞生与进化

1. Swing 的特点

2. Swing 和 AWT 的主要区别

3. Swing 的基本组件

三、Swing 编程的基础示例

四、Swing 的高级功能

1. 布局管理器

2. 事件监听

3. 自定义外观

五、综合案例:计算器

六、总结


前言

Java 提供了强大的图形用户界面(GUI)工具,用于创建跨平台的桌面应用程序。从早期的 AWT(Abstract Window Toolkit)到更先进的 Swing,Java GUI 编程逐步演进,解决了跨平台一致性、组件丰富性以及性能等问题。本篇博客将详细讲解从 AWT 到 Swing 的过渡。

一、AWT 简介

1. 什么是 AWT?

AWT(Abstract Window Toolkit)是 Java 1.0 提供的一个 GUI 工具包,它使用系统的本地 GUI 组件(如 Windows 的按钮、macOS 的窗口等)来构建界面。由于 AWT 依赖于本地操作系统的组件,因此具有如下特点:

  • 优点
    • 跨平台支持:能在不同操作系统中运行。
    • 轻量级:组件直接调用本地系统资源。
  • 缺点
    • 限制较多:组件功能单一,难以满足复杂 GUI 的需求。
    • 外观不一致:不同操作系统上的显示效果可能不同。
    • 不灵活:自定义组件的能力有限。
2. AWT 的基本组件

AWT 提供了一些基本组件,例如:

  • Container:顶级容器(如 FramePanel)用于容纳其他组件。
  • Component:基本组件(如 ButtonLabelTextField)。
  • Layout Manager:布局管理器,用于控制组件的排列方式。
3. AWT 编程示例
import java.awt.*;public class AWTExample {public static void main(String[] args) {// 创建 Frame 窗口Frame frame = new Frame("AWT Example");frame.setSize(300, 200);frame.setLayout(new FlowLayout());// 添加组件Label label = new Label("AWT Label");Button button = new Button("Click Me");frame.add(label);frame.add(button);// 显示窗口frame.setVisible(true);}
}

二、Swing 的诞生与进化

为了弥补 AWT 的不足,Java 在 JDK 1.2 中引入了 Swing。Swing 是基于 AWT 的扩展,它不仅解决了 AWT 的缺陷,还大大增强了 GUI 开发的能力。

1. Swing 的特点
  • 轻量级组件:Swing 的组件不依赖于本地操作系统,而是用纯 Java 实现。
  • 丰富的组件库:提供了大量高级组件(如 JTableJTreeJTabbedPane 等),能够满足复杂的用户界面需求。
  • 可定制性:Swing 支持基于 Pluggable Look-and-Feel 的外观定制,可以实现跨平台一致的用户界面。
  • 事件驱动模型:通过事件监听器机制处理用户交互。
2. Swing 和 AWT 的主要区别
特性AWTSwing
组件实现依赖本地操作系统的组件纯 Java 实现(轻量级组件)
组件外观外观由操作系统决定支持跨平台外观,可自定义
线程模型非线程安全大多数操作需要在事件调度线程中完成
组件种类基本组件,如 ButtonLabel丰富组件,如 JButtonJLabel
功能扩展性功能有限,扩展困难支持高级功能,易于扩展
3. Swing 的基本组件

Swing 的组件以 J 开头,例如:

  • 顶级容器JFrameJDialogJApplet
  • 基本组件JButtonJLabelJTextFieldJCheckBox
  • 高级组件JTableJTreeJTabbedPaneJScrollPane

三、Swing 编程的基础示例

以下是一个使用 Swing 创建简单窗口的示例:

import javax.swing.*;public class SwingExample {public static void main(String[] args) {// 创建 JFrame 窗口JFrame frame = new JFrame("Swing Example");frame.setSize(300, 200);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 添加组件JLabel label = new JLabel("Hello, Swing!");JButton button = new JButton("Click Me");frame.setLayout(new java.awt.FlowLayout());frame.add(label);frame.add(button);// 显示窗口frame.setVisible(true);}
}

四、Swing 的高级功能

1. 布局管理器

Swing 提供了多种布局管理器,用于控制组件在容器中的排列方式:

  • FlowLayout:按添加顺序从左到右排列。
  • BorderLayout:分为东、南、西、北、中五个区域。
  • GridLayout:以网格形式排列组件。
  • BoxLayout:允许组件在垂直或水平方向排列。
frame.setLayout(new BorderLayout());
frame.add(new JButton("North"), BorderLayout.NORTH);
frame.add(new JButton("South"), BorderLayout.SOUTH);
frame.add(new JButton("East"), BorderLayout.EAST);
frame.add(new JButton("West"), BorderLayout.WEST);
frame.add(new JButton("Center"), BorderLayout.CENTER);

2. 事件监听

Swing 使用事件监听器来处理用户操作,例如按钮点击、鼠标移动等。

示例:按钮点击事件

button.addActionListener(e -> System.out.println("Button clicked!"));
3. 自定义外观

Swing 支持修改外观(Look-and-Feel),可以通过以下代码设置跨平台外

try {UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {e.printStackTrace();
}

五、综合案例:计算器

以下是一个简单的 Swing 计算器示例:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Stack;public class Calculator {public static void main(String[] args) {JFrame frame = new JFrame("Calculator");frame.setSize(400, 500);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setLayout(new BorderLayout());// 显示区域JTextField display = new JTextField();display.setFont(new Font("Arial", Font.BOLD, 24));frame.add(display, BorderLayout.NORTH);// 按钮区域JPanel buttonPanel = new JPanel();buttonPanel.setLayout(new GridLayout(4, 4));String[] buttons = {"7", "8", "9", "/","4", "5", "6", "*","1", "2", "3", "-","C", "0", "=", "+"};for (String text : buttons) {JButton button = new JButton(text);button.setFont(new Font("Arial", Font.BOLD, 20));buttonPanel.add(button);// 按钮事件监听button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String command = e.getActionCommand();if (command.equals("=")) {// 计算结果try {display.setText(evaluateExpression(display.getText()));} catch (Exception ex) {display.setText("Error");}} else if (command.equals("C")) {// 清空输入框display.setText("");} else {// 更新显示display.setText(display.getText() + command);}}});}frame.add(buttonPanel, BorderLayout.CENTER);// 显示窗口frame.setVisible(true);}// 方法:计算输入的数学表达式private static String evaluateExpression(String expression) {// 使用栈进行数学表达式的求值Stack<Double> values = new Stack<>();Stack<Character> operators = new Stack<>();// 处理输入的表达式for (int i = 0; i < expression.length(); i++) {char ch = expression.charAt(i);// 跳过空格if (ch == ' ') continue;// 如果是数字,处理多位数if (Character.isDigit(ch)) {StringBuilder num = new StringBuilder();while (i < expression.length() && (Character.isDigit(expression.charAt(i)) || expression.charAt(i) == '.')) {num.append(expression.charAt(i));i++;}i--; // 回退一个字符values.push(Double.parseDouble(num.toString()));} // 如果是左括号,压入栈else if (ch == '(') {operators.push(ch);} // 如果是右括号,解决括号中的内容else if (ch == ')') {while (operators.peek() != '(') {values.push(applyOperation(operators.pop(), values.pop(), values.pop()));}operators.pop(); // 弹出 '('} // 如果是运算符,处理优先级并执行运算else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {while (!operators.isEmpty() && hasPrecedence(ch, operators.peek())) {values.push(applyOperation(operators.pop(), values.pop(), values.pop()));}operators.push(ch);}}// 处理剩下的运算符while (!operators.isEmpty()) {values.push(applyOperation(operators.pop(), values.pop(), values.pop()));}// 最终结果return String.valueOf(values.pop());}// 方法:检查当前运算符的优先级private static boolean hasPrecedence(char op1, char op2) {if (op2 == '(' || op2 == ')') return false;return (op1 != '*' && op1 != '/') || (op2 != '+' && op2 != '-');}// 方法:执行基本的算术运算private static double applyOperation(char op, double b, double a) {switch (op) {case '+': return a + b;case '-': return a - b;case '*': return a * b;case '/': if (b == 0) throw new UnsupportedOperationException("Cannot divide by zero");return a / b;}return 0;}
}

后续会模拟一个跟手机差不多的计算器。

六、总结

Java Swing 的出现极大地提升了 Java GUI 编程的能力,它克服了 AWT 的局限,提供了更强大的组件库和更高的灵活性。在实际开发中,Swing 仍然是构建桌面应用程序的常用工具,尽管随着 JavaFX 的发展,Swing 的使用场景有所减少,但依然是学习 Java GUI 编程的良好起点。

http://www.lryc.cn/news/525139.html

相关文章:

  • mysql数据库启动出现Plugin ‘FEEDBACK‘ is disabled.问题解决记录
  • 2025年大模型对智能硬件发展的助力与创新创意
  • Tensor 基本操作1 unsqueeze, squeeze, softmax | PyTorch 深度学习实战
  • Python - itertools- pairwise函数的详解
  • Docker可视化管理工具Portainer
  • WPF实战案例 | C# WPF实现大学选课系统
  • leetcode 面试经典 150 题:有效的括号
  • python学opencv|读取图像(三十九 )阈值处理Otsu方法
  • GBase8c aes_encrypt和aes_decrypt函数
  • 【2024年华为OD机试】(B卷,100分)- 数据分类 (Java JS PythonC/C++)
  • 机器学习 vs 深度学习
  • flutter_学习记录_00_环境搭建
  • SpringBoot如何自定义Starter ?
  • 前沿技术对比:大模型技术为什么发展远快于区块链技术,中英对照解释
  • WordPress果果对象存储插件
  • elk 安装
  • Python 预训练:打通视觉与大语言模型应用壁垒——Python预训练视觉和大语言模型
  • OpenCV相机标定与3D重建(63)校正图像的畸变函数undistort()的使用
  • 用 Java 发送 HTML 内容并带附件的电子邮件
  • 【Day24 LeetCode】贪心Ⅱ
  • vue3+elementPlus之后台管理系统(从0到1)(day3-管理员管理)
  • 上位机知识篇---ROS2命令行命令静态链接库动态链接库
  • 2025/1/21 学习Vue的第四天
  • 云计算、AI与国产化浪潮下DBA职业之路风云变幻,如何谋破局启新途?
  • Linux内核编程(二十一)USB驱动开发-键盘驱动
  • 模拟算法习题篇
  • 蓝桥杯真题 - 翻转 - 题解
  • IP属地与视频定位位置不一致:现象解析与影响探讨
  • 管道符、重定向与环境变量
  • 可扩展性设计架构模式——开闭原则