From ccb681ec3a4ef38da878ac3a01c498853e9be4ca Mon Sep 17 00:00:00 2001 From: 826220679@qq.com <826220679@qq.com> Date: 星期六, 09 八月 2025 16:34:19 +0800 Subject: [PATCH] 修改 --- src/dell_system/MessageViewPanel.java | 239 +++++++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 159 insertions(+), 80 deletions(-) diff --git a/src/dell_system/MessageViewPanel.java b/src/dell_system/MessageViewPanel.java index da83577..3dcb4a2 100644 --- a/src/dell_system/MessageViewPanel.java +++ b/src/dell_system/MessageViewPanel.java @@ -7,13 +7,11 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.ResourceBundle; -import java.util.Set; -import dell_targets.Dell_MessageType; import dell_targets.Dell_tag; +import publicsWay.Languages; import udptcp.UDPPortAReceiver; import udptcp.UDPPortBReceiver; @@ -28,7 +26,7 @@ // UI组件声明 private JButton btnStart, btnPause, btnClear, btnSend; // 控制按钮:开始、暂停、清除、发送 private static JComboBox<String> cbDataType; // 下拉框:数据类型、协议、设备ID - private JComboBox<String> cbProtocol; + private static JComboBox<String> cbProtocol; private static JComboBox<String> cbDeviceId; private static JComboBox<String> cbRemoteDevice; // 远程设备下拉框 private static JCheckBox chkAutoSave; // 复选框:自动保存、显示来源、十六进制显示、ASCII显示 @@ -46,15 +44,16 @@ // 状态变量 private static boolean isCapturing = false; // 是否正在捕获数据的标志 - // 存储所有远程设备(IP:端口) - private static Set<String> remoteDevices = new HashSet<>(); - // 修改为Map存储设备及其本地端口 + // 修改为Map存储设备及其本地端口 private static Map<String, Integer> remoteDeviceLocalPortMap = new HashMap<>(); // 构造函数 public MessageViewPanel(ResourceBundle messages) { this.messages = messages; // 初始化消息资源包 initializeUI(); // 初始化用户界面 } + + + public void addNotify() { super.addNotify(); @@ -66,7 +65,7 @@ public void windowClosing(WindowEvent e) { isWindowVisible = false; } - + @Override public void windowClosed(WindowEvent e) { isWindowVisible = false; @@ -199,22 +198,22 @@ // 创建发送选项面板 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")); @@ -266,18 +265,18 @@ 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)); // 设置前景色 - + // 美化选中效果 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) { @@ -287,7 +286,7 @@ radioButton.setForeground(new Color(70, 70, 70)); } }); - + return radioButton; } @@ -295,21 +294,21 @@ private static class RadioButtonIcon implements Icon { private static final int SIZE = 14; private final boolean selected; - + public RadioButtonIcon(boolean selected) { this.selected = selected; } - + @Override public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2d = (Graphics2D) g.create(); 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); @@ -318,39 +317,31 @@ g2d.setColor(new Color(150, 150, 150)); g2d.drawOval(x, y, SIZE-1, SIZE-1); } - + g2d.dispose(); } - + @Override public int getIconWidth() { return SIZE; } - + @Override public int getIconHeight() { return SIZE; } } - // 加载设备ID列表 - private void loadDeviceIds() { - // 从Dell_tag类获取所有设备ID - List<String> tags = Dell_tag.getAlldeviceIds(); - // 遍历设备ID列表并添加到下拉框 - for (String tag : tags) { - cbDeviceId.addItem(tag); - } - } // 加载数据类型 private void loadtyps() { - // 从Dell_tag类获取所有设备ID - List<String> typs = Dell_MessageType.getAllMessageTypes(); - // 遍历设备ID列表并添加到下拉框 - for (String typ : typs) { - cbDataType.addItem(typ); - } + 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")); } // 设置按钮动作 @@ -385,21 +376,23 @@ // 发送数据到远程设备 private void sendData() { + // 使用新方法获取当前资源包 + ResourceBundle currentMessages = Languages.getCurrentMessages(); String selectedDevice = (String) cbRemoteDevice.getSelectedItem(); - if (selectedDevice == null || selectedDevice.equals(messages.getString("MESSAGE_VIEW_ALL_DEVICES"))) { + if (selectedDevice == null || selectedDevice.equals(currentMessages.getString("MESSAGE_VIEW_ALL_DEVICES"))) { JOptionPane.showMessageDialog(this, - messages.getString("MESSAGE_VIEW_SELECT_DEVICE"), - messages.getString("WARNING"), + currentMessages.getString("MESSAGE_VIEW_SELECT_DEVICE"), + currentMessages.getString("WARNING"), JOptionPane.WARNING_MESSAGE); return; } - + // 获取本地端口 Integer localPort = remoteDeviceLocalPortMap.get(selectedDevice); if (localPort == null) { JOptionPane.showMessageDialog(this, "无法确定设备的接收端口", - messages.getString("ERROR"), + currentMessages.getString("ERROR"), JOptionPane.ERROR_MESSAGE); return; } @@ -408,8 +401,8 @@ String[] parts = selectedDevice.split(":"); if (parts.length != 2) { JOptionPane.showMessageDialog(this, - messages.getString("MESSAGE_VIEW_INVALID_DEVICE"), - messages.getString("ERROR"), + currentMessages.getString("MESSAGE_VIEW_INVALID_DEVICE"), + currentMessages.getString("ERROR"), JOptionPane.ERROR_MESSAGE); return; } @@ -420,8 +413,8 @@ port = Integer.parseInt(parts[1]); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(this, - messages.getString("MESSAGE_VIEW_INVALID_PORT"), - messages.getString("ERROR"), + currentMessages.getString("MESSAGE_VIEW_INVALID_PORT"), + currentMessages.getString("ERROR"), JOptionPane.ERROR_MESSAGE); return; } @@ -429,8 +422,8 @@ String dataToSend = txtSendData.getText(); if (dataToSend.isEmpty()) { JOptionPane.showMessageDialog(this, - messages.getString("MESSAGE_VIEW_EMPTY_DATA"), - messages.getString("WARNING"), + currentMessages.getString("MESSAGE_VIEW_EMPTY_DATA"), + currentMessages.getString("WARNING"), JOptionPane.WARNING_MESSAGE); return; } @@ -458,7 +451,7 @@ // 传入是否HEX发送的标志 UDPPortBReceiver.sendData(ip, port, dataToSend, true); } - + } else { // ASCII格式发送 displayData.append(dataToSend); @@ -477,7 +470,7 @@ txtDataView.setCaretPosition(txtDataView.getDocument().getLength()); }); } - + // 修改添加远程设备方法 // 在MessageViewPanel类中修改addRemoteDevice方法 public static void addRemoteDevice(String ip, int port, int localPort) { @@ -494,65 +487,133 @@ break; } } - + if (!exists) { cbRemoteDevice.addItem(device); } }); } } - + // 捕获数据的核心方法 - public static void captureData(String rawData, String ip, int port, int localPort, String timestamp) { - // 检查窗口是否可见 + // 修改通用数据显示方法 + public static void showData(String rawData, String ip, int port, int localPort, String deviceId) { if (!isWindowVisible) { return; } - String formattedData = formatData(rawData,ip,port,timestamp); // 格式化数据 - if(isCapturing) { + + // 获取当前选择 + String selectedDataType = (String) cbDataType.getSelectedItem(); + String selectedProtocol = (String) cbProtocol.getSelectedItem(); + String selectedDeviceId = (String) cbDeviceId.getSelectedItem(); + + // 使用新方法获取当前资源包 + ResourceBundle messages = Languages.getCurrentMessages(); + + 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"; // 直接使用协议名称 + + // 检查数据类型过滤 + boolean dataTypeMatch = selectedDataType.equals(allTypes) || + (localPort == UDPPortAReceiver.PORT && selectedDataType.equals(udpPortA)) || + (localPort == UDPPortBReceiver.PORT && selectedDataType.equals(udpPortB)); + + // 检查协议过滤 + 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); // 确保调用带端口参数的方法 - // 获取当前选择的设备ID和数据类型 - String deviceId = cbDeviceId.getSelectedItem().toString(); - String dataType = cbDataType.getSelectedItem().toString(); - + addRemoteDevice(ip, port, localPort); + // 在EDT线程中更新UI SwingUtilities.invokeLater(() -> { - txtDataView.append(formattedData + "\n"); // 添加数据到文本区域 - // 自动滚动到底部 + txtDataView.append(formattedData + "\n"); txtDataView.setCaretPosition(txtDataView.getDocument().getLength()); }); } + // 如果启用了自动保存,则保存到文件 if (chkAutoSave.isSelected()) { saveToFile(formattedData); - } + } } // 格式化数据显示 - private static String formatData(String rawData, String ip, int port,String timestamp) { - StringBuilder formatted = new StringBuilder(); // 使用StringBuilder构建格式化字符串 - - // 如果启用了显示来源,添加时间戳和源地址 + // 修改格式显示方法,支持混合格式 + 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("["+timestamp+";"+ip+":"+port+"]"); // 添加模拟源地址 + formatted.append("[") + .append(timestamp) + .append("][") + .append(ip) + .append(":") + .append(port) + .append("] "); } // 根据显示选项格式化数据 if (chkHexDisplay.isSelected() && chkAsciiDisplay.isSelected()) { - // 同时显示十六进制和ASCII - formatted.append(toHexString(rawData)) // 添加十六进制表示 - .append(" | ") // 添加分隔符 - .append(rawData); // 添加原始ASCII数据 + formatted.append(formatHexString(rawData)) + .append(" | ") + .append(hexToAscii(rawData)) + .append(" [") + .append(messages.getString("MESSAGE_VIEW_MIXED_FORMAT")) + .append("]"); } else if (chkHexDisplay.isSelected()) { - // 仅显示十六进制 - formatted.append(toHexString(rawData)); + 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 { - // 默认显示原始ASCII数据 - formatted.append(rawData); + formatted.append(hexToAscii(rawData)); } - return formatted.toString(); // 返回格式化后的字符串 + return formatted.toString(); + } + + // 修改设备ID加载方法 + private void loadDeviceIds() { + cbDeviceId.removeAllItems(); + cbDeviceId.addItem(messages.getString("MESSAGE_VIEW_ALL_DEVICES")); + + List<String> tags = Dell_tag.getAlldeviceIds(); + for (String tag : tags) { + cbDeviceId.addItem(tag); + } } // 将字符串转换为十六进制表示 @@ -563,7 +624,25 @@ } 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(); + } + // 将十六进制字符串转换为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"); // 文件日期格式 -- Gitblit v1.9.3