【Java Swing】图形用户界面(GUI)开发及打包EXE指南

一、关于 Java Swing

Java Swing 是 Java 编程语言中一个用于构建图形用户界面(GUI)的工具包,它提供了一套丰富的组件和功能,使开发者能够创建跨平台的桌面应用程序。作为 Java Foundation Classes(JFC)的一部分,Swing 是对早期 Abstract Window Toolkit(AWT)的扩展和改进,采用了纯 Java 实现,确保了跨平台的一致性。

在这里插入图片描述

📦 核心组件与结构

Swing 的组件体系分为顶层容器中间容器基本组件

  • 顶层容器:如 JFrame(主窗口)、JDialog(对话框),是窗口类组件,可以独立显示。
  • 中间容器:如 JPanel(面板)、JScrollPane(滚动面板),用于组织和承载其他组件,必须依附于顶层容器。
  • 基本组件:如 JButton(按钮)、JTextField(文本框)、JLabel(标签),直接实现用户交互。

Swing 组件均以 “J” 开头(例如 JButton),位于 javax.swing包中。其设计遵循 MVC(Model-View-Controller)模式,将数据逻辑、显示逻辑和用户输入处理分离,提高了代码的灵活性和可维护性。

🎨 特点与优势

  1. 跨平台性:Swing 组件完全用 Java 编写,不依赖本地操作系统的图形界面,因此可以在 Windows、Linux、macOS 等平台上保持一致的外观和行为。
  2. 可定制性:支持可插拔的外观风格(Pluggable Look and Feel),允许应用程序使用系统原生外观或自定义主题。
  3. 丰富的组件库:提供了大量预构建组件,如表格(JTable)、树(JTree)、菜单(JMenu)等,满足复杂界面的需求。
  4. 事件处理机制:通过事件监听器(如 ActionListener)响应用户操作(如点击按钮、输入文本),实现交互逻辑。

📚 应用场景

Swing 适用于开发各种桌面应用程序,如:企业管理系统:如财务软件、客户关系管理(CRM)系统。工具软件:如文本编辑器、图像查看器、科学计算工具。教育软件:如教学辅助工具、学习应用程序。

二、密码生成器示例

Windows 密码生成器应用功能:输入设备ID号通过加密算法得到6位数字密码

2.1 用Java实现核心加密逻辑

使用Java的加密库(JCE - Java Cryptography Extension)来实现,创建一个名为 CryptoUtils.java 的文件。

// CryptoUtils.java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class CryptoUtils {

    // !!! 重要 !!!
    private static final String SECRET_KEY = "Your_Unique_And_Secret_Key_Here";

    /**
     * 根据设备ID和密钥生成6位密码。
     * @param deviceId 设备唯一标识符
     * @return 生成的6位数字密码字符串
     * @throws NoSuchAlgorithmException 如果HmacSHA256算法不可用
     * @throws InvalidKeyException 如果密钥无效
     */
    public static String generatePassword(String deviceId) throws NoSuchAlgorithmException, InvalidKeyException {
        // 1. 定义加密算法为 HmacSHA256
        final String ALGORITHM = "HmacSHA256";
        Mac mac = Mac.getInstance(ALGORITHM);

        // 2. 使用我们的密钥初始化Mac实例
        SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), ALGORITHM);
        mac.init(secretKeySpec);

        // 3. 对设备ID进行加密,得到字节数组形式的哈希摘要
        byte[] hash = mac.doFinal(deviceId.getBytes(StandardCharsets.UTF_8));

        // 4. 截取哈希摘要的最后4个字节,并将其转换为一个整数
        //    这部分逻辑必须精确地模拟Python的行为
        int offset = hash.length - 4;
        long truncatedHash = 0;
        for (int i = 0; i < 4; ++i) {
            truncatedHash <<= 8;
            truncatedHash |= (hash[offset + i] & 0xFF);
        }

        // 5. 将整数的最高位清零,确保结果为正数
        truncatedHash &= 0x7FFFFFFF;

        // 6. 对 1,000,000 取模
        long sixDigitNumber = truncatedHash % 1000000;

        // 7. 格式化为6位数字,不足的前面补0
        return String.format("%06d", sixDigitNumber);
    }
}

2.2 用Java Swing创建图形用户界面(GUI)

使用Java内置的Swing库来创建窗口界面,创建一个名为 PasswordGeneratorApp.java 的文件。

