张世豪
21 小时以前 0f1509097818fbf48d7741d0fe0d9b973e88730d
src/home/Homein.java
@@ -1,5 +1,4 @@
package home;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
@@ -7,9 +6,25 @@
import chushihua.Chushihua;
import chushihua.SlotManager;
import chushihua.lunxun;
import dialog.Dingshidialog;
import jiekou.lunxunkazhuangtai;
import java.io.IOException;
import java.net.ServerSocket;
public class Homein {
    // 单实例锁的端口号,选择一个不常用的端口
    private static final int SINGLE_INSTANCE_PORT = 9999;
    private static ServerSocket singleInstanceSocket;
    public static void main(String[] args) {
        // 检查是否已有实例在运行
        if (!checkSingleInstance()) {
            Dingshidialog.showTimedDialog(null,5, "软件已经在运行中,不能重复打开!");
            System.exit(0);
            return;
        }
        SwingUtilities.invokeLater(() -> {
            try {
                // 设置系统外观
@@ -27,6 +42,7 @@
                        "系统初始化失败,无法启动应用程序", 
                        "错误", 
                        JOptionPane.ERROR_MESSAGE);
                    cleanupSingleInstanceLock();
                    System.exit(1);
                }
                
@@ -36,9 +52,50 @@
                    "程序启动失败: " + e.getMessage(), 
                    "错误", 
                    JOptionPane.ERROR_MESSAGE);
                cleanupSingleInstanceLock();
                System.exit(1);
            }
        });        
    }
    /**
     * 检查是否单实例运行
     * @return 如果是唯一实例返回true,如果已有实例运行返回false
     */
    private static boolean checkSingleInstance() {
        try {
            // 尝试绑定到指定端口,如果成功说明是第一个实例
            singleInstanceSocket = new ServerSocket(SINGLE_INSTANCE_PORT);
            return true;
        } catch (IOException e) {
            // 端口已被占用,说明已有实例在运行
            return false;
        }
    }
    /**
     * 清理单实例锁 - 改为公共静态方法以便外部调用
     */
    public static void cleanupSingleInstanceLock() {
        if (singleInstanceSocket != null && !singleInstanceSocket.isClosed()) {
            try {
                singleInstanceSocket.close();
                //System.out.println("单实例锁已清理");
            } catch (IOException e) {
                System.err.println("关闭单实例锁时发生异常: " + e.getMessage());
            } finally {
                singleInstanceSocket = null;
            }
        }
        // 额外确保:尝试再次绑定端口来确认是否已释放
        try {
            ServerSocket testSocket = new ServerSocket(SINGLE_INSTANCE_PORT);
            testSocket.close();
            //System.out.println("端口确认已释放");
        } catch (IOException e) {
            System.err.println("端口可能仍被占用: " + e.getMessage());
        }
    }
    
    /**
@@ -47,23 +104,23 @@
     */
    private static boolean initializeSystem() {
        try {
            System.out.println("开始系统初始化流程...");
            //System.out.println("开始系统初始化流程...");
            
            // 1. 运行系统初始化类 Chushihua
            System.out.println("步骤1: 初始化系统配置...");
            //System.out.println("步骤1: 初始化系统配置...");
            if (!initializeChushihua()) {
                System.err.println("系统配置初始化失败");
                return false;
            }
            
            // 2. 初始化 SlotManager 类
            System.out.println("步骤2: 初始化卡槽管理器...");
            //System.out.println("步骤2: 初始化卡槽管理器...");
            if (!initializeSlotManager()) {
                System.err.println("卡槽管理器初始化失败");
                return false;
            }
            
            System.out.println("系统初始化完成");
            //System.out.println("系统初始化完成");
            return true;
            
        } catch (Exception e) {
@@ -82,11 +139,11 @@
            boolean success = configSystem.initialize();
            
            if (success) {
                System.out.println("✓ 系统配置初始化成功");
                System.out.println("  设备编号: " + configSystem.getMachineConfig().getMachineId());
                System.out.println("  卡槽总数: " + configSystem.getMachineConfig().getTotalSlots());
                System.out.println("  轮询间隔: " + configSystem.getMachineConfig().getPollingInterval() + "ms");
                System.out.println("  波特率: " + configSystem.getMachineConfig().getBaudrate());
                //System.out.println("✓ 系统配置初始化成功");
                //System.out.println("  设备编号: " + configSystem.getMachineConfig().getMachineId());
                //System.out.println("  卡槽总数: " + configSystem.getMachineConfig().getTotalSlots());
                //System.out.println("  轮询间隔: " + configSystem.getMachineConfig().getPollingInterval() + "ms");
                //System.out.println("  波特率: " + configSystem.getMachineConfig().getBaudrate());
            } else {
                System.err.println("✗ 系统配置初始化失败");
            }
@@ -105,9 +162,9 @@
    private static boolean initializeSlotManager() {
        try {
            // SlotManager 会在构造函数中自动初始化所有卡槽
            SlotManager slotManager = new SlotManager();
            System.out.println("✓ 卡槽管理器初始化成功");
            System.out.println("  总卡槽数: " + slotManager.getTotalSlots());
            new SlotManager();
            //System.out.println("✓ 卡槽管理器初始化成功");
            //System.out.println("  总卡槽数: " + slotManager.getTotalSlots());
            
            return true;
            
@@ -121,32 +178,21 @@
     * 启动应用程序主流程
     */
    private static void startApplication() {
        try {
            System.out.println("开始应用程序主流程...");
        try {
            // 3. 运行串口连接对话框,等待串口连接成功
            System.out.println("步骤3: 启动串口连接...");
            boolean serialConnected = initializeSerialPort();
            
            if (serialConnected) {
                // 4. 串口连接成功后,启动轮询
                System.out.println("步骤4: 启动轮询查询...");
                boolean pollingStarted = startPollingService();
                startPollingService();
                showMainInterface();
                lunxunkazhuangtai.startPolling();//启动卡状态轮询发给服务器
                
                if (pollingStarted) {
                    // 5. 进入主界面
                    System.out.println("步骤5: 启动主界面...");
                    showMainInterface();
                } else {
                    System.err.println("轮询服务启动失败");
                    JOptionPane.showMessageDialog(null,
                        "轮询服务启动失败,应用程序无法正常运行",
                        "警告",
                        JOptionPane.WARNING_MESSAGE);
                }
            } else {
                System.err.println("串口连接失败");
                // 串口连接失败已经由SerialPortConnectionDialog处理,直接退出
                cleanupSingleInstanceLock();
                System.exit(0);
            }
            
@@ -157,6 +203,7 @@
                "应用程序启动过程中发生错误: " + e.getMessage(), 
                "错误", 
                JOptionPane.ERROR_MESSAGE);
            cleanupSingleInstanceLock();
            System.exit(1);
        }
    }
@@ -166,17 +213,17 @@
     */
    private static boolean initializeSerialPort() {
        try {
            System.out.println("正在打开串口连接对话框...");
            //System.out.println("正在打开串口连接对话框...");
            
            // 显示串口连接对话框(模态对话框,会阻塞直到用户操作)
            // 用户必须点击"连接串口"按钮才会实际连接
            boolean connected = SerialPortConnectionDialog.showConnectionDialog(null);
            
            if (connected) {
                System.out.println("✓ 串口连接成功");
                //System.out.println("✓ 串口连接成功");
                return true;
            } else {
                System.out.println("✗ 串口连接失败或用户取消");
                //System.out.println("✗ 串口连接失败或用户取消");
                // 添加详细错误信息
                JOptionPane.showMessageDialog(null, 
                    "串口连接失败,请检查串口设备是否可用", 
@@ -211,7 +258,7 @@
            boolean started = lunxun.startPolling();
            
            if (started) {
                System.out.println("✓ 轮询查询启动成功");
                //System.out.println("✓ 轮询查询启动成功");
                return true;
            } else {
                System.err.println("✗ 轮询查询启动失败");
@@ -229,11 +276,11 @@
     */
    private static void showMainInterface() {
        try {
            System.out.println("正在创建主界面...");
            //System.out.println("正在创建主界面...");
            
            // 确保轮询服务已启动
            if (!lunxun.isPolling()) {
                System.out.println("启动轮询服务...");
                //System.out.println("启动轮询服务...");
                startPollingService();
            }
            
@@ -241,8 +288,8 @@
            CardMachineUI mainUI = new CardMachineUI();
            mainUI.setVisible(true);
            
            System.out.println("✓ 主界面启动成功");
            System.out.println("应用程序启动完成,进入正常运行状态");
            //System.out.println("✓ 主界面启动成功");
            //System.out.println("应用程序启动完成,进入正常运行状态");
            
            // 添加关闭钩子,确保应用程序退出时正确清理资源
            addShutdownHook(mainUI);
@@ -263,26 +310,29 @@
     */
    private static void addShutdownHook(CardMachineUI mainUI) {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("应用程序正在关闭,执行清理操作...");
            //System.out.println("应用程序正在关闭,执行清理操作...");
            
            try {
                // 停止轮询查询
                if (lunxun.isPolling()) {
                    System.out.println("停止轮询查询...");
                    //System.out.println("停止轮询查询...");
                    lunxun.stopPolling();
                }
                
                // 关闭系统配置
                System.out.println("关闭系统配置...");
                //System.out.println("关闭系统配置...");
                Chushihua.getInstance().shutdown();
                
                // 关闭主界面资源
                if (mainUI != null) {
                    System.out.println("关闭主界面资源...");
                    //System.out.println("关闭主界面资源...");
                    mainUI.dispose();
                }
                
                System.out.println("应用程序关闭完成");
                // 清理单实例锁 - 确保在关闭钩子中也调用
                cleanupSingleInstanceLock();
                //System.out.println("应用程序关闭完成");
                
            } catch (Exception e) {
                System.err.println("应用程序关闭过程中发生异常: " + e.getMessage());