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

打印 上一主题 下一主题

主题 1019|帖子 1019|积分 3057

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
目录
前言
一、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:顶级容器(如 Frame、Panel)用于容纳其他组件。
  • Component:基本组件(如 Button、Label、TextField)。
  • Layout Manager:布局管理器,用于控制组件的排列方式。
3. AWT 编程示例

  1. import java.awt.*;
  2. public class AWTExample {
  3.     public static void main(String[] args) {
  4.         // 创建 Frame 窗口
  5.         Frame frame = new Frame("AWT Example");
  6.         frame.setSize(300, 200);
  7.         frame.setLayout(new FlowLayout());
  8.         // 添加组件
  9.         Label label = new Label("AWT Label");
  10.         Button button = new Button("Click Me");
  11.         frame.add(label);
  12.         frame.add(button);
  13.         // 显示窗口
  14.         frame.setVisible(true);
  15.     }
  16. }
复制代码

二、Swing 的诞生与进化

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



  • 轻量级组件:Swing 的组件不依赖于本地操纵系统,而是用纯 Java 实现。
  • 丰富的组件库:提供了大量高级组件(如 JTable、JTree、JTabbedPane 等),能够满足复杂的用户界面需求。
  • 可定制性:Swing 支持基于 Pluggable Look-and-Feel 的表面定制,可以实现跨平台一致的用户界面。
  • 变乱驱动模型:通过变乱监听器机制处置惩罚用户交互。
2. Swing 和 AWT 的主要区别

特性AWTSwing组件实现依赖本地操纵系统的组件纯 Java 实现(轻量级组件)组件表面表面由操纵系统决定支持跨平台表面,可自定义线程模型非线程安全大多数操纵需要在变乱调度线程中完成组件种类基本组件,如 Button、Label丰富组件,如 JButton、JLabel功能扩展性功能有限,扩展困难支持高级功能,易于扩展 3. Swing 的基本组件

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


  • 顶级容器:JFrame、JDialog、JApplet。
  • 基本组件:JButton、JLabel、JTextField、JCheckBox。
  • 高级组件:JTable、JTree、JTabbedPane、JScrollPane。
三、Swing 编程的基础示例

以下是一个利用 Swing 创建简单窗口的示例:
  1. import javax.swing.*;
  2. public class SwingExample {
  3.     public static void main(String[] args) {
  4.         // 创建 JFrame 窗口
  5.         JFrame frame = new JFrame("Swing Example");
  6.         frame.setSize(300, 200);
  7.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  8.         // 添加组件
  9.         JLabel label = new JLabel("Hello, Swing!");
  10.         JButton button = new JButton("Click Me");
  11.         frame.setLayout(new java.awt.FlowLayout());
  12.         frame.add(label);
  13.         frame.add(button);
  14.         // 显示窗口
  15.         frame.setVisible(true);
  16.     }
  17. }
复制代码
四、Swing 的高级功能

1. 布局管理器

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


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

2. 变乱监听

Swing 利用变乱监听器来处置惩罚用户操纵,例如按钮点击、鼠标移动等。
示例:按钮点击变乱
  1. button.addActionListener(e -> System.out.println("Button clicked!"));
复制代码
3. 自定义表面

Swing 支持修改表面(Look-and-Feel),可以通过以下代码设置跨平台外
  1. try {
  2.     UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
  3. } catch (Exception e) {
  4.     e.printStackTrace();
  5. }
复制代码

五、综合案例:计算器

