首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java Swing 實戰:手把手構建登錄界面(組件佈局、事件監聽、輸入驗證全流程)

     編輯:Java 綜合教學

前言:從零寫一個可運行的 Swing 登錄窗口

Swing 是 Java 經典 GUI 框架,雖然現代開發多用 JavaFX/Web,但理解 Swing 組件模型、事件機制、佈局管理對掌握桌面開發基礎仍有價值。本文通過一個完整的登錄界面案例,涵蓋 JFrame、JPanel、JLabel、JTextField、JPasswordField、JComboBox、JButton、JOptionPane 核心組件用法,以及絕對佈局、事件監聽、鍵盤快捷鍵、輸入驗證、圖片加載完整流程。

一、 效果預覽與功能清單

  • 窗口居中顯示,固定大小 560×400,不可縮放
  • 標題:「網站內容管理系統」,楷體 20pt
  • 輸入:用戶名(文本框)、密碼(密碼框、*掩碼)、身份(下拉框:管理員/其他)
  • 按鈕:確定(Alt+Y)、取消(Alt+N),黑色字體
  • 驗證:用戶名/密碼均為 "123" 登錄成功,否則失敗並清空密碼
  • 圖片:背景圖片加載(代碼中路徑需自行調整)

二、 完整源碼(可直接複製運行)


package com.example.swing;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class LoginFrame extends JFrame implements ActionListener {

    // 組件聲明
    private JPanel backgroundPanel;
    private JButton btnLogin, btnCancel;
    private JLabel lblTitle, lblUser, lblPwd, lblRole;
    private JLabel lblImage;
    private JComboBox cmbRole;
    private JTextField txtUser;
    private JPasswordField txtPwd;
    private ImageIcon bgIcon;

    private static final String[] ROLES = {"管理員", "其他"};
    private static final String VALID_USER = "123";
    private static final String VALID_PWD = "123";

    public LoginFrame() {
        initComponents();
        layoutComponents();
        registerListeners();
        frameSettings();
    }

    private void initComponents() {
        // 標題
        lblTitle = new JLabel("網 站 內 容 管 理 系 統");
        lblTitle.setFont(new Font("楷體", Font.BOLD, 20));
        lblTitle.setForeground(Color.BLACK);

        // 標籤
        lblUser = new JLabel("用戶名:");
        lblPwd = new JLabel("密 碼:");
        lblRole = new JLabel("身 份:");
        for (JLabel lbl : new JLabel[]{lblUser, lblPwd, lblRole}) {
            lbl.setFont(new Font("楷體", Font.PLAIN, 15));
            lbl.setForeground(Color.BLACK);
        }

        // 輸入組件
        txtUser = new JTextField();
        txtUser.setForeground(Color.BLACK);

        txtPwd = new JPasswordField();
        txtPwd.setEchoChar('*');
        txtPwd.setForeground(Color.BLACK);

        cmbRole = new JComboBox<>(ROLES);
        cmbRole.setForeground(Color.BLACK);

        // 按鈕 + 快捷鍵
        btnLogin = new JButton("確定 (Alt+Y)");
        btnLogin.setMnemonic(KeyEvent.VK_Y);
        btnLogin.setForeground(Color.BLACK);

        btnCancel = new JButton("取消 (Alt+N)");
        btnCancel.setMnemonic(KeyEvent.VK_N);
        btnCancel.setForeground(Color.BLACK);

        // 背景圖片面板
        backgroundPanel = new JPanel(null); // 面板內部也用絕對佈局
        bgIcon = new ImageIcon(getClass().getResource("/images/login_bg.jpg")); // 建議放 resources/images
        lblImage = new JLabel(bgIcon);
        backgroundPanel.add(lblImage);
    }

    private void layoutComponents() {
        setLayout(null); // 窗口絕對佈局
        // 背景面板鋪滿
        backgroundPanel.setBounds(0, 0, 560, 400);
        lblImage.setBounds(0, 0, 560, 400);
        add(backgroundPanel);

        // 組件座標 (x, y, width, height)
        lblTitle.setBounds(115, 20, 420, 50);
        lblUser.setBounds(130, 90, 100, 50);
        txtUser.setBounds(210, 100, 180, 25);
        lblPwd.setBounds(130, 150, 100, 50);
        txtPwd.setBounds(210, 160, 180, 25);
        lblRole.setBounds(130, 200, 100, 50);
        cmbRole.setBounds(210, 210, 100, 25);
        btnLogin.setBounds(120, 270, 120, 35);
        btnCancel.setBounds(320, 270, 120, 35);

        // 添加到窗口 (背景面板在最底層)
        add(lblTitle);
        add(lblUser);
        add(txtUser);
        add(lblPwd);
        add(txtPwd);
        add(lblRole);
        add(cmbRole);
        add(btnLogin);
        add(btnCancel);
    }

    private void registerListeners() {
        btnLogin.addActionListener(this);
        btnCancel.addActionListener(this);
    }

    private void frameSettings() {
        setTitle("歡迎登陸網站內容管理系統");
        setSize(560, 400);
        setResizable(false);
        setLocationRelativeTo(null); // 居中
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == btnLogin) {
            handleLogin();
        } else if (e.getSource() == btnCancel) {
            System.exit(0);
        }
    }

    private void handleLogin() {
        String username = txtUser.getText().trim();
        String password = new String(txtPwd.getPassword()); // 獲取密碼字符數組轉字符串

        if (username.isEmpty()) {
            JOptionPane.showMessageDialog(this, "請輸入用戶名!", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }
        if (password.isEmpty()) {
            JOptionPane.showMessageDialog(this, "請輸入密碼!", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }

        if (VALID_USER.equals(username) && VALID_PWD.equals(password)) {
            JOptionPane.showMessageDialog(this, "恭喜你,登陸成功!", "成功", JOptionPane.INFORMATION_MESSAGE);
            dispose(); // 關閉登錄窗口
            // TODO: 打開主業務窗口 new MainFrame().setVisible(true);
        } else {
            JOptionPane.showMessageDialog(this, "用戶名或密碼錯誤!", "錯誤", JOptionPane.ERROR_MESSAGE);
            txtPwd.setText(""); // 清空密碼框
        }
    }

    public static void main(String[] args) {
        // EDT 線程安全啟動
        SwingUtilities.invokeLater(() -> new LoginFrame());
    }
}

三、 核心知識點深度解析

3.1 佈局管理策略

  • 窗口層:setLayout(null) 絕對佈局,手動 setBounds(x,y,w,h),適合固定尺寸登錄頁。
  • 背景面板層:JPanel(null) 同樣絕對佈局,JLabel 裝載 ImageIcon 鋪滿背景。
  • 生產建議:複雜界面改用 BorderLayout + GridBagLayout 或 MigLayout 第三方庫,自適應縮放。

3.2 事件監聽機制

  • 實現 ActionListener 接口,actionPerformed 統一分發。
  • e.getSource() 區分事件源。
  • 現代寫法:Lambda 表達式 btnLogin.addActionListener(e -> handleLogin()); 更簡潔。

3.3 鍵盤快捷鍵


btnLogin.setMnemonic(KeyEvent.VK_Y); // Alt+Y 觸發
btnCancel.setMnemonic(KeyEvent.VK_N); // Alt+N 觸發

配合按鈕文本顯示「確定 (Alt+Y)」,提升鍵盤用戶體驗。

3.4 密碼框處理


JPasswordField pwdField = new JPasswordField();
pwdField.setEchoChar('*'); // 掩碼字符
char[] pwdChars = pwdField.getPassword(); // 返回 char[] 而非 String,安全性更高
String pwd = new String(pwdChars); // 用完及時清空:Arrays.fill(pwdChars, '0');

3.5 圖片資源加載

  • 開發環境:getClass().getResource("/images/xxx.jpg") 從 classpath 讀取 (需放入 src/main/resources/images)。
  • 打包後:JAR 內部同樣可用,避免文件路徑依賴。
  • 備選:new ImageIcon("path/to/file.jpg") 讀取外部文件,部署靈活但路徑易錯。

3.6 輸入驗證與用戶反饋

  • JOptionPane.showMessageDialog 四種圖標:ERROR_MESSAGE, WARNING_MESSAGE, INFORMATION_MESSAGE, QUESTION_MESSAGE。
  • 登錄失敗清空密碼框 txtPwd.setText(""),防止肩部偷窺。

四、 進階優化方向

  1. 表單驗證框架:引入 Hibernate Validator + 自定義註解,分離驗證邏輯。
  2. 記住密碼/自動登錄:Preferences API 或加密配置文件存儲 Token。
  3. 第三方登錄:OAuth2 整合微信/Google/GitHub。
  4. 響應式佈局:遷移至 JavaFX (FXML + CSS) 或 Web 技術棧。
  5. 國際化:ResourceBundle 管理多語言文本。

結語

Swing 登錄界面雖小,卻包含了 GUI 開發的核心要素:組件樹構建、佈局策略、事件模型、資源管理、輸入驗證、線程安全。掌握這些基石,無論未來轉向 JavaFX、Electron 還是 Web 前端,都能觸類旁通。建議動手跑通代碼,再嘗試加入「記住密碼」複選框、登錄成功跳轉主頁等功能,在實戰中內化知識。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved