| | |
| | | package home; |
| | | |
| | | import javax.swing.JOptionPane; |
| | | import javax.swing.SwingUtilities; |
| | | import javax.swing.UIManager; |
| | |
| | | import chushihua.Chushihua; |
| | | import chushihua.SlotManager; |
| | | import chushihua.lunxun; |
| | | import chushihua.lunxunzaixian; |
| | | 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 { |
| | | // 设置系统外观 |
| | |
| | | "系统初始化失败,无法启动应用程序", |
| | | "错误", |
| | | JOptionPane.ERROR_MESSAGE); |
| | | cleanupSingleInstanceLock(); |
| | | System.exit(1); |
| | | } |
| | | |
| | |
| | | "程序启动失败: " + 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()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | private static boolean initializeSlotManager() { |
| | | try { |
| | | // SlotManager 会在构造函数中自动初始化所有卡槽 |
| | | SlotManager slotManager = new SlotManager(); |
| | | new SlotManager(); |
| | | //System.out.println("✓ 卡槽管理器初始化成功"); |
| | | //System.out.println(" 总卡槽数: " + slotManager.getTotalSlots()); |
| | | |
| | |
| | | |
| | | if (serialConnected) { |
| | | // 4. 串口连接成功后,启动轮询 |
| | | boolean pollingStarted = startPollingService(); |
| | | startPollingService(); |
| | | showMainInterface(); |
| | | lunxunkazhuangtai.startPolling();//启动卡状态轮询发给服务器 |
| | | |
| | | if (pollingStarted) { |
| | | showMainInterface(); |
| | | //启动轮询卡状态给服务器发数据 |
| | | lunxunkazhuangtai.startPolling(); |
| | | //启动在线的卡状态轮询 |
| | | lunxunzaixian.startOnlinePolling(); |
| | | } else { |
| | | System.err.println("轮询服务启动失败"); |
| | | JOptionPane.showMessageDialog(null, |
| | | "轮询服务启动失败,应用程序无法正常运行", |
| | | "警告", |
| | | JOptionPane.WARNING_MESSAGE); |
| | | } |
| | | |
| | | } else { |
| | | System.err.println("串口连接失败"); |
| | | // 串口连接失败已经由SerialPortConnectionDialog处理,直接退出 |
| | | cleanupSingleInstanceLock(); |
| | | System.exit(0); |
| | | } |
| | | |
| | |
| | | "应用程序启动过程中发生错误: " + e.getMessage(), |
| | | "错误", |
| | | JOptionPane.ERROR_MESSAGE); |
| | | cleanupSingleInstanceLock(); |
| | | System.exit(1); |
| | | } |
| | | } |
| | |
| | | mainUI.dispose(); |
| | | } |
| | | |
| | | // 清理单实例锁 - 确保在关闭钩子中也调用 |
| | | cleanupSingleInstanceLock(); |
| | | |
| | | //System.out.println("应用程序关闭完成"); |
| | | |
| | | } catch (Exception e) { |