| | |
| | | import java.io.File; |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | |
| | |
| | | private JCheckBox asciiDisplayCheck, autoSaveCheck, showTimeCheck; |
| | | private JButton toggleBtn, clearBtn; |
| | | |
| | | // 用于存储接收到的数据 |
| | | // 用于存储接收到的数据 |
| | | private StringBuilder receivedData = new StringBuilder(); |
| | | private boolean isPaused = false; |
| | | |
| | |
| | | clearBtn = ButtonUtils.createBlueButton(getString("clear"), 25); |
| | | clearBtn.setPreferredSize(new Dimension(70, 25)); |
| | | |
| | | // 添加按钮监听器 |
| | | // 添加按钮监听器 |
| | | toggleBtn.addActionListener(e -> toggleDisplay()); |
| | | clearBtn.addActionListener(e -> clearLog()); |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * 添加日志数据 - 原始方法 |
| | | * 添加日志数据 - 原始方法 |
| | | */ |
| | | public void addLogData(byte[] data) { |
| | | if (isPaused || data == null || data.length == 0) { |
| | | return; |
| | | } |
| | | |
| | | // 根据显示格式处理数据 |
| | | // 根据显示格式处理数据 |
| | | String displayData; |
| | | if (asciiDisplayCheck.isSelected()) { |
| | | // ASCII显示格式 |
| | | // ASCII显示格式 |
| | | displayData = bytesToAscii(data); |
| | | } else { |
| | | // HEX显示格式 |
| | | // HEX显示格式 |
| | | displayData = bytesToHex(data); |
| | | } |
| | | |
| | | // 添加时间戳 |
| | | // 添加时间戳 |
| | | String finalData; |
| | | if (showTimeCheck.isSelected()) { |
| | | String timestamp = new SimpleDateFormat("HH:mm:ss").format(new Date()); |
| | |
| | | finalData = displayData + "\n"; |
| | | } |
| | | |
| | | // 更新显示 |
| | | // 更新显示 |
| | | SwingUtilities.invokeLater(() -> { |
| | | logArea.append(finalData); |
| | | logArea.setCaretPosition(logArea.getDocument().getLength()); |
| | | }); |
| | | |
| | | // 自动保存 |
| | | // 自动保存 |
| | | if (autoSaveCheck.isSelected()) { |
| | | saveToFile(data, displayData); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 添加带标签的日志数据 |
| | | * @param data 字节数组数据 |
| | | * @param tag 数据标签(如"发送"、"接收"等) |
| | | * 添加带标签的日志数据 |
| | | * @param data 字节数组数据 |
| | | * @param tag 数据标签(如"发送"、"接收"等) |
| | | */ |
| | | public void addLogData(byte[] data, String tag) { |
| | | if (isPaused || data == null || data.length == 0) { |
| | | return; |
| | | } |
| | | |
| | | // 根据显示格式处理数据 |
| | | // 根据显示格式处理数据 |
| | | String displayData; |
| | | if (asciiDisplayCheck.isSelected()) { |
| | | // ASCII显示格式 |
| | | // ASCII显示格式 |
| | | displayData = bytesToAscii(data); |
| | | } else { |
| | | // HEX显示格式 |
| | | // HEX显示格式 |
| | | displayData = bytesToHex(data); |
| | | } |
| | | |
| | | // 添加时间戳和标签 |
| | | // 添加时间戳和标签 |
| | | String finalData; |
| | | if (showTimeCheck.isSelected()) { |
| | | String timestamp = new SimpleDateFormat("HH:mm:ss").format(new Date()); |
| | |
| | | finalData = "[" + tag + "] " + displayData + "\n"; |
| | | } |
| | | |
| | | // 更新显示 |
| | | // 更新显示 |
| | | SwingUtilities.invokeLater(() -> { |
| | | logArea.append(finalData); |
| | | logArea.setCaretPosition(logArea.getDocument().getLength()); |
| | | }); |
| | | |
| | | // 自动保存 |
| | | // 自动保存 |
| | | if (autoSaveCheck.isSelected()) { |
| | | saveToFileWithTag(data, displayData, tag); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 字节数组转ASCII字符串 |
| | | * 字节数组转ASCII字符串 |
| | | */ |
| | | private String bytesToAscii(byte[] bytes) { |
| | | StringBuilder sb = new StringBuilder(); |
| | | for (byte b : bytes) { |
| | | if (b >= 32 && b <= 126) { |
| | | // 可打印ASCII字符 |
| | | sb.append((char) b); |
| | | } else { |
| | | // 不可打印字符用点号代替 |
| | | sb.append('.'); |
| | | } |
| | | } |
| | | return sb.toString(); |
| | | String message1 = new String(bytes, 0, bytes.length, StandardCharsets.UTF_8); |
| | | return message1; |
| | | } |
| | | |
| | | /** |
| | | * 字节数组转十六进制字符串 |
| | | * 字节数组转十六进制字符串 |
| | | */ |
| | | private String bytesToHex(byte[] bytes) { |
| | | StringBuilder sb = new StringBuilder(); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 保存数据到文件 |
| | | * 保存数据到文件 |
| | | */ |
| | | private void saveToFile(byte[] data, String displayData) { |
| | | try { |
| | |
| | | fos.write(fileContent.getBytes("UTF-8")); |
| | | } |
| | | } catch (IOException e) { |
| | | System.err.println("保存文件错误: " + e.getMessage()); |
| | | System.err.println(getString("save.file.error") + ": " + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 带标签保存数据到文件 |
| | | * 带标签保存数据到文件 |
| | | */ |
| | | private void saveToFileWithTag(byte[] data, String displayData, String tag) { |
| | | try { |
| | |
| | | fos.write(fileContent.getBytes("UTF-8")); |
| | | } |
| | | } catch (IOException e) { |
| | | System.err.println("保存文件错误: " + e.getMessage()); |
| | | System.err.println(getString("save.file.error") + ": " + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 切换显示暂停/继续 |
| | | * 切换显示暂停/继续 |
| | | */ |
| | | private void toggleDisplay() { |
| | | isPaused = !isPaused; |
| | |
| | | } |
| | | |
| | | /** |
| | | * 清除日志 |
| | | * 清除日志 |
| | | */ |
| | | private void clearLog() { |
| | | logArea.setText(""); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 通用方法 |
| | | * 通用方法 |
| | | */ |
| | | public void addLog(String logMessage) { |
| | | if (logArea != null) { |