手機(jī)網(wǎng)站頁(yè)面怎么做網(wǎng)站鏈接
目錄
前言
一、AWT 簡(jiǎn)介
1. 什么是 AWT?
2. AWT 的基本組件
3. AWT 編程示例
二、Swing 的誕生與進(jìn)化
1. Swing 的特點(diǎn)
2. Swing 和 AWT 的主要區(qū)別
3. Swing 的基本組件
三、Swing 編程的基礎(chǔ)示例
四、Swing 的高級(jí)功能
1. 布局管理器
2. 事件監(jiān)聽
3. 自定義外觀
五、綜合案例:計(jì)算器
六、總結(jié)
前言
Java 提供了強(qiáng)大的圖形用戶界面(GUI)工具,用于創(chuàng)建跨平臺(tái)的桌面應(yīng)用程序。從早期的 AWT(Abstract Window Toolkit)到更先進(jìn)的 Swing,Java GUI 編程逐步演進(jìn),解決了跨平臺(tái)一致性、組件豐富性以及性能等問(wèn)題。本篇博客將詳細(xì)講解從 AWT 到 Swing 的過(guò)渡。
一、AWT 簡(jiǎn)介
1. 什么是 AWT?
AWT(Abstract Window Toolkit)是 Java 1.0 提供的一個(gè) GUI 工具包,它使用系統(tǒng)的本地 GUI 組件(如 Windows 的按鈕、macOS 的窗口等)來(lái)構(gòu)建界面。由于 AWT 依賴于本地操作系統(tǒng)的組件,因此具有如下特點(diǎn):
- 優(yōu)點(diǎn):
- 跨平臺(tái)支持:能在不同操作系統(tǒng)中運(yùn)行。
- 輕量級(jí):組件直接調(diào)用本地系統(tǒng)資源。
- 缺點(diǎn):
- 限制較多:組件功能單一,難以滿足復(fù)雜 GUI 的需求。
- 外觀不一致:不同操作系統(tǒng)上的顯示效果可能不同。
- 不靈活:自定義組件的能力有限。
2. AWT 的基本組件
AWT 提供了一些基本組件,例如:
- Container:頂級(jí)容器(如
Frame
、Panel
)用于容納其他組件。 - Component:基本組件(如
Button
、Label
、TextField
)。 - Layout Manager:布局管理器,用于控制組件的排列方式。
3. AWT 編程示例
import java.awt.*;public class AWTExample {public static void main(String[] args) {// 創(chuàng)建 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 的誕生與進(jìn)化
為了彌補(bǔ) AWT 的不足,Java 在 JDK 1.2 中引入了 Swing。Swing 是基于 AWT 的擴(kuò)展,它不僅解決了 AWT 的缺陷,還大大增強(qiáng)了 GUI 開發(fā)的能力。
1. Swing 的特點(diǎn)
- 輕量級(jí)組件:Swing 的組件不依賴于本地操作系統(tǒng),而是用純 Java 實(shí)現(xiàn)。
- 豐富的組件庫(kù):提供了大量高級(jí)組件(如
JTable
、JTree
、JTabbedPane
等),能夠滿足復(fù)雜的用戶界面需求。 - 可定制性:Swing 支持基于
Pluggable Look-and-Feel
的外觀定制,可以實(shí)現(xiàn)跨平臺(tái)一致的用戶界面。 - 事件驅(qū)動(dòng)模型:通過(guò)事件監(jiān)聽器機(jī)制處理用戶交互。
2. Swing 和 AWT 的主要區(qū)別
特性 | AWT | Swing |
---|---|---|
組件實(shí)現(xiàn) | 依賴本地操作系統(tǒng)的組件 | 純 Java 實(shí)現(xiàn)(輕量級(jí)組件) |
組件外觀 | 外觀由操作系統(tǒng)決定 | 支持跨平臺(tái)外觀,可自定義 |
線程模型 | 非線程安全 | 大多數(shù)操作需要在事件調(diào)度線程中完成 |
組件種類 | 基本組件,如 Button 、Label | 豐富組件,如 JButton 、JLabel |
功能擴(kuò)展性 | 功能有限,擴(kuò)展困難 | 支持高級(jí)功能,易于擴(kuò)展 |
3. Swing 的基本組件
Swing 的組件以 J
開頭,例如:
- 頂級(jí)容器:
JFrame
、JDialog
、JApplet
。 - 基本組件:
JButton
、JLabel
、JTextField
、JCheckBox
。 - 高級(jí)組件:
JTable
、JTree
、JTabbedPane
、JScrollPane
。
三、Swing 編程的基礎(chǔ)示例
以下是一個(gè)使用 Swing 創(chuàng)建簡(jiǎn)單窗口的示例:
import javax.swing.*;public class SwingExample {public static void main(String[] args) {// 創(chuàng)建 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 的高級(jí)功能
1. 布局管理器
Swing 提供了多種布局管理器,用于控制組件在容器中的排列方式:
- FlowLayout:按添加順序從左到右排列。
- BorderLayout:分為東、南、西、北、中五個(gè)區(qū)域。
- GridLayout:以網(wǎng)格形式排列組件。
- 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. 事件監(jiān)聽
Swing 使用事件監(jiān)聽器來(lái)處理用戶操作,例如按鈕點(diǎn)擊、鼠標(biāo)移動(dòng)等。
示例:按鈕點(diǎn)擊事件
button.addActionListener(e -> System.out.println("Button clicked!"));
3. 自定義外觀
Swing 支持修改外觀(Look-and-Feel),可以通過(guò)以下代碼設(shè)置跨平臺(tái)外
try {UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {e.printStackTrace();
}
五、綜合案例:計(jì)算器
以下是一個(gè)簡(jiǎn)單的 Swing 計(jì)算器示例:
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());// 顯示區(qū)域JTextField display = new JTextField();display.setFont(new Font("Arial", Font.BOLD, 24));frame.add(display, BorderLayout.NORTH);// 按鈕區(qū)域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);// 按鈕事件監(jiān)聽button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String command = e.getActionCommand();if (command.equals("=")) {// 計(jì)算結(jié)果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);}// 方法:計(jì)算輸入的數(shù)學(xué)表達(dá)式private static String evaluateExpression(String expression) {// 使用棧進(jìn)行數(shù)學(xué)表達(dá)式的求值Stack<Double> values = new Stack<>();Stack<Character> operators = new Stack<>();// 處理輸入的表達(dá)式for (int i = 0; i < expression.length(); i++) {char ch = expression.charAt(i);// 跳過(guò)空格if (ch == ' ') continue;// 如果是數(shù)字,處理多位數(shù)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--; // 回退一個(gè)字符values.push(Double.parseDouble(num.toString()));} // 如果是左括號(hào),壓入棧else if (ch == '(') {operators.push(ch);} // 如果是右括號(hào),解決括號(hào)中的內(nèi)容else if (ch == ')') {while (operators.peek() != '(') {values.push(applyOperation(operators.pop(), values.pop(), values.pop()));}operators.pop(); // 彈出 '('} // 如果是運(yùn)算符,處理優(yōu)先級(jí)并執(zhí)行運(yùn)算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);}}// 處理剩下的運(yùn)算符while (!operators.isEmpty()) {values.push(applyOperation(operators.pop(), values.pop(), values.pop()));}// 最終結(jié)果return String.valueOf(values.pop());}// 方法:檢查當(dāng)前運(yùn)算符的優(yōu)先級(jí)private static boolean hasPrecedence(char op1, char op2) {if (op2 == '(' || op2 == ')') return false;return (op1 != '*' && op1 != '/') || (op2 != '+' && op2 != '-');}// 方法:執(zhí)行基本的算術(shù)運(yùn)算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;}
}
后續(xù)會(huì)模擬一個(gè)跟手機(jī)差不多的計(jì)算器。
六、總結(jié)
Java Swing 的出現(xiàn)極大地提升了 Java GUI 編程的能力,它克服了 AWT 的局限,提供了更強(qiáng)大的組件庫(kù)和更高的靈活性。在實(shí)際開發(fā)中,Swing 仍然是構(gòu)建桌面應(yīng)用程序的常用工具,盡管隨著 JavaFX 的發(fā)展,Swing 的使用場(chǎng)景有所減少,但依然是學(xué)習(xí) Java GUI 編程的良好起點(diǎn)。