以下是一个简单的 Swing 计算器示例:
  1. import javax.swing.*;
  2. import java.awt.*;
  3. import java.awt.event.ActionEvent;
  4. import java.awt.event.ActionListener;
  5. import java.util.Stack;
  6. public class Calculator {
  7.     public static void main(String[] args) {
  8.         JFrame frame = new JFrame("Calculator");
  9.         frame.setSize(400, 500);
  10.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  11.         frame.setLayout(new BorderLayout());
  12.         // 显示区域
  13.         JTextField display = new JTextField();
  14.         display.setFont(new Font("Arial", Font.BOLD, 24));
  15.         frame.add(display, BorderLayout.NORTH);
  16.         // 按钮区域
  17.         JPanel buttonPanel = new JPanel();
  18.         buttonPanel.setLayout(new GridLayout(4, 4));
  19.         String[] buttons = {"7", "8", "9", "/",
  20.                             "4", "5", "6", "*",
  21.                             "1", "2", "3", "-",
  22.                             "C", "0", "=", "+"};
  23.         for (String text : buttons) {
  24.             JButton button = new JButton(text);
  25.             button.setFont(new Font("Arial", Font.BOLD, 20));
  26.             buttonPanel.add(button);
  27.             // 按钮事件监听
  28.             button.addActionListener(new ActionListener() {
  29.                 @Override
  30.                 public void actionPerformed(ActionEvent e) {
  31.                     String command = e.getActionCommand();
  32.                     if (command.equals("=")) {
  33.                         // 计算结果
  34.                         try {
  35.                             display.setText(evaluateExpression(display.getText()));
  36.                         } catch (Exception ex) {
  37.                             display.setText("Error");
  38.                         }
  39.                     } else if (command.equals("C")) {
  40.                         // 清空输入框
  41.                         display.setText("");
  42.                     } else {
  43.                         // 更新显示
  44.                         display.setText(display.getText() + command);
  45.                     }
  46.                 }
  47.             });
  48.         }
  49.         frame.add(buttonPanel, BorderLayout.CENTER);
  50.         // 显示窗口
  51.         frame.setVisible(true);
  52.     }
  53.     // 方法:计算输入的数学表达式
  54.     private static String evaluateExpression(String expression) {
  55.         // 使用栈进行数学表达式的求值
  56.         Stack<Double> values = new Stack<>();
  57.         Stack<Character> operators = new Stack<>();
  58.         
  59.         // 处理输入的表达式
  60.         for (int i = 0; i < expression.length(); i++) {
  61.             char ch = expression.charAt(i);
  62.             
  63.             // 跳过空格
  64.             if (ch == ' ') continue;
  65.             
  66.             // 如果是数字,处理多位数
  67.             if (Character.isDigit(ch)) {
  68.                 StringBuilder num = new StringBuilder();
  69.                 while (i < expression.length() && (Character.isDigit(expression.charAt(i)) || expression.charAt(i) == '.')) {
  70.                     num.append(expression.charAt(i));
  71.                     i++;
  72.                 }
  73.                 i--; // 回退一个字符
  74.                 values.push(Double.parseDouble(num.toString()));
  75.             }
  76.             // 如果是左括号,压入栈
  77.             else if (ch == '(') {
  78.                 operators.push(ch);
  79.             }
  80.             // 如果是右括号,解决括号中的内容
  81.             else if (ch == ')') {
  82.                 while (operators.peek() != '(') {
  83.                     values.push(applyOperation(operators.pop(), values.pop(), values.pop()));
  84.                 }
  85.                 operators.pop(); // 弹出 '('
  86.             }
  87.             // 如果是运算符,处理优先级并执行运算
  88.             else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
  89.                 while (!operators.isEmpty() && hasPrecedence(ch, operators.peek())) {
  90.                     values.push(applyOperation(operators.pop(), values.pop(), values.pop()));
  91.                 }
  92.                 operators.push(ch);
  93.             }
  94.         }
  95.         // 处理剩下的运算符
  96.         while (!operators.isEmpty()) {
  97.             values.push(applyOperation(operators.pop(), values.pop(), values.pop()));
  98.         }
  99.         // 最终结果
  100.         return String.valueOf(values.pop());
  101.     }
  102.     // 方法:检查当前运算符的优先级
  103.     private static boolean hasPrecedence(char op1, char op2) {
  104.         if (op2 == '(' || op2 == ')') return false;
  105.         return (op1 != '*' && op1 != '/') || (op2 != '+' && op2 != '-');
  106.     }
  107.     // 方法:执行基本的算术运算
  108.     private static double applyOperation(char op, double b, double a) {
  109.         switch (op) {
  110.             case '+': return a + b;
  111.             case '-': return a - b;
  112.             case '*': return a * b;
  113.             case '/':
  114.                 if (b == 0) throw new UnsupportedOperationException("Cannot divide by zero");
  115.                 return a / b;
  116.         }
  117.         return 0;
  118.     }
  119. }
复制代码
后续会模仿一个跟手机差不多的计算器。
六、总结

Java Swing 的出现极大地提拔了 Java GUI 编程的能力,它降服了 AWT 的范围,提供了更强大的组件库和更高的灵活性。在实际开发中,Swing 仍旧是构建桌面应用程序的常用工具,只管随着 JavaFX 的发展,Swing 的利用场景有所淘汰,但依然是学习 Java GUI 编程的良好出发点。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

吴旭华

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表