// PasswordGeneratorApp.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class PasswordGeneratorApp {

    public static void main(String[] args) {
        // 在事件调度线程中创建和显示GUI,这是Swing的最佳实践
        SwingUtilities.invokeLater(PasswordGeneratorApp::createAndShowGUI);
    }

    private static void createAndShowGUI() {
        // --- 创建主窗口 ---
        JFrame frame = new JFrame("Java 密码生成器");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(420, 220);
        frame.setLocationRelativeTo(null); // 窗口居中

        // --- 创建面板和控件 ---
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); // 垂直布局
        panel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15)); // 添加边距

        JLabel idLabel = new JLabel("设备ID (Device ID):");
        idLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

        JTextField idField = new JTextField(25);
        idField.setMaximumSize(idField.getPreferredSize()); // 防止输入框过大
        idField.setFont(new Font("Arial", Font.PLAIN, 14));

        JButton generateButton = new JButton("生成6位密码");
        generateButton.setAlignmentX(Component.CENTER_ALIGNMENT);

        JLabel passwordLabel = new JLabel("生成的密码:");
        passwordLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

        JTextField passwordField = new JTextField(10);
        passwordField.setMaximumSize(passwordField.getPreferredSize());
        passwordField.setEditable(false); // 设置为不可编辑
        passwordField.setFont(new Font("Arial", Font.BOLD, 18));
        passwordField.setHorizontalAlignment(JTextField.CENTER);
        passwordField.setForeground(Color.BLUE);
        passwordField.setBackground(Color.WHITE);

        // --- 按钮点击事件处理 ---
        generateButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String deviceId = idField.getText();
                if (deviceId == null || deviceId.trim().isEmpty()) {
                    JOptionPane.showMessageDialog(frame, "请输入设备ID!", "输入为空", JOptionPane.WARNING_MESSAGE);
                    return;
                }
                try {
                    String password = CryptoUtils.generatePassword(deviceId);
                    passwordField.setText(password);
                } catch (Exception ex) {
                    ex.printStackTrace();
                    JOptionPane.showMessageDialog(frame, "生成密码时发生错误:\n" + ex.getMessage(), "加密错误", JOptionPane.ERROR_MESSAGE);
                }
            }
        });

        // --- 将控件添加到面板 ---
        panel.add(idLabel);
        panel.add(Box.createRigidArea(new Dimension(0, 5))); // 添加间距
        panel.add(idField);
        panel.add(Box.createRigidArea(new Dimension(0, 10)));
        panel.add(generateButton);
        panel.add(Box.createRigidArea(new Dimension(0, 10)));
        panel.add(passwordLabel);
        panel.add(Box.createRigidArea(new Dimension(0, 5)));
        panel.add(passwordField);

        // --- 将面板添加到窗口并显示 ---
        frame.getContentPane().add(panel);
        frame.setVisible(true);
    }
}

2.3 将Java项目编译成一个可执行的.jar文件

现在你有两个.java文件了。我们需要将它们编译并打包。

1. 环境准备:确保你已经安装了 JDK (Java Development Kit),而不是只有JRE。
2. 打开命令行:进入你保存 CryptoUtils.javaPasswordGeneratorApp.java 这两个文件的目录。
3. 编译 .java 文件:

javac CryptoUtils.java PasswordGeneratorApp.java

执行后,目录下会生成 CryptoUtils.classPasswordGeneratorApp.class 两个文件。

4. 创建清单文件 (Manifest):
创建一个名为 manifest.txt 的文本文件,内容只有一行,并且文件末尾必须有一个换行

Main-Class: PasswordGeneratorApp

这个文件告诉Java哪个类是程序的入口(包含main方法)。

5. 打包成.jar文件:

jar cfm PasswordGenerator.jar manifest.txt *.class
  • c - 创建新的归档文件
  • f - 指定归档文件名 (PasswordGenerator.jar)
  • m - 包含指定清单文件中的信息 (manifest.txt)

6. 测试.jar文件:
现在你可以直接运行这个jar包来测试你的GUI应用:

java -jar PasswordGenerator.jar

如果窗口正常弹出并且功能正常,说明.jar文件制作成功!

在这里插入图片描述

2.4 使用工具exe4j将.jar文件打包成exe文件

可以使用JDK 16及以后版本自带的官方工具 jpackage,可使用命令:"C:\Users\Administrator\.jdks\ms-17.0.15\bin\jpackage.exe" --input . --name PasswordGenerator --main-jar PasswordGenerator.jar --main-class PasswordGeneratorApp --type app-image

我们这里使用 exe4j,下载地址:https://exe4j.apponic.com/download/,下载并完成安装 exe4j,打开 exe4j 软件,在欢迎界面,直接点击next,选择 JAR in EXE mode

在这里插入图片描述

设置项目名称,以及导出路径

在这里插入图片描述

配置程序运行相关的参数,在 java invocation 界面我们可以导入上面生成的 PasswordGenerator.jar 包,Main Class form 中选择主类

在这里插入图片描述

配置 java 版本

在这里插入图片描述

配置 jre 地址,首先点击右侧的X按钮来删除默认的三个地址,我们将本机系统中的jre文件夹复制到我们输出exe文件的文件夹,选择本机的 jre 目录

在这里插入图片描述

再执行 Compile executable,生成 EXE 文件,最后运行 EXE 程序查看效果,此时的 EXE 文件是自带 java 环境的,可以在任何 Windows 电脑上直接运行

在这里插入图片描述

如果 exe4j 没有注册,在运行有exe4j转换的*.exe的可执行文件是会提示:this executable was created with an evaluation version exe4j!,解决方案注册即可,可参考 exe4j 注册,上面的打包 exe 教程可参考 exe4j 打包 exe

三、总结

Java Swing 是一个成熟且功能丰富的 GUI 工具包,适合开发跨平台的桌面应用程序。通过其丰富的组件、灵活的布局管理和强大的事件处理机制,开发者可以构建出美观且交互性强的用户界面。尽管如今有更多现代 GUI 技术出现,如更现代的 GUI 框架 JavaFX,Swing 仍在许多遗留系统和需要稳定跨平台支持的场景中广泛应用。

相关参考:
https://www.runoob.com/w3cnote/java-swing-demo-intro.html
https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/swing/package-summary.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值