杰瑞科技汇

Java Swing登录界面如何实现?

最基础版本

这是一个最简单的登录界面,包含用户名、密码输入框和登录按钮,并处理最基础的点击事件。

Java Swing登录界面如何实现?-图1
(图片来源网络,侵删)

核心组件

  • JFrame: 窗口
  • JPanel: 面板,用于布局组件
  • JLabel: 标签,用于显示“用户名”、“密码”
  • JTextField: 单行文本框,用于输入用户名
  • JPasswordField: 密码框,用于输入密码(显示为星号)
  • JButton: 按钮

代码实现

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class SimpleLoginUI {
    public static void main(String[] args) {
        // 创建一个窗口
        JFrame frame = new JFrame("简单登录界面");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭窗口时退出程序
        frame.setSize(350, 200); // 设置窗口大小
        frame.setLocationRelativeTo(null); // 窗口居中显示
        // 创建一个面板,使用流式布局
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 20));
        // 创建组件
        JLabel userLabel = new JLabel("用户名:");
        JTextField userText = new JTextField(15); // 列数为15
        JLabel passLabel = new JLabel("密码:");
        JPasswordField passText = new JPasswordField(15); // 密码框
        JButton loginButton = new JButton("登录");
        // 将组件添加到面板
        panel.add(userLabel);
        panel.add(userText);
        panel.add(passLabel);
        panel.add(passText);
        panel.add(loginButton);
        // 将面板添加到窗口
        frame.add(panel);
        // 为登录按钮添加点击事件
        loginButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String username = userText.getText();
                String password = new String(passText.getPassword()); // 从密码框获取文本
                // 这里只是一个简单的示例,实际应用中应该连接数据库进行验证
                if ("admin".equals(username) && "123456".equals(password)) {
                    JOptionPane.showMessageDialog(frame, "登录成功!");
                    // 登录成功后可以打开新窗口或关闭当前窗口
                    // frame.dispose(); // 关闭登录窗口
                    // new MainApplicationUI(); // 打开主应用窗口
                } else {
                    JOptionPane.showMessageDialog(frame, "用户名或密码错误!", "错误", JOptionPane.ERROR_MESSAGE);
                }
            }
        });
        // 设置窗口可见
        frame.setVisible(true);
    }
}

运行效果


使用 GridBagLayout 的专业版

FlowLayout 布局比较简单,无法精确控制组件位置。GridBagLayout 是 Swing 中最强大、最灵活的布局管理器,可以创建对齐良好、间距均匀的专业界面。

代码实现

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ProfessionalLoginUI {
    public static void main(String[] args) {
        // 1. 创建主窗口
        JFrame frame = new JFrame("专业登录界面");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 250);
        frame.setLocationRelativeTo(null);
        // 2. 使用 GridBagLayout
        JPanel panel = new JPanel(new GridBagLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // 添加内边距
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5); // 组件间距
        gbc.fill = GridBagConstraints.HORIZONTAL; // 水平填充
        // 3. 创建组件
        JLabel titleLabel = new JLabel("用户登录", JLabel.CENTER);
        titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 20)); // 设置字体
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 2; // 占据两列
        panel.add(titleLabel, gbc);
        JLabel userLabel = new JLabel("用户名:");
        JTextField userText = new JTextField(15);
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.gridwidth = 1; // 占据一列
        panel.add(userLabel, gbc);
        gbc.gridx = 1;
        panel.add(userText, gbc);
        JLabel passLabel = new JLabel("密码:");
        JPasswordField passText = new JPasswordField(15);
        gbc.gridx = 0;
        gbc.gridy = 2;
        panel.add(passLabel, gbc);
        gbc.gridx = 1;
        panel.add(passText, gbc);
        // 登录按钮
        JButton loginButton = new JButton("登录");
        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.gridwidth = 2; // 占据两列,使其居中
        gbc.fill = GridBagConstraints.NONE; // 不填充
        gbc.anchor = GridBagConstraints.CENTER; // 居中
        panel.add(loginButton, gbc);
        // 忘记密码标签
        JLabel forgotLabel = new JLabel("忘记密码?", JLabel.RIGHT);
        gbc.gridx = 0;
        gbc.gridy = 4;
        gbc.gridwidth = 2;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.anchor = GridBagConstraints.LINE_END; // 右对齐
        panel.add(forgotLabel, gbc);
        // 4. 添加事件处理
        loginButton.addActionListener(e -> {
            String username = userText.getText();
            String password = new String(passText.getPassword());
            if ("admin".equals(username) && "123456".equals(password)) {
                JOptionPane.showMessageDialog(frame, "登录成功!");
                frame.dispose();
                // 这里可以跳转到主界面
                // SwingUtilities.invokeLater(MainApplicationUI::new);
            } else {
                JOptionPane.showMessageDialog(frame, "用户名或密码错误!", "登录失败", JOptionPane.ERROR_MESSAGE);
                userText.setText(""); // 清空用户名
                passText.setText(""); // 清空密码
                userText.requestFocus(); // 让用户名框重新获得焦点
            }
        });
        // 5. 显示窗口
        frame.add(panel);
        frame.setVisible(true);
    }
}

