完整知识点手册)
第一部分Java GUI 概述1.1 Java GUI 技术发展史技术年代特点现状AWTJDK 1.0依赖本地操作系统组件重量级基本废弃但部分概念保留SwingJDK 1.2纯 Java 实现轻量级可移植主流仍在大量使用JavaFXJDK 8 引入现代化 GUI支持 CSS、FXMLJDK 11 起从 JDK 移除独立维护1.2 本文范围主要讲解Swing最常用面试和企业项目主流补充AWT的基础概念事件模型简要介绍JavaFX第二部分AWT 基础2.1 AWT 核心类textjava.awt 包 ├── Component所有组件的父类 │ ├── Button │ ├── Label │ ├── TextComponent │ │ ├── TextField │ │ └── TextArea │ ├── Checkbox │ ├── Choice │ └── Container容器 │ ├── Panel │ ├── Frame窗口 │ └── Dialog ├── LayoutManager布局管理器 │ ├── FlowLayout │ ├── BorderLayout │ ├── GridLayout │ └── CardLayout └── Event事件 ├── ActionEvent ├── MouseEvent └── KeyEvent2.2 AWT 示例javaimport java.awt.*; import java.awt.event.*; public class AWTExample { public static void main(String[] args) { // 创建窗口 Frame frame new Frame(AWT 示例); frame.setSize(300, 200); frame.setLayout(new FlowLayout()); // 创建按钮 Button btn new Button(点击我); // 添加事件监听 btn.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { System.out.println(按钮被点击了); } }); frame.add(btn); frame.setVisible(true); // 窗口关闭事件AWT 需要手动处理 frame.addWindowListener(new WindowAdapter() { Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } }第三部分Swing 核心知识点3.1 Swing 架构textjavax.swing 包 ├── JComponent所有 Swing 组件的父类继承自 AWT 的 Container │ ├── JButton按钮 │ ├── JLabel标签 │ ├── JTextField单行文本 │ ├── JTextArea多行文本 │ ├── JCheckBox复选框 │ ├── JRadioButton单选按钮 │ ├── JComboBox下拉列表 │ ├── JList列表 │ ├── JTable表格 │ ├── JTree树形结构 │ ├── JMenuBar菜单栏 │ ├── JPanel面板容器 │ ├── JScrollPane滚动面板 │ └── JTabbedPane选项卡面板 └── JFrame顶级窗口继承自 AWT 的 Frame3.2 Swing 特点轻量级组件纯 Java 实现不依赖本地系统可插拔外观Pluggable Look and Feel可以切换不同操作系统风格MVC 架构Model-View-Controller 设计模式双缓冲技术减少闪烁提升绘制性能第四部分Swing 核心组件详解4.1 JFrame顶级窗口基本用法javaimport javax.swing.*; public class JFrameDemo { public static void main(String[] args) { // 1. 创建窗口 JFrame frame new JFrame(我的第一个 Swing 窗口); // 2. 设置窗口大小 frame.setSize(400, 300); // 3. 设置关闭操作点击 X 时退出程序 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 4. 设置窗口位置居中 frame.setLocationRelativeTo(null); // 5. 设置布局管理器 frame.setLayout(null); // 绝对布局不推荐 // 6. 设置窗口可见必须最后执行 frame.setVisible(true); // 7. 其他设置 frame.setResizable(false); // 禁止调整大小 frame.setAlwaysOnTop(true); // 置顶 } }JFrame 常用方法javaframe.setTitle(标题); // 设置标题 frame.setSize(800, 600); // 设置宽高像素 frame.setLocation(100, 50); // 设置位置x, y frame.setLocationRelativeTo(null); // 居中显示 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭时退出 frame.setResizable(false); // 禁止调整窗口大小 frame.setAlwaysOnTop(true); // 窗口置顶 frame.setIconImage(image); // 设置图标 frame.setVisible(true); // 显示窗口最后调用 frame.pack(); // 根据组件自动调整窗口大小关闭操作常量javaJFrame.EXIT_ON_CLOSE // 退出程序最常用 JFrame.DISPOSE_ON_CLOSE // 释放窗口资源但不退出程序 JFrame.HIDE_ON_CLOSE // 隐藏窗口默认 JFrame.DO_NOTHING_ON_CLOSE // 什么都不做4.2 JPanel面板/容器特点作为中间容器用于组织其他组件可以设置布局管理器可以嵌套使用代码示例javaimport javax.swing.*; import java.awt.*; public class JPanelDemo { public static void main(String[] args) { JFrame frame new JFrame(面板示例); frame.setSize(500, 400); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); // 创建三个面板 JPanel topPanel new JPanel(); topPanel.setBackground(Color.BLUE); topPanel.add(new JLabel(顶部面板)); JPanel centerPanel new JPanel(); centerPanel.setBackground(Color.GREEN); centerPanel.setLayout(new FlowLayout()); centerPanel.add(new JButton(按钮1)); centerPanel.add(new JButton(按钮2)); centerPanel.add(new JButton(按钮3)); JPanel bottomPanel new JPanel(); bottomPanel.setBackground(Color.RED); bottomPanel.add(new JLabel(底部面板)); // 添加到框架 frame.add(topPanel, BorderLayout.NORTH); frame.add(centerPanel, BorderLayout.CENTER); frame.add(bottomPanel, BorderLayout.SOUTH); frame.setVisible(true); } }4.3 常用组件JLabel标签javaJLabel label new JLabel(用户名); JLabel label2 new JLabel(带图标, SwingConstants.CENTER); label2.setFont(new Font(宋体, Font.BOLD, 20)); label2.setForeground(Color.RED);JTextField单行文本框javaJTextField textField new JTextField(); // 默认 JTextField textField2 new JTextField(20); // 指定列数 JTextField textField3 new JTextField(默认文字, 15); textField.setText(设置文本); String text textField.getText(); // 获取文本 textField.setEditable(false); // 设为只读JPasswordField密码框javaJPasswordField pwdField new JPasswordField(15); pwdField.setEchoChar(*); // 设置回显字符 char[] pwd pwdField.getPassword(); // 获取密码char数组 // 注意不要用 String 存储密码用 char[] 更安全JTextArea多行文本域javaJTextArea textArea new JTextArea(10, 30); // 行数列数 textArea.setLineWrap(true); // 自动换行 textArea.setWrapStyleWord(true); // 按单词换行 textArea.setText(初始文本); String content textArea.getText(); // 放入滚动面板 JScrollPane scrollPane new JScrollPane(textArea);JButton按钮javaJButton btn1 new JButton(确定); JButton btn2 new JButton(带图标, new ImageIcon(icon.png)); btn1.setToolTipText(点击此按钮提交); // 提示文本 btn1.setEnabled(false); // 禁用按钮 btn1.setMnemonic(O); // 快捷键 AltOJCheckBox复选框javaJCheckBox check1 new JCheckBox(Java); JCheckBox check2 new JCheckBox(Python, true); // 默认选中 check1.isSelected(); // 判断是否选中JRadioButton单选按钮java// 必须放在 ButtonGroup 中才能实现互斥 JRadioButton radio1 new JRadioButton(男); JRadioButton radio2 new JRadioButton(女, true); // 默认选中 ButtonGroup group new ButtonGroup(); group.add(radio1); group.add(radio2);JComboBox下拉列表javaString[] items {选项1, 选项2, 选项3}; JComboBoxString comboBox new JComboBox(items); comboBox.addItem(选项4); // 添加选项 comboBox.removeItem(选项2); // 移除选项 int index comboBox.getSelectedIndex(); // 获取选中索引 String item (String) comboBox.getSelectedItem(); // 获取选中值JList列表javaString[] data {项目A, 项目B, 项目C, 项目D}; JListString list new JList(data); list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); JScrollPane scrollPane new JScrollPane(list); // 需要滚动面板 // 获取选中值 ListString selected list.getSelectedValuesList();JTable表格java// 数据二维数组 String[][] data { {1, 张三, 男, 20}, {2, 李四, 女, 22}, {3, 王五, 男, 21} }; String[] columns {编号, 姓名, 性别, 年龄}; JTable table new JTable(data, columns); table.setRowHeight(25); // 设置行高 JScrollPane scrollPane new JScrollPane(table); // 必须加滚动面板第五部分布局管理器LayoutManager5.1 概述布局管理器负责自动排列容器中的组件避免硬编码坐标。5.2 FlowLayout流式布局从左到右排列放不下就换行默认居中对齐javaJPanel panel new JPanel(new FlowLayout()); // 或 JPanel panel new JPanel(); panel.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10)); // 左对齐间距10 panel.add(new JButton(按钮1)); panel.add(new JButton(按钮2)); panel.add(new JButton(按钮3));5.3 BorderLayout边界布局分为五个区域NORTH、SOUTH、WEST、EAST、CENTERJFrame 默认使用 BorderLayoutjavaJFrame frame new JFrame(); frame.setLayout(new BorderLayout(10, 10)); // 水平间距垂直间距 frame.add(new JButton(北), BorderLayout.NORTH); frame.add(new JButton(南), BorderLayout.SOUTH); frame.add(new JButton(西), BorderLayout.WEST); frame.add(new JButton(东), BorderLayout.EAST); frame.add(new JButton(中), BorderLayout.CENTER);5.4 GridLayout网格布局将容器划分为等大的网格每个组件占一个格子javaJPanel panel new JPanel(new GridLayout(3, 2, 5, 5)); // 3行2列间距5 for (int i 1; i 6; i) { panel.add(new JButton(按钮 i)); }5.5 CardLayout卡片布局多个组件重叠一次只显示一个常用于选项卡效果javaJPanel panel new JPanel(); CardLayout cardLayout new CardLayout(); panel.setLayout(cardLayout); panel.add(new JLabel(页面1), page1); panel.add(new JLabel(页面2), page2); panel.add(new JLabel(页面3), page3); // 切换页面 cardLayout.show(panel, page2); cardLayout.next(panel); cardLayout.previous(panel);5.6 BoxLayout箱式布局水平或垂直排列组件javaJPanel panel new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); // 垂直排列 panel.add(new JButton(按钮1)); panel.add(Box.createVerticalStrut(10)); // 添加间距 panel.add(new JButton(按钮2));5.7 布局管理器对比表布局特点适用场景FlowLayout从左到右自动换行工具栏、按钮组BorderLayout五区域主窗口布局GridLayout等分网格计算器、表单CardLayout重叠切换选项卡、向导BoxLayout水平/垂直排列表单、面板GridBagLayout最灵活最复杂复杂专业界面第六部分事件处理Event Handling6.1 事件模型委托事件模型text事件源组件 → 触发事件 → 事件对象 → 事件监听器 → 执行处理6.2 核心接口事件源发生事件的组件如 JButton事件对象封装事件信息如 ActionEvent事件监听器处理事件的接口如 ActionListener6.3 ActionListener动作事件javaimport javax.swing.*; import java.awt.event.*; public class ActionListenerDemo { public static void main(String[] args) { JFrame frame new JFrame(事件示例); frame.setSize(300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new FlowLayout()); JButton btn new JButton(点击我); JLabel label new JLabel(等待点击...); // 方式1匿名内部类最常用 btn.addActionListener(new ActionListener() { Override public void actionPerformed(ActionEvent e) { label.setText(按钮被点击了); System.out.println(点击事件触发); } }); // 方式2Lambda 表达式JDK 8 btn.addActionListener(e - { label.setText(Lambda 方式); }); // 方式3独立监听器类 btn.addActionListener(new MyActionListener()); frame.add(btn); frame.add(label); frame.setVisible(true); } } // 独立监听器类 class MyActionListener implements ActionListener { Override public void actionPerformed(ActionEvent e) { System.out.println(独立的监听器类); } }6.4 MouseListener鼠标事件javaimport javax.swing.*; import java.awt.event.*; public class MouseListenerDemo { public static void main(String[] args) { JFrame frame new JFrame(鼠标事件); frame.setSize(300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel new JPanel(); panel.setBackground(Color.LIGHT_GRAY); // 鼠标监听 panel.addMouseListener(new MouseListener() { Override public void mouseClicked(MouseEvent e) { System.out.println(鼠标单击( e.getX() , e.getY() )); } Override public void mousePressed(MouseEvent e) { System.out.println(鼠标按下); } Override public void mouseReleased(MouseEvent e) { System.out.println(鼠标释放); } Override public void mouseEntered(MouseEvent e) { System.out.println(鼠标进入); } Override public void mouseExited(MouseEvent e) { System.out.println(鼠标离开); } }); // 或使用适配器类只需要重写需要的方法 panel.addMouseListener(new MouseAdapter() { Override public void mouseClicked(MouseEvent e) { if (e.getButton() MouseEvent.BUTTON1) { System.out.println(左键单击); } else if (e.getButton() MouseEvent.BUTTON3) { System.out.println(右键单击); } } }); frame.add(panel); frame.setVisible(true); } }6.5 KeyListener键盘事件javaJTextField textField new JTextField(20); textField.addKeyListener(new KeyAdapter() { Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() KeyEvent.VK_ENTER) { System.out.println(按了回车键); } System.out.println(按下的键 e.getKeyChar()); } });6.6 ItemListener选项事件 - 复选框/下拉列表javaJCheckBox checkBox new JCheckBox(启用功能); checkBox.addItemListener(new ItemListener() { Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() ItemEvent.SELECTED) { System.out.println(选中); } else { System.out.println(取消选中); } } }); // Lambda 方式 checkBox.addItemListener(e - { boolean selected (e.getStateChange() ItemEvent.SELECTED); System.out.println(状态 selected); });6.7 DocumentListener文本变化事件javaJTextField textField new JTextField(20); textField.getDocument().addDocumentListener(new DocumentListener() { Override public void insertUpdate(DocumentEvent e) { System.out.println(文本插入 textField.getText()); } Override public void removeUpdate(DocumentEvent e) { System.out.println(文本删除 textField.getText()); } Override public void changedUpdate(DocumentEvent e) { // 属性变化不常用 } });6.8 事件监听器总结监听器事件类适用组件ActionListenerActionEventJButton、JMenuItem、JTextFieldMouseListenerMouseEvent所有 ComponentMouseMotionListenerMouseEvent所有 Component拖拽、移动KeyListenerKeyEvent所有 ComponentItemListenerItemEventJCheckBox、JRadioButton、JComboBoxDocumentListenerDocumentEventJTextField、JTextAreaWindowListenerWindowEventJFrame、JDialogFocusListenerFocusEvent所有 Component第七部分完整综合示例登录界面javaimport javax.swing.*; import java.awt.*; import java.awt.event.*; public class LoginDemo extends JFrame { private JTextField usernameField; private JPasswordField passwordField; private JLabel messageLabel; public LoginDemo() { setTitle(用户登录系统); setSize(400, 250); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); setResizable(false); // 创建主面板 JPanel mainPanel new JPanel(new BorderLayout(10, 10)); mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); // 标题 JLabel titleLabel new JLabel(用户登录, SwingConstants.CENTER); titleLabel.setFont(new Font(微软雅黑, Font.BOLD, 24)); titleLabel.setForeground(new Color(0, 102, 204)); // 表单面板 JPanel formPanel new JPanel(new GridBagLayout()); GridBagConstraints gbc new GridBagConstraints(); gbc.insets new Insets(5, 5, 5, 5); // 用户名 gbc.gridx 0; gbc.gridy 0; formPanel.add(new JLabel(用户名), gbc); gbc.gridx 1; gbc.gridy 0; usernameField new JTextField(15); formPanel.add(usernameField, gbc); // 密码 gbc.gridx 0; gbc.gridy 1; formPanel.add(new JLabel(密 码), gbc); gbc.gridx 1; gbc.gridy 1; passwordField new JPasswordField(15); passwordField.setEchoChar(●); formPanel.add(passwordField, gbc); // 按钮面板 JPanel buttonPanel new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 0)); JButton loginBtn new JButton(登录); JButton resetBtn new JButton(重置); JButton exitBtn new JButton(退出); // 设置按钮颜色 loginBtn.setBackground(new Color(0, 153, 204)); loginBtn.setForeground(Color.WHITE); loginBtn.setFocusPainted(false); buttonPanel.add(loginBtn); buttonPanel.add(resetBtn); buttonPanel.add(exitBtn); // 消息标签 messageLabel new JLabel(请输入用户名和密码, SwingConstants.CENTER); messageLabel.setForeground(Color.GRAY); messageLabel.setFont(new Font(宋体, Font.PLAIN, 12)); // 组装 mainPanel.add(titleLabel, BorderLayout.NORTH); mainPanel.add(formPanel, BorderLayout.CENTER); mainPanel.add(buttonPanel, BorderLayout.SOUTH); add(mainPanel, BorderLayout.CENTER); add(messageLabel, BorderLayout.SOUTH); // 事件监听 // 登录按钮 loginBtn.addActionListener(e - handleLogin()); // 回车键登录 usernameField.addActionListener(e - handleLogin()); passwordField.addActionListener(e - handleLogin()); // 重置按钮 resetBtn.addActionListener(e - { usernameField.setText(); passwordField.setText(); messageLabel.setText(已重置); messageLabel.setForeground(Color.GRAY); usernameField.requestFocus(); }); // 退出按钮 exitBtn.addActionListener(e - System.exit(0)); // 窗口关闭确认 addWindowListener(new WindowAdapter() { Override public void windowClosing(WindowEvent e) { int choice JOptionPane.showConfirmDialog( LoginDemo.this, 确定要退出吗, 确认退出, JOptionPane.YES_NO_OPTION ); if (choice JOptionPane.YES_OPTION) { System.exit(0); } } }); setVisible(true); } private void handleLogin() { String username usernameField.getText().trim(); String password new String(passwordField.getPassword()); if (username.isEmpty() || password.isEmpty()) { messageLabel.setForeground(Color.RED); messageLabel.setText(用户名和密码不能为空); return; } // 模拟验证 if (admin.equals(username) 123456.equals(password)) { messageLabel.setForeground(new Color(0, 153, 0)); messageLabel.setText(登录成功欢迎 username); JOptionPane.showMessageDialog( this, 登录成功, 提示, JOptionPane.INFORMATION_MESSAGE ); } else { messageLabel.setForeground(Color.RED); messageLabel.setText(用户名或密码错误); passwordField.setText(); passwordField.requestFocus(); } } public static void main(String[] args) { // 设置 Swing 外观为系统风格 try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); } // 在事件调度线程中创建 GUI SwingUtilities.invokeLater(() - new LoginDemo()); } }第八部分Swing 高级特性8.1 对话框JOptionPanejava// 消息对话框 JOptionPane.showMessageDialog(parent, 这是一个消息); JOptionPane.showMessageDialog(parent, 带标题, 标题, JOptionPane.INFORMATION_MESSAGE); // 确认对话框 int result JOptionPane.showConfirmDialog(parent, 确认删除吗); if (result JOptionPane.YES_OPTION) { System.out.println(用户点击了是); } else if (result JOptionPane.NO_OPTION) { System.out.println(用户点击了否); } // 输入对话框 String input JOptionPane.showInputDialog(parent, 请输入姓名); if (input ! null !input.isEmpty()) { System.out.println(输入的姓名 input); } // 选项对话框 String[] options {选项A, 选项B, 选项C}; int choice JOptionPane.showOptionDialog( parent, 请选择一个选项, 选择, JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0] );8.2 菜单JMenuBarjavaJMenuBar menuBar new JMenuBar(); // 文件菜单 JMenu fileMenu new JMenu(文件); JMenuItem newItem new JMenuItem(新建); JMenuItem openItem new JMenuItem(打开); JMenuItem saveItem new JMenuItem(保存); JMenuItem exitItem new JMenuItem(退出); // 快捷键 newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_DOWN_MASK)); openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK)); saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)); // 添加分割线 fileMenu.add(newItem); fileMenu.add(openItem); fileMenu.add(saveItem); fileMenu.addSeparator(); fileMenu.add(exitItem); // 事件监听 exitItem.addActionListener(e - System.exit(0)); // 编辑菜单 JMenu editMenu new JMenu(编辑); editMenu.add(new JMenuItem(剪切)); editMenu.add(new JMenuItem(复制)); editMenu.add(new JMenuItem(粘贴)); // 添加到菜单栏 menuBar.add(fileMenu); menuBar.add(editMenu); // 设置到框架 frame.setJMenuBar(menuBar);8.3 弹出菜单JPopupMenujavaJPopupMenu popupMenu new JPopupMenu(); popupMenu.add(new JMenuItem(复制)); popupMenu.add(new JMenuItem(粘贴)); popupMenu.addSeparator(); popupMenu.add(new JMenuItem(删除)); // 鼠标右键弹出 panel.addMouseListener(new MouseAdapter() { Override public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) { popupMenu.show(panel, e.getX(), e.getY()); } } });8.4 选项卡JTabbedPanejavaJTabbedPane tabbedPane new JTabbedPane(); JPanel tab1 new JPanel(); tab1.add(new JLabel(这是第一个选项卡)); tab1.setBackground(Color.WHITE); JPanel tab2 new JPanel(); tab2.add(new JButton(按钮)); tab2.setBackground(Color.LIGHT_GRAY); JPanel tab3 new JPanel(new GridLayout(2, 2)); tab3.add(new JCheckBox(选项1)); tab3.add(new JCheckBox(选项2)); tabbedPane.addTab(基本信息, tab1); tabbedPane.addTab(操作, tab2); tabbedPane.addTab(设置, tab3); frame.add(tabbedPane, BorderLayout.CENTER);8.5 滚动面板JScrollPanejava// 文本域需要滚动 JTextArea textArea new JTextArea(10, 30); JScrollPane scrollPane new JScrollPane(textArea); // 设置滚动策略 scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); // 表格需要滚动 JTable table new JTable(data, columns); JScrollPane tableScroll new JScrollPane(table);8.6 外观Look and Feeljava// 系统外观Windows/Mac/Linux UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // 跨平台外观Metal UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); // Nimbus 外观JDK 6 UIManager.setLookAndFeel(javax.swing.plaf.nimbus.NimbusLookAndFeel); // 所有外观 UIManager.LookAndFeelInfo[] looks UIManager.getInstalledLookAndFeels(); for (UIManager.LookAndFeelInfo info : looks) { System.out.println(info.getName() : info.getClassName()); }8.7 线程安全Swing 与多线程java// Swing 组件必须在事件调度线程EDT中创建和更新 // 错误方式 new Thread(() - { label.setText(新文本); // ❌ 多线程操作 Swing 不安全 }).start(); // 正确方式1invokeLater SwingUtilities.invokeLater(() - { label.setText(新文本); }); // 正确方式2invokeAndWait等待执行完成 try { SwingUtilities.invokeAndWait(() - { label.setText(新文本); }); } catch (Exception e) { e.printStackTrace(); } // 在主方法中创建 GUI public static void main(String[] args) { SwingUtilities.invokeLater(() - new LoginDemo()); }第九部分JavaFX 简要介绍9.1 特点现代化 GUI 框架替代 Swing支持 CSS 样式支持 FXML声明式 UI硬件加速渲染内置动画、图表、WebView9.2 简单示例javaimport javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.StackPane; import javafx.stage.Stage; public class JavaFXDemo extends Application { Override public void start(Stage primaryStage) { Button btn new Button(点击我); btn.setOnAction(e - System.out.println(按钮被点击)); StackPane root new StackPane(); root.getChildren().add(btn); Scene scene new Scene(root, 300, 200); primaryStage.setTitle(JavaFX 示例); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } }第十部分Swing 最佳实践与常见问题10.1 最佳实践所有 GUI 操作在 EDT 线程中执行使用SwingUtilities.invokeLater()避免使用绝对布局使用布局管理器组件创建与显示分离先创建所有组件最后setVisible(true)使用pack()而不是setSize()让窗口自适应大文本用 JTextArea JScrollPane密码用 JPasswordField用 char[] 获取长时间操作使用 SwingWorker后台任务10.2 常见问题问题原因解决方案组件不显示未添加到容器或未设置布局检查add()和布局管理器窗口无法关闭未设置关闭操作setDefaultCloseOperation()界面闪烁未使用双缓冲Swing 默认双缓冲检查是否关闭卡顿/无响应在 EDT 执行耗时操作使用 SwingWorker 或新线程乱码编码问题设置-Dfile.encodingUTF-810.3 SwingWorker后台任务javaimport javax.swing.*; public class SwingWorkerDemo { public static void main(String[] args) { JFrame frame new JFrame(进度示例); frame.setSize(300, 150); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new FlowLayout()); JProgressBar progressBar new JProgressBar(0, 100); progressBar.setStringPainted(true); JButton startBtn new JButton(开始); JLabel label new JLabel(准备就绪); startBtn.addActionListener(e - { startBtn.setEnabled(false); // SwingWorker 执行后台任务 SwingWorkerVoid, Integer worker new SwingWorkerVoid, Integer() { Override protected Void doInBackground() throws Exception { for (int i 0; i 100; i) { Thread.sleep(50); // 模拟耗时 publish(i); // 更新进度 } return null; } Override protected void process(Integer... chunks) { int progress chunks[chunks.length - 1]; progressBar.setValue(progress); label.setText(进度 progress %); } Override protected void done() { startBtn.setEnabled(true); label.setText(完成); } }; worker.execute(); }); frame.add(progressBar); frame.add(startBtn); frame.add(label); frame.setVisible(true); } }第十一部分知识点速查表分类组件/类用途顶层容器JFrame主窗口中间容器JPanel组织组件基本组件JLabel显示文本/图标JButton按钮JTextField单行文本输入JTextArea多行文本输入JPasswordField密码输入选择组件JCheckBox复选框JRadioButton单选按钮JComboBox下拉列表JList列表高级组件JTable表格JTree树形结构JTabbedPane选项卡JScrollPane滚动面板布局FlowLayout流式布局BorderLayout边界布局GridLayout网格布局CardLayout卡片布局BoxLayout箱式布局事件ActionListener动作事件MouseListener鼠标事件KeyListener键盘事件ItemListener选项事件对话框JOptionPane标准对话框菜单JMenuBar菜单栏JPopupMenu右键菜单线程SwingUtilitiesEDT 工具类SwingWorker后台任务第十二部分记忆口诀textSwing 组件分三层顶层容器 JFrame中间面板 JPanel 基本组件有标签按钮文本框和密码 选择组件复选框单选按钮下拉框 表格列表滚动条选项卡和菜单栏 布局管理器五兄弟流式边界和网格卡片箱式最灵活 事件模型三要素事件源和监听器事件对象传信息 匿名内部类最常用Lambda 表达式更简洁 GUI 操作在 EDT耗时任务用 Worker 创建完毕再显示setVisible 最后放