From fb883547ede83b1c758b1a9a025898ba3f83497a Mon Sep 17 00:00:00 2001 From: 826220679@qq.com <826220679@qq.com> Date: 星期日, 10 八月 2025 23:05:19 +0800 Subject: [PATCH] 新增 --- src/dell_system/MessageViewPanel.java | 600 +++++++++++++++++++++++------------------------------------ 1 files changed, 239 insertions(+), 361 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 -- Gitblit v1.9.3