代码解释

  1. GridBagConstraints: 这是 GridBagLayout 的配置对象,它定义了每个组件的布局规则。
  2. gbc.gridx, gbc.gridy: 定义组件在网格中的坐标(列和行)。
  3. gbc.gridwidth: 定义组件跨越的列数。
  4. gbc.insets: 设置组件与单元格边界的内边距。
  5. gbc.fill: 定义组件在单元格内的填充方式(HORIZONTAL, VERTICAL, BOTH, NONE)。
  6. gbc.anchor: 定义组件在单元格内的对齐方式(CENTER, NORTH, SOUTH, EAST, WEST 等)。
  7. panel.setBorder(...): 为面板添加边距,让界面看起来不那么拥挤。

运行效果


更美观的版本(带背景图片和图标)

这个版本将展示如何添加背景图片、为按钮和标签添加图标,使界面更具吸引力。

准备工作

你需要准备两张图片:

  1. background.jpg (作为窗口背景)
  2. user_icon.pngpassword_icon.png (作为输入框前的图标)

将这两张图片放在项目的 src 目录下(或者创建一个 resources 文件夹,并确保在构建路径中)。

Java Swing登录界面如何实现?-图2
(图片来源网络,侵删)

代码实现

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
public class BeautifulLoginUI {
    public static void main(String[] args) {
        // 使用 SwingUtilities.invokeLater 确保在事件分发线程中创建和显示 GUI
        SwingUtilities.invokeLater(() -> {
            // 创建主窗口
            JFrame frame = new JFrame("美观登录界面");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(500, 350);
            frame.setLocationRelativeTo(null);
            frame.setResizable(false); // 禁止调整窗口大小
            // 创建带背景的面板
            BackgroundPanel backgroundPanel = new BackgroundPanel();
            backgroundPanel.setLayout(new BorderLayout());
            // 创建登录面板(使用方案二的 GridBagLayout)
            JPanel loginPanel = createLoginPanel(frame);
            // 将登录面板添加到背景面板中央
            backgroundPanel.add(loginPanel, BorderLayout.CENTER);
            frame.setContentPane(backgroundPanel); // 设置背景面板为窗口内容面板
            frame.setVisible(true);
        });
    }
    private static JPanel createLoginPanel(JFrame parentFrame) {
        JPanel panel = new JPanel(new GridBagLayout());
        panel.setOpaque(false); // 设置为透明,以便显示背景
        panel.setBorder(BorderFactory.createEmptyBorder(20, 40, 20, 40));
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(10, 10, 10, 10);
        gbc.fill = GridBagConstraints.HORIZONTAL;
        // 标题
        JLabel titleLabel = new JLabel("欢迎登录", JLabel.CENTER);
        titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24));
        titleLabel.setForeground(new Color(70, 130, 180)); // 设置字体颜色
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 2;
        panel.add(titleLabel, gbc);
        // 用户名行
        gbc.gridwidth = 1;
        JLabel userIcon = new JLabel(loadIcon("user_icon.png", 20, 20));
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.anchor = GridBagConstraints.EAST;
        panel.add(userIcon, gbc);
        JTextField userText = new JTextField(15);
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.anchor = GridBagConstraints.WEST;
        panel.add(userText, gbc);
        // 密码行
        JLabel passIcon = new JLabel(loadIcon("password_icon.png", 20, 20));
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.anchor = GridBagConstraints.EAST;
        panel.add(passIcon, gbc);
        JPasswordField passText = new JPasswordField(15);
        gbc.gridx = 1;
        gbc.gridy = 2;
        gbc.anchor = GridBagConstraints.WEST;
        panel.add(passText, gbc);
        // 登录按钮
        JButton loginButton = new JButton("登 录");
        loginButton.setFont(new Font("微软雅黑", Font.BOLD, 14));
        loginButton.setBackground(new Color(70, 130, 180));
        loginButton.setForeground(Color.WHITE);
        loginButton.setFocusPainted(false); // 去除点击时的焦点框
        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.gridwidth = 2;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.CENTER;
        panel.add(loginButton, gbc);
        // 事件处理
        loginButton.addActionListener(e -> {
            String username = userText.getText();
            String password = new String(passText.getPassword());
            if ("admin".equals(username) && "123456".equals(password)) {
                JOptionPane.showMessageDialog(parentFrame, "登录成功!");
                parentFrame.dispose();
            } else {
                JOptionPane.showMessageDialog(parentFrame, "用户名或密码错误!", "错误", JOptionPane.ERROR_MESSAGE);
                userText.setText("");
                passText.setText("");
                userText.requestFocus();
            }
        });
        return panel;
    }
    // 辅助方法:从类路径加载图标
    private static Icon loadIcon(String path, int width, int height) {
        URL imageUrl = BeautifulLoginUI.class.getResource(path);
        if (imageUrl != null) {
            ImageIcon icon = new ImageIcon(imageUrl);
            Image image = icon.getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH);
            return new ImageIcon(image);
        }
        return null;
    }
}
// 自定义背景面板
class BackgroundPanel extends JPanel {
    private Image backgroundImage;
    public BackgroundPanel() {
        try {
            // 从类路径加载背景图片
            backgroundImage = new ImageIcon(BeautifulLoginUI.class.getResource("background.jpg")).getImage();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (backgroundImage != null) {
            // 绘制背景图片,并拉伸以填满整个面板
            g.drawImage(backgroundImage, 0, 0, this.getWidth(), this.getHeight(), this);
        }
    }
}

代码解释

  1. SwingUtilities.invokeLater: 这是创建 Swing GUI 的标准做法,确保所有 GUI 相关的代码都在“事件分发线程”(EDT) 上执行,避免线程安全问题。
  2. BackgroundPanel: 这是一个自定义的 JPanel,通过重写 paintComponent 方法,我们可以在面板上绘制自定义内容,在这里是背景图片。
  3. Image.getScaledInstance: 用于将加载的图片缩放到指定大小。
  4. setFocusPainted(false): 移除按钮被点击时默认绘制的焦点矩形,使界面更清爽。
  5. setOpaque(false): 对于放置在背景面板上的子面板(如 loginPanel),必须设置为透明,才能显示出底层的背景图片。

运行效果

总结与建议

特性 方案一 (基础) 方案二 (专业) 方案三 (美观)
布局管理器 FlowLayout GridBagLayout GridBagLayout
美观度
灵活性
复杂度
适用场景 快速原型、学习 大多数桌面应用 对UI有较高要求的商业应用

对于初学者,建议从方案一开始,理解各个组件的基本用法。 对于实际项目开发,方案二是很好的起点,它提供了专业且可控的布局。 如果你的应用需要更好的用户体验,可以参考方案三进行美化,并考虑使用第三方库(如 FlatLaf)来快速实现现代化的界面风格。

Java Swing登录界面如何实现?-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