From 176cfa1a137d2050d4e8a105dfdbdc8f1b32afb2 Mon Sep 17 00:00:00 2001
From: 826220679@qq.com <826220679@qq.com>
Date: 星期日, 10 八月 2025 23:04:55 +0800
Subject: [PATCH] 修改

---
 src/dell_system/SerialPacketParser.java |    8 
 src/dell_system/SerialCommPanel.java    |    4 
 src/dell_system/MessageViewPanel.java   |  600 +++++++++++++++++++++--------------------------------
 3 files changed, 245 insertions(+), 367 deletions(-)

diff --git a/src/dell_system/MessageViewPanel.java b/src/dell_system/MessageViewPanel.java
index 3dcb4a2..7d090dd 100644
--- a/src/dell_system/MessageViewPanel.java
+++ b/src/dell_system/MessageViewPanel.java
@@ -16,50 +16,46 @@
 import udptcp.UDPPortBReceiver;
 
 public class MessageViewPanel extends JPanel {
-    /**
-     * 
-     */
     private static final long serialVersionUID = 1L;
 
-    private ResourceBundle messages;   // 国际化消息资源包
-
-    // UI组件声明
-    private JButton btnStart, btnPause, btnClear, btnSend; // 控制按钮:开始、暂停、清除、发送
-    private static JComboBox<String> cbDataType; // 下拉框:数据类型、协议、设备ID
+    private ResourceBundle messages;
+    private JButton btnStart, btnPause, btnClear, btnSend;
+    private static JComboBox<String> cbDataType;
     private static JComboBox<String> cbProtocol;
     private static JComboBox<String> cbDeviceId;
-    private static JComboBox<String> cbRemoteDevice; // 远程设备下拉框
-    private static JCheckBox chkAutoSave; // 复选框:自动保存、显示来源、十六进制显示、ASCII显示
+    private static JComboBox<String> cbRemoteDevice;
+    private static JCheckBox chkAutoSave;
     private static JCheckBox chkShowSource;
-    private static JCheckBox chkHexDisplay;
-    private static JCheckBox chkAsciiDisplay;
-    private static JTextArea txtDataView; // 数据显示区域
-    private JScrollPane scrollPane; // 带滚动条的面板
-    private JTextField txtSendData; // 发送数据文本框
-    private JRadioButton rdoSendHex; // HEX发送单选按钮
-    private JRadioButton rdoSendAscii; // ASCII发送单选按钮
-    private JCheckBox chkAppendNewline; // 回车换行复选框
-    // 添加静态变量跟踪窗口可见状态
+    private static JTextArea txtDataView;
+    private JScrollPane scrollPane;
+    private JTextField txtSendData;
+    private JRadioButton rdoSendHex;
+    private JRadioButton rdoSendAscii;
+    private JCheckBox chkAppendNewline;
+    
+    private static final ThreadLocal<StringBuilder> SB =
+            ThreadLocal.withInitial(() -> new StringBuilder(256));
+    private static final char[] DIGITS = "0123456789".toCharArray();
+    private static final String COLON = ":";
+    private static final String PREFIX = "[";
+    private static final String SUFFIX = "]";
+    
     public static volatile boolean isWindowVisible = false;
-    // 状态变量
-    private static boolean isCapturing = false; // 是否正在捕获数据的标志
-
-    // 修改为Map存储设备及其本地端口
+    private static boolean isCapturing = false;
+    private static boolean isStarted = false; // 新增:跟踪开始按钮状态
+    
     private static Map<String, Integer> remoteDeviceLocalPortMap = new HashMap<>();
-    // 构造函数
-    public MessageViewPanel(ResourceBundle messages) {       
-        this.messages = messages; // 初始化消息资源包        
-        initializeUI(); // 初始化用户界面
-    }
 
-   
- 
+    public MessageViewPanel(ResourceBundle messages) {
+        this.messages = messages;
+        initializeUI();
+    }
 
     public void addNotify() {
         super.addNotify();
         Window window = SwingUtilities.getWindowAncestor(this);
         if (window != null) {
-            isWindowVisible = true; // 面板已添加到可见窗口
+            isWindowVisible = true;
             window.addWindowListener(new WindowAdapter() {
                 @Override
                 public void windowClosing(WindowEvent e) {
@@ -74,154 +70,129 @@
         }
     }
 
-    // 初始化UI组件
     private void initializeUI() {
-        setLayout(new GridBagLayout()); // 使用网格袋布局
-        GridBagConstraints gbc = new GridBagConstraints(); // 布局约束对象
-        gbc.insets = new Insets(5, 10, 5, 10); // 设置组件间距(上、左、下、右)
-        gbc.anchor = GridBagConstraints.WEST; // 组件靠左对齐
-        gbc.fill = GridBagConstraints.HORIZONTAL; // 水平填充
-        setBackground(new Color(240, 245, 249)); // 设置背景色
+        setLayout(new GridBagLayout());
+        GridBagConstraints gbc = new GridBagConstraints();
+        gbc.insets = new Insets(5, 10, 5, 10);
+        gbc.anchor = GridBagConstraints.WEST;
+        gbc.fill = GridBagConstraints.HORIZONTAL;
+        setBackground(new Color(240, 245, 249));
 
         // 下拉框区域
-        gbc.gridx = 0; // 起始列
-        gbc.gridy = 0; // 起始行
-        gbc.gridwidth = 1; // 占用1列宽度
-        gbc.weightx = 0.25; // 水平权重
+        gbc.gridx = 0;
+        gbc.gridy = 0;
+        gbc.gridwidth = 1;
+        gbc.weightx = 0.25;
 
-        // 数据类型下拉框面板
-        JPanel dataTypePanel = new JPanel(new BorderLayout(5, 0)); // 使用边界布局
-        dataTypePanel.setBackground(new Color(240, 245, 249)); // 设置背景色
-        dataTypePanel.add(createLabel(messages.getString("MESSAGE_VIEW_DATA_TYPE")), BorderLayout.WEST); // 添加标签
-        cbDataType = new JComboBox<>(); // 创建下拉框
-        loadtyps();// 添加"所有类型"选项       
-        dataTypePanel.add(cbDataType, BorderLayout.CENTER); // 将下拉框添加到面板中央
-        add(dataTypePanel, gbc); // 将面板添加到主面板
+        JPanel dataTypePanel = new JPanel(new BorderLayout(5, 0));
+        dataTypePanel.setBackground(new Color(240, 245, 249));
+        dataTypePanel.add(createLabel(messages.getString("MESSAGE_VIEW_DATA_TYPE")), BorderLayout.WEST);
+        cbDataType = new JComboBox<>();
+        loadtyps();
+        dataTypePanel.add(cbDataType, BorderLayout.CENTER);
+        add(dataTypePanel, gbc);
 
-        // 协议下拉框
-        gbc.gridx++; // 移动到下一列
-        JPanel protocolPanel = new JPanel(new BorderLayout(5, 0)); // 协议选择面板
-        protocolPanel.setBackground(new Color(240, 245, 249)); // 设置背景色
-        protocolPanel.add(createLabel(messages.getString("MESSAGE_VIEW_PROTOCOL")), BorderLayout.WEST); // 添加协议标签
-        cbProtocol = new JComboBox<>(new String[]{ // 创建协议下拉框并初始化选项
-                messages.getString("MESSAGE_VIEW_ALL_PROTOCOLS"), // 所有协议
-                "UDP", // UDP协议
-                "TCP", // TCP协议
-                "MQTT", // MQTT协议
-                "HTTP" // HTTP协议
+        gbc.gridx++;
+        JPanel protocolPanel = new JPanel(new BorderLayout(5, 0));
+        protocolPanel.setBackground(new Color(240, 245, 249));
+        protocolPanel.add(createLabel(messages.getString("MESSAGE_VIEW_PROTOCOL")), BorderLayout.WEST);
+        cbProtocol = new JComboBox<>(new String[]{
+                "ALL", 
+                "55AA01", "55AA02", "55AA03", "55AA05", "55AA07", 
+                "55AA0A", "55AA0C", "55AA12", "55AA14", "55AA20",
+                "GNGGA", "XTB"
         });
-        protocolPanel.add(cbProtocol, BorderLayout.CENTER); // 将下拉框添加到面板中央
-        add(protocolPanel, gbc); // 将面板添加到主面板
+        protocolPanel.add(cbProtocol, BorderLayout.CENTER);
+        add(protocolPanel, gbc);
 
-        // 设备ID下拉框
-        gbc.gridx++; // 移动到下一列
-        JPanel devicePanel = new JPanel(new BorderLayout(5, 0)); // 设备ID选择面板
-        devicePanel.setBackground(new Color(240, 245, 249)); // 设置背景色
-        devicePanel.add(createLabel(messages.getString("MESSAGE_VIEW_DEVICE_ID")), BorderLayout.WEST); // 添加设备ID标签
-        cbDeviceId = new JComboBox<>(); // 创建设备ID下拉框
-        cbDeviceId.setEditable(true); // 设置为可编辑,允许手动输入设备ID
-        cbDeviceId.addItem(messages.getString("MESSAGE_VIEW_ALL_DEVICES")); // 添加"所有设备"选项
-        loadDeviceIds(); // 加载设备ID列表
-        devicePanel.add(cbDeviceId, BorderLayout.CENTER); // 将下拉框添加到面板中央
-        add(devicePanel, gbc); // 将面板添加到主面板
+        gbc.gridx++;
+        JPanel devicePanel = new JPanel(new BorderLayout(5, 0));
+        devicePanel.setBackground(new Color(240, 245, 249));
+        devicePanel.add(createLabel(messages.getString("MESSAGE_VIEW_DEVICE_ID")), BorderLayout.WEST);
+        cbDeviceId = new JComboBox<>();
+        cbDeviceId.setEditable(true);
+        cbDeviceId.addItem("ALL");
+        loadDeviceIds();
+        devicePanel.add(cbDeviceId, BorderLayout.CENTER);
+        add(devicePanel, gbc);
 
-        // 远程设备下拉框
-        gbc.gridx++; // 移动到下一列
-        JPanel remoteDevicePanel = new JPanel(new BorderLayout(5, 0)); // 远程设备选择面板
-        remoteDevicePanel.setBackground(new Color(240, 245, 249)); // 设置背景色
-        remoteDevicePanel.add(createLabel(messages.getString("MESSAGE_VIEW_REMOTE_DEVICE")), BorderLayout.WEST); // 添加远程设备标签
-        cbRemoteDevice = new JComboBox<>(); // 创建远程设备下拉框
-        cbRemoteDevice.setEditable(true); // 设置为可编辑
-        cbRemoteDevice.addItem(messages.getString("MESSAGE_VIEW_ALL_DEVICES")); // 添加"所有设备"选项
-        remoteDevicePanel.add(cbRemoteDevice, BorderLayout.CENTER); // 将下拉框添加到面板中央
-        add(remoteDevicePanel, gbc); // 将面板添加到主面板
+        gbc.gridx++;
+        JPanel remoteDevicePanel = new JPanel(new BorderLayout(5, 0));
+        remoteDevicePanel.setBackground(new Color(240, 245, 249));
+        remoteDevicePanel.add(createLabel(messages.getString("MESSAGE_VIEW_REMOTE_DEVICE")), BorderLayout.WEST);
+        cbRemoteDevice = new JComboBox<>();
+        cbRemoteDevice.setEditable(true);
+        cbRemoteDevice.addItem(messages.getString("MESSAGE_VIEW_ALL_DEVICES"));
+        remoteDevicePanel.add(cbRemoteDevice, BorderLayout.CENTER);
+        add(remoteDevicePanel, gbc);
 
-        // 复选框区域
-        gbc.gridx = 0; // 重置列位置
-        gbc.gridy++; // 移动到下一行
-        gbc.gridwidth = 4; // 横跨4列
-        gbc.weightx = 1.0; // 水平权重
+        // 复选框区域 - 简化为两个复选框
+        gbc.gridx = 0;
+        gbc.gridy++;
+        gbc.gridwidth = 4;
+        gbc.weightx = 1.0;
 
-        JPanel checkboxPanel = new JPanel(new GridLayout(1, 4, 6, 0)); // 创建网格布局面板(1行4列)
-        checkboxPanel.setBackground(new Color(240, 245, 249)); // 设置背景色
-        chkAutoSave = createStyledCheckbox(messages.getString("MESSAGE_VIEW_AUTO_SAVE")); // 创建自动保存复选框
-        chkShowSource = createStyledCheckbox(messages.getString("MESSAGE_VIEW_SHOW_SOURCE")); // 创建显示来源复选框
-        chkHexDisplay = createStyledCheckbox(messages.getString("MESSAGE_VIEW_HEX_DISPLAY")); // 创建十六进制显示复选框
-        chkAsciiDisplay = createStyledCheckbox(messages.getString("MESSAGE_VIEW_ASCII_DISPLAY")); // 创建ASCII显示复选框
-
-        // 将复选框添加到面板
+        JPanel checkboxPanel = new JPanel(new GridLayout(1, 2, 6, 0)); // 修改为2列
+        checkboxPanel.setBackground(new Color(240, 245, 249));
+        chkAutoSave = createStyledCheckbox(messages.getString("MESSAGE_VIEW_AUTO_SAVE"));
+        chkShowSource = createStyledCheckbox(messages.getString("MESSAGE_VIEW_SHOW_SOURCE"));
+        
+        // 移除了十六进制和ASCII显示复选框
         checkboxPanel.add(chkAutoSave);
         checkboxPanel.add(chkShowSource);
-        checkboxPanel.add(chkHexDisplay);
-        checkboxPanel.add(chkAsciiDisplay);
 
-        add(checkboxPanel, gbc); // 将复选框面板添加到主面板
+        add(checkboxPanel, gbc);
 
         // 数据显示区域
-        gbc.gridy++; // 移动到下一行
-        gbc.weighty = 1.0; // 垂直权重
-        gbc.fill = GridBagConstraints.BOTH; // 双向填充
+        gbc.gridy++;
+        gbc.weighty = 1.0;
+        gbc.fill = GridBagConstraints.BOTH;
 
-        txtDataView = new JTextArea(); // 创建文本区域
-        txtDataView.setFont(new Font("Monospaced", Font.PLAIN, 14)); // 设置等宽字体
-        txtDataView.setEditable(false); // 设置为不可编辑
-        scrollPane = new JScrollPane(txtDataView); // 创建带滚动条的面板
+        txtDataView = new JTextArea();
+        txtDataView.setFont(new Font("Monospaced", Font.PLAIN, 14));
+        txtDataView.setEditable(false);
+        scrollPane = new JScrollPane(txtDataView);
         scrollPane.setPreferredSize(new Dimension(800, 400));
-        scrollPane.setBorder(BorderFactory.createTitledBorder( // 设置带标题的边框
-                BorderFactory.createLineBorder(new Color(180, 180, 220)), // 边框颜色
-                messages.getString("MESSAGE_VIEW_DATA_PANEL"), // 标题文本
-                TitledBorder.LEFT, // 标题位置
-                TitledBorder.TOP, // 标题位置
-                new Font("微软雅黑", Font.BOLD, 12), // 标题字体
-                new Color(70, 130, 180) // 标题颜色
-                ));
+        scrollPane.setBorder(BorderFactory.createTitledBorder(
+                BorderFactory.createLineBorder(new Color(180, 180, 220)),
+                messages.getString("MESSAGE_VIEW_DATA_PANEL"),
+                TitledBorder.LEFT,
+                TitledBorder.TOP,
+                new Font("微软雅黑", Font.BOLD, 12),
+                new Color(70, 130, 180)
+        ));
 
-        add(scrollPane, gbc); // 将滚动面板添加到主面板
+        add(scrollPane, gbc);
 
         // 按钮面板区域
-        gbc.gridy++; // 移动到下一行
-        gbc.weighty = 0; // 重置垂直权重
-        gbc.fill = GridBagConstraints.HORIZONTAL; // 水平填充
+        gbc.gridy++;
+        gbc.weighty = 0;
+        gbc.fill = GridBagConstraints.HORIZONTAL;
 
-        // 按钮面板
-        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5)); // 使用流式布局(左对齐)
-        buttonPanel.setBackground(new Color(240, 245, 249)); // 设置背景色
-        btnStart = createStyledButton(messages.getString("MESSAGE_VIEW_START"), new Color(70, 130, 180)); // 创建开始按钮(蓝色)
-        btnPause = createStyledButton(messages.getString("MESSAGE_VIEW_PAUSE"), new Color(218, 165, 32)); // 创建暂停按钮(金色)
-        btnClear = createStyledButton(messages.getString("MESSAGE_VIEW_CLEAR"), new Color(205, 92, 92)); // 创建清除按钮(红色)
+        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
+        buttonPanel.setBackground(new Color(240, 245, 249));
+        btnStart = createStyledButton(messages.getString("MESSAGE_VIEW_START"), new Color(70, 130, 180));
+        btnPause = createStyledButton(messages.getString("MESSAGE_VIEW_PAUSE"), new Color(218, 165, 32));
+        btnClear = createStyledButton(messages.getString("MESSAGE_VIEW_CLEAR"), new Color(205, 92, 92));
 
-        // 发送相关控件
-        txtSendData = new JTextField(30); // 发送数据文本框
-        txtSendData.setFont(new Font("微软雅黑", Font.PLAIN, 12)); // 设置字体
-        btnSend = createStyledButton(messages.getString("MESSAGE_VIEW_SEND"), new Color(60, 179, 113)); // 创建发送按钮(绿色)
+        txtSendData = new JTextField(30);
+        txtSendData.setFont(new Font("微软雅黑", Font.PLAIN, 12));
+        btnSend = createStyledButton(messages.getString("MESSAGE_VIEW_SEND"), new Color(60, 179, 113));
 
-        // 创建发送选项面板
         JPanel sendOptionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
         sendOptionsPanel.setBackground(new Color(240, 245, 249));
-
-        // 创建单选按钮组
         ButtonGroup sendFormatGroup = new ButtonGroup();
-
-        // 创建HEX发送单选按钮
         rdoSendHex = createStyledRadioButton(messages.getString("MESSAGE_VIEW_SEND_HEX"));
-        // 创建ASCII发送单选按钮
         rdoSendAscii = createStyledRadioButton(messages.getString("MESSAGE_VIEW_SEND_ASCII"));
-
-        // 将单选按钮添加到按钮组
         sendFormatGroup.add(rdoSendHex);
         sendFormatGroup.add(rdoSendAscii);
-
-        // 默认选中ASCII发送
         rdoSendAscii.setSelected(true);
-
-        // 回车换行复选框
         chkAppendNewline = createStyledCheckbox(messages.getString("MESSAGE_VIEW_APPEND_NEWLINE"));
 
         sendOptionsPanel.add(rdoSendHex);
         sendOptionsPanel.add(rdoSendAscii);
         sendOptionsPanel.add(chkAppendNewline);
 
-        // 将按钮添加到按钮面板
         buttonPanel.add(btnStart);
         buttonPanel.add(btnPause);
         buttonPanel.add(btnClear);
@@ -229,55 +200,46 @@
         buttonPanel.add(btnSend);
         buttonPanel.add(sendOptionsPanel);
 
-        add(buttonPanel, gbc); // 将按钮面板添加到主面板
+        add(buttonPanel, gbc);
 
-        // 设置按钮动作
         setupActions();
     }
 
-    // 创建带样式的标签
     private JLabel createLabel(String text) {
-        JLabel label = new JLabel(text); // 创建标签
-        label.setFont(new Font("微软雅黑", Font.BOLD, 12)); // 设置字体
-        label.setForeground(new Color(70, 70, 70)); // 设置前景色
+        JLabel label = new JLabel(text);
+        label.setFont(new Font("微软雅黑", Font.BOLD, 12));
+        label.setForeground(new Color(70, 70, 70));
         return label;
     }
 
-    // 创建带样式的按钮
     private JButton createStyledButton(String text, Color bgColor) {
-        JButton button = new JButton(text); // 创建按钮
-        button.setFont(new Font("微软雅黑", Font.BOLD, 12)); // 设置字体
-        button.setBackground(bgColor); // 设置背景色
-        button.setForeground(Color.WHITE); // 设置前景色(白色)
-        button.setFocusPainted(false); // 禁用焦点边框
-        button.setBorder(BorderFactory.createCompoundBorder( // 设置复合边框
-                BorderFactory.createLineBorder(bgColor.darker(), 1), // 外部边框(深色)
-                BorderFactory.createEmptyBorder(5, 15, 5, 15) // 内部边距
-                ));
+        JButton button = new JButton(text);
+        button.setFont(new Font("微软雅黑", Font.BOLD, 12));
+        button.setBackground(bgColor);
+        button.setForeground(Color.WHITE);
+        button.setFocusPainted(false);
+        button.setBorder(BorderFactory.createCompoundBorder(
+                BorderFactory.createLineBorder(bgColor.darker(), 1),
+                BorderFactory.createEmptyBorder(5, 15, 5, 15)
+        ));
         return button;
     }
 
-    // 创建带样式的复选框
     private JCheckBox createStyledCheckbox(String text) {
-        JCheckBox checkBox = new JCheckBox(text); // 创建复选框
-        checkBox.setFont(new Font("微软雅黑", Font.PLAIN, 12)); // 设置字体
-        checkBox.setBackground(new Color(240, 245, 249)); // 设置背景色
-        checkBox.setForeground(new Color(70, 70, 70)); // 设置前景色
+        JCheckBox checkBox = new JCheckBox(text);
+        checkBox.setFont(new Font("微软雅黑", Font.PLAIN, 12));
+        checkBox.setBackground(new Color(240, 245, 249));
+        checkBox.setForeground(new Color(70, 70, 70));
         return checkBox;
     }
 
-    // 创建带样式的单选按钮
     private JRadioButton createStyledRadioButton(String text) {
-        JRadioButton radioButton = new JRadioButton(text); // 创建单选按钮
-        radioButton.setFont(new Font("微软雅黑", Font.PLAIN, 12)); // 设置字体
-        radioButton.setBackground(new Color(240, 245, 249)); // 设置背景色
-        radioButton.setForeground(new Color(70, 70, 70)); // 设置前景色
-
-        // 美化选中效果
+        JRadioButton radioButton = new JRadioButton(text);
+        radioButton.setFont(new Font("微软雅黑", Font.PLAIN, 12));
+        radioButton.setBackground(new Color(240, 245, 249));
+        radioButton.setForeground(new Color(70, 70, 70));
         radioButton.setIcon(new RadioButtonIcon(false));
         radioButton.setSelectedIcon(new RadioButtonIcon(true));
-
-        // 添加鼠标悬停效果
         radioButton.addMouseListener(new java.awt.event.MouseAdapter() {
             public void mouseEntered(java.awt.event.MouseEvent evt) {
                 radioButton.setForeground(new Color(30, 144, 255));
@@ -286,11 +248,9 @@
                 radioButton.setForeground(new Color(70, 70, 70));
             }
         });
-
         return radioButton;
     }
 
-    // 自定义单选按钮图标
     private static class RadioButtonIcon implements Icon {
         private static final int SIZE = 14;
         private final boolean selected;
@@ -305,19 +265,14 @@
             g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 
             if (selected) {
-                // 选中状态 - 蓝色填充
                 g2d.setColor(new Color(70, 130, 180));
                 g2d.fillOval(x, y, SIZE, SIZE);
-
-                // 内圆 - 白色
                 g2d.setColor(Color.WHITE);
                 g2d.fillOval(x + SIZE/4, y + SIZE/4, SIZE/2, SIZE/2);
             } else {
-                // 未选中状态 - 灰色边框
                 g2d.setColor(new Color(150, 150, 150));
                 g2d.drawOval(x, y, SIZE-1, SIZE-1);
             }
-
             g2d.dispose();
         }
 
@@ -332,77 +287,65 @@
         }
     }
 
-
-    // 加载数据类型
     private void loadtyps() {
         cbDataType.removeAllItems();
-        // 添加国际化选项
-        cbDataType.addItem(messages.getString("MESSAGE_VIEW_ALL_TYPES"));
-        cbDataType.addItem(messages.getString("MESSAGE_VIEW_UDP_PORT_A"));
-        cbDataType.addItem(messages.getString("MESSAGE_VIEW_UDP_PORT_B"));
-        cbDataType.addItem(messages.getString("MESSAGE_VIEW_TCP_PORT"));
-        cbDataType.addItem(messages.getString("MESSAGE_VIEW_MQTT_PORT"));
+        cbDataType.addItem("UDPA");
+        cbDataType.addItem("UDPB");
+        cbDataType.addItem("TCP");
     }
 
-    // 设置按钮动作
     private void setupActions() {
-        btnStart.addActionListener(e -> startCapture()); // 开始按钮绑定开始捕获方法
-        btnPause.addActionListener(e -> pauseCapture()); // 暂停按钮绑定暂停捕获方法
-        btnClear.addActionListener(e -> clearDisplay()); // 清除按钮绑定清除显示方法
-        btnSend.addActionListener(e -> sendData()); // 发送按钮绑定发送方法
+        btnStart.addActionListener(e -> startCapture());
+        btnPause.addActionListener(e -> pauseCapture());
+        btnClear.addActionListener(e -> clearDisplay());
+        btnSend.addActionListener(e -> sendData());
     }
 
-    // 开始捕获数据
     private void startCapture() {
-        if (!isCapturing) { // 如果当前未在捕获状态
-            isCapturing = true; // 设置捕获状态为true
-            btnStart.setEnabled(false); // 禁用开始按钮
-            btnPause.setEnabled(true); // 启用暂停按钮
-            // 启动数据捕获线程
+        if (!isCapturing) {
+            isStarted = true; // 设置开始标志
+            isCapturing = true;
+            btnStart.setEnabled(false);
+            btnPause.setEnabled(true);
         }
     }
 
-    // 暂停捕获数据
     private void pauseCapture() {
-        isCapturing = false; // 设置捕获状态为false
-        btnStart.setEnabled(true); // 启用开始按钮
-        btnPause.setEnabled(false); // 禁用暂停按钮
+        isStarted = false; // 清除开始标志
+        isCapturing = false;
+        btnStart.setEnabled(true);
+        btnPause.setEnabled(false);
     }
 
-    // 清除数据显示
     private void clearDisplay() {
-        txtDataView.setText(""); // 清空文本区域
+        txtDataView.setText("");
     }
 
-    // 发送数据到远程设备
     private void sendData() {
-        // 使用新方法获取当前资源包
-        ResourceBundle currentMessages = Languages.getCurrentMessages();        
+        ResourceBundle currentMessages = Languages.getCurrentMessages();
         String selectedDevice = (String) cbRemoteDevice.getSelectedItem();
         if (selectedDevice == null || selectedDevice.equals(currentMessages.getString("MESSAGE_VIEW_ALL_DEVICES"))) {
-            JOptionPane.showMessageDialog(this, 
-                    currentMessages.getString("MESSAGE_VIEW_SELECT_DEVICE"), 
-                    currentMessages.getString("WARNING"), 
+            JOptionPane.showMessageDialog(this,
+                    currentMessages.getString("MESSAGE_VIEW_SELECT_DEVICE"),
+                    currentMessages.getString("WARNING"),
                     JOptionPane.WARNING_MESSAGE);
             return;
         }
 
-        // 获取本地端口
         Integer localPort = remoteDeviceLocalPortMap.get(selectedDevice);
         if (localPort == null) {
-            JOptionPane.showMessageDialog(this, 
+            JOptionPane.showMessageDialog(this,
                     "无法确定设备的接收端口",
-                    currentMessages.getString("ERROR"), 
+                    currentMessages.getString("ERROR"),
                     JOptionPane.ERROR_MESSAGE);
             return;
         }
 
-        // 解析IP和端口
         String[] parts = selectedDevice.split(":");
         if (parts.length != 2) {
-            JOptionPane.showMessageDialog(this, 
-                    currentMessages.getString("MESSAGE_VIEW_INVALID_DEVICE"), 
-                    currentMessages.getString("ERROR"), 
+            JOptionPane.showMessageDialog(this,
+                    currentMessages.getString("MESSAGE_VIEW_INVALID_DEVICE"),
+                    currentMessages.getString("ERROR"),
                     JOptionPane.ERROR_MESSAGE);
             return;
         }
@@ -412,28 +355,26 @@
         try {
             port = Integer.parseInt(parts[1]);
         } catch (NumberFormatException ex) {
-            JOptionPane.showMessageDialog(this, 
-                    currentMessages.getString("MESSAGE_VIEW_INVALID_PORT"), 
-                    currentMessages.getString("ERROR"), 
+            JOptionPane.showMessageDialog(this,
+                    currentMessages.getString("MESSAGE_VIEW_INVALID_PORT"),
+                    currentMessages.getString("ERROR"),
                     JOptionPane.ERROR_MESSAGE);
             return;
         }
 
         String dataToSend = txtSendData.getText();
         if (dataToSend.isEmpty()) {
-            JOptionPane.showMessageDialog(this, 
-                    currentMessages.getString("MESSAGE_VIEW_EMPTY_DATA"), 
-                    currentMessages.getString("WARNING"), 
+            JOptionPane.showMessageDialog(this,
+                    currentMessages.getString("MESSAGE_VIEW_EMPTY_DATA"),
+                    currentMessages.getString("WARNING"),
                     JOptionPane.WARNING_MESSAGE);
             return;
         }
 
-        // 添加回车换行
         if (chkAppendNewline.isSelected()) {
             dataToSend += "\r\n";
         }
 
-        // 记录发送数据到界面
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         String timestamp = sdf.format(new Date());
 
@@ -441,21 +382,15 @@
         displayData.append("[SEND][").append(timestamp).append("][").append(ip).append(":").append(port).append("] ");
 
         if (rdoSendHex.isSelected()) {
-            // HEX格式发送
             String hexData = toHexString(dataToSend);
             displayData.append(hexData);
             if (localPort == UDPPortAReceiver.PORT) {
-                // 传入是否HEX发送的标志
                 UDPPortAReceiver.sendData(ip, port, dataToSend, true);
             } else if (localPort == UDPPortBReceiver.PORT) {
-                // 传入是否HEX发送的标志
                 UDPPortBReceiver.sendData(ip, port, dataToSend, true);
             }
-
         } else {
-            // ASCII格式发送
             displayData.append(dataToSend);
-            // 实际发送ASCII数据(这里需要调用UDP发送方法)
             if (localPort == UDPPortAReceiver.PORT) {
                 UDPPortAReceiver.sendData(ip, port, dataToSend, false);
             } else if (localPort == UDPPortBReceiver.PORT) {
@@ -463,22 +398,17 @@
             }
         }
 
-        // 在EDT线程中更新UI
         SwingUtilities.invokeLater(() -> {
             txtDataView.append(displayData.toString() + "\n");
-            // 自动滚动到底部
             txtDataView.setCaretPosition(txtDataView.getDocument().getLength());
         });
     }
 
-    // 修改添加远程设备方法
-    // 在MessageViewPanel类中修改addRemoteDevice方法
     public static void addRemoteDevice(String ip, int port, int localPort) {
         String device = ip + ":" + port;
         if (!remoteDeviceLocalPortMap.containsKey(device)) {
             remoteDeviceLocalPortMap.put(device, localPort);
             SwingUtilities.invokeLater(() -> {
-                // 检查下拉框中是否已存在该设备
                 boolean exists = false;
                 ComboBoxModel<String> model = cbRemoteDevice.getModel();
                 for (int i = 0; i < model.getSize(); i++) {
@@ -495,120 +425,56 @@
         }
     }
 
-    // 捕获数据的核心方法
-    // 修改通用数据显示方法
-    public static void showData(String rawData, String ip, int port, int localPort, String deviceId) {
-        if (!isWindowVisible) {
+    public static void showData(String rawData, String ip, int port, int localPort,
+                               String DataType, String Protocol, String Id) {
+        // 双重检查:窗口可见且已点击开始按钮
+        if (!isWindowVisible || !isStarted) {
             return;
         }
-
-        // 获取当前选择
+        
+        if (cbDataType == null || cbProtocol == null || cbDeviceId == null) {
+            return;
+        }
+        
         String selectedDataType = (String) cbDataType.getSelectedItem();
         String selectedProtocol = (String) cbProtocol.getSelectedItem();
         String selectedDeviceId = (String) cbDeviceId.getSelectedItem();
 
-        // 使用新方法获取当前资源包
-        ResourceBundle messages = Languages.getCurrentMessages();
+        boolean DataTypeboolean = "ALL".equals(selectedDataType) || selectedDataType.equals(DataType);
+        boolean Protocolboolean = "ALL".equals(selectedProtocol) || selectedProtocol.equals(Protocol);
+        boolean DeviceIdboolean = "ALL".equals(selectedDeviceId) || selectedDeviceId.equals(Id);
         
-        String allTypes = messages.getString("MESSAGE_VIEW_ALL_TYPES");
-        String allProtocols = messages.getString("MESSAGE_VIEW_ALL_PROTOCOLS");
-        String allDevices = messages.getString("MESSAGE_VIEW_ALL_DEVICES");
-        String udpPortA = messages.getString("MESSAGE_VIEW_UDP_PORT_A");
-        String udpPortB = messages.getString("MESSAGE_VIEW_UDP_PORT_B");
-        String udpProtocol = "UDP"; // 直接使用协议名称
+        if (DataTypeboolean && Protocolboolean && DeviceIdboolean) {
+            StringBuilder sb = SB.get();
+            sb.setLength(0);
 
-        // 检查数据类型过滤
-        boolean dataTypeMatch = selectedDataType.equals(allTypes) || 
-                (localPort == UDPPortAReceiver.PORT && selectedDataType.equals(udpPortA)) ||
-                (localPort == UDPPortBReceiver.PORT && selectedDataType.equals(udpPortB));
+            if (chkShowSource.isSelected()) {
+                sb.append(PREFIX);
+                formatTime(sb);
+                sb.append(',').append(ip).append(COLON).append(port).append(SUFFIX);
+            }
+            sb.append(rawData);
 
-        // 检查协议过滤
-        boolean protocolMatch = selectedProtocol.equals(allProtocols) || 
-                (localPort == UDPPortAReceiver.PORT && selectedProtocol.equals(udpProtocol)) ||
-                (localPort == UDPPortBReceiver.PORT && selectedProtocol.equals(udpProtocol));
-
-        // 检查设备ID过滤
-        boolean deviceIdMatch=false;
-        if("1".equals(deviceId)) {
-            deviceIdMatch=true;
-        }else {
-            deviceIdMatch = selectedDeviceId.equals(allDevices) || 
-                    (deviceId != null && deviceId.equals(selectedDeviceId));
-        }
-
-        // 只有当所有条件都匹配时才显示
-        if (!(dataTypeMatch && protocolMatch && deviceIdMatch)) {
-            return;
-        }
-
-        // 生成毫秒级时间戳
-        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
-        String timestamp = sdf.format(new Date());
-        String formattedData = formatData(rawData, ip, port, timestamp);
-
-        if (isCapturing) {
-            // 添加远程设备到下拉框
-            addRemoteDevice(ip, port, localPort);
-
-            // 在EDT线程中更新UI
+            final String finalText = sb.toString();
             SwingUtilities.invokeLater(() -> {
-                txtDataView.append(formattedData + "\n");
+                txtDataView.append(finalText);
+                txtDataView.append("\n");
                 txtDataView.setCaretPosition(txtDataView.getDocument().getLength());
             });
-        }
 
-        // 如果启用了自动保存,则保存到文件
-        if (chkAutoSave.isSelected()) {
-            saveToFile(formattedData);
+            if (isCapturing && localPort != 0) {
+                addRemoteDevice(ip, port, localPort);
+            }
+
+            if (chkAutoSave.isSelected()) {
+                saveToFile(finalText);
+            }
         }
     }
 
-    // 格式化数据显示
-    // 修改格式显示方法,支持混合格式
-    private static String formatData(String rawData, String ip, int port, String timestamp) {
-        StringBuilder formatted = new StringBuilder();
-        // 使用新方法获取当前资源包
-        ResourceBundle messages = Languages.getCurrentMessages();
-        // 显示来源信息
-        if (chkShowSource.isSelected()) {
-            formatted.append("[")
-            .append(timestamp)
-            .append("][")
-            .append(ip)
-            .append(":")
-            .append(port)
-            .append("] ");
-        }
-
-        // 根据显示选项格式化数据
-        if (chkHexDisplay.isSelected() && chkAsciiDisplay.isSelected()) {
-            formatted.append(formatHexString(rawData))
-            .append(" | ")
-            .append(hexToAscii(rawData))
-            .append(" [")
-            .append(messages.getString("MESSAGE_VIEW_MIXED_FORMAT"))
-            .append("]");
-        } else if (chkHexDisplay.isSelected()) {
-            formatted.append(formatHexString(rawData))
-            .append(" [")
-            .append(messages.getString("MESSAGE_VIEW_HEX_FORMAT"))
-            .append("]");
-        } else if (chkAsciiDisplay.isSelected()) {
-            formatted.append(hexToAscii(rawData))
-            .append(" [")
-            .append(messages.getString("MESSAGE_VIEW_ASCII_FORMAT"))
-            .append("]");
-        } else {
-            formatted.append(hexToAscii(rawData));
-        }
-
-        return formatted.toString();
-    }
-
-    // 修改设备ID加载方法
     private void loadDeviceIds() {
         cbDeviceId.removeAllItems();
-        cbDeviceId.addItem(messages.getString("MESSAGE_VIEW_ALL_DEVICES"));
+        cbDeviceId.addItem("ALL");
 
         List<String> tags = Dell_tag.getAlldeviceIds();
         for (String tag : tags) {
@@ -616,42 +482,54 @@
         }
     }
 
-    // 将字符串转换为十六进制表示
     private static String toHexString(String input) {
-        StringBuilder hex = new StringBuilder(); // 使用StringBuilder构建十六进制字符串
-        for (char c : input.toCharArray()) { // 遍历每个字符
-            hex.append(String.format("%02X ", (int) c)); // 格式化为两位十六进制
+        StringBuilder hex = new StringBuilder();
+        for (char c : input.toCharArray()) {
+            hex.append(String.format("%02X ", (int) c));
         }
-        return hex.toString().trim(); // 返回并去除末尾空格
-    }
-    // 格式化十六进制字符串(每两个字符加空格)
-    private static String formatHexString(String hex) {
-        StringBuilder formatted = new StringBuilder();
-        for (int i = 0; i < hex.length(); i += 2) {
-            if (i > 0) formatted.append(" ");
-            formatted.append(hex.substring(i, Math.min(i + 2, hex.length())));
-        }
-        return formatted.toString();
+        return hex.toString().trim();
     }
 
-    // 将十六进制字符串转换为ASCII
-    private static String hexToAscii(String hexStr) {
-        StringBuilder output = new StringBuilder();
-        for (int i = 0; i < hexStr.length(); i += 2) {
-            String str = hexStr.substring(i, i + 2);
-            output.append((char) Integer.parseInt(str, 16));
-        }
-        return output.toString();
-    }
-    // 保存数据到文件
     private static void saveToFile(String data) {
-        SimpleDateFormat fileFormat = new SimpleDateFormat("yyyyMMdd"); // 文件日期格式
-        String fileName = "systemfile/baowen/messages_" + fileFormat.format(new Date()) + ".txt"; // 文件名包含日期
+        SimpleDateFormat fileFormat = new SimpleDateFormat("yyyyMMdd");
+        String fileName = "systemfile/baowen/messages_" + fileFormat.format(new Date()) + ".txt";
 
-        try (java.io.FileWriter writer = new java.io.FileWriter(fileName, true)) { // 使用追加模式
-            writer.write(data + "\n"); // 写入数据并换行
+        try (java.io.FileWriter writer = new java.io.FileWriter(fileName, true)) {
+            writer.write(data + "\n");
         } catch (java.io.IOException ex) {
-            ex.printStackTrace(); // 打印IO异常
+            ex.printStackTrace();
         }
     }
+
+    public static String getSelectedDataType() {
+        return cbDataType == null ? "" : String.valueOf(cbDataType.getSelectedItem());
+    }
+
+    public static String getSelectedProtocol() {
+        return cbProtocol == null ? "" : String.valueOf(cbProtocol.getSelectedItem());
+    }
+
+    public static String getSelectedDeviceId() {
+        return cbDeviceId == null ? "" : String.valueOf(cbDeviceId.getSelectedItem());
+    }
+    
+    private static void formatTime(StringBuilder sb) {
+        long now = System.currentTimeMillis();
+        long sec  = (now / 1000) % 86400;
+        int  ms   = (int) (now % 1000);
+
+        int h = (int) (sec / 3600);
+        int m = (int) ((sec % 3600) / 60);
+        int s = (int) (sec % 60);
+
+        sb.append((char) ('0' + (h / 10)))
+          .append((char) ('0' + (h % 10))).append(':');
+        sb.append((char) ('0' + (m / 10)))
+          .append((char) ('0' + (m % 10))).append(':');
+        sb.append((char) ('0' + (s / 10)))
+          .append((char) ('0' + (s % 10))).append('.');
+        sb.append(DIGITS[ms / 100])
+          .append(DIGITS[(ms / 10) % 10])
+          .append(DIGITS[ms % 10]);
+    }
 }
\ No newline at end of file
diff --git a/src/dell_system/SerialCommPanel.java b/src/dell_system/SerialCommPanel.java
index a4aee12..6267556 100644
--- a/src/dell_system/SerialCommPanel.java
+++ b/src/dell_system/SerialCommPanel.java
@@ -1,6 +1,6 @@
 package dell_system;
 import com.fazecast.jSerialComm.SerialPort;
-import dell55AAData.PacketParser;
+
 import javax.swing.*;
 import javax.swing.border.TitledBorder;
 import javax.swing.event.PopupMenuEvent;
@@ -332,7 +332,7 @@
             lblPacketCount.setText(String.format(messages.getString("packet.count.format"), packetCounter));
 
             try {
-                String parsed = PacketParser.parse(data, messages, chkTimestamp.isSelected());
+                String parsed = SerialPacketParser.parse(data, messages, chkTimestamp.isSelected());
                 txtParsedData.append(parsed);
                 txtParsedData.setCaretPosition(txtParsedData.getDocument().getLength());
                 lblParseStatus.setText(
diff --git a/src/dell55AAData/PacketParser.java b/src/dell_system/SerialPacketParser.java
similarity index 96%
rename from src/dell55AAData/PacketParser.java
rename to src/dell_system/SerialPacketParser.java
index bc75351..c523447 100644
--- a/src/dell55AAData/PacketParser.java
+++ b/src/dell_system/SerialPacketParser.java
@@ -1,4 +1,4 @@
-package dell55AAData;
+package dell_system;
 import dell55AAData.Dell55AA12HighPerf;
 import dell55AAData.Dell55AA12HighPerf.ParseResult;
 import dell55AAData.Dell55AA01Parser;
@@ -10,11 +10,11 @@
  * 公共解析器:根据包头统一解析 55AA01 / 55AA12 / 未知协议
  * 可被任何 UI 或业务类直接调用
  */
-public final class PacketParser {
+public final class SerialPacketParser {
 
     private static final SimpleDateFormat SDF = new SimpleDateFormat("HH:mm:ss.SSS");
 
-    private PacketParser() { /* 工具类,禁止实例化 */ }
+    private SerialPacketParser() { /* 工具类,禁止实例化 */ }
 
     /**
      * 解析入口
@@ -32,7 +32,7 @@
         }
 
         if (hex.startsWith("55AA01")) {
-            Dell55AA01Parser.ParseResult r = Dell55AA01Parser.parse(hex);
+            Dell55AA01Parser.ParseResult r = Dell55AA01Parser.parse(hex,"127.0.0.1", 0);
             if (r == null) {
                 sb.append(bundle.getString("parser.invalid")).append(" 55AA01");
                 return sb.toString();

--
Gitblit v1.9.3