package home; import javax.swing.*; import java.awt.*; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class DataLogPanel extends JPanel { /** * */ private static final long serialVersionUID = 1L; private MainFrame mainFrame; private JTextArea logArea; private JCheckBox asciiDisplayCheck, autoSaveCheck, showTimeCheck; private JButton toggleBtn, clearBtn; // ÓÃÓÚ´æ´¢½ÓÊÕµ½µÄÊý¾Ý private StringBuilder receivedData = new StringBuilder(); private boolean isPaused = false; public DataLogPanel(MainFrame mainFrame) { this.mainFrame = mainFrame; initializeUI(); } private void initializeUI() { setLayout(new BorderLayout()); setBorder(BorderFactory.createTitledBorder(getString("data.log"))); logArea = new JTextArea(20, 30); logArea.setEditable(false); JScrollPane scrollPane = new JScrollPane(logArea); JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); asciiDisplayCheck = new JCheckBox(getString("ascii.display")); autoSaveCheck = new JCheckBox(getString("auto.save")); showTimeCheck = new JCheckBox(getString("show.time")); toggleBtn = ButtonUtils.createBlueButton(getString("start"), 25); toggleBtn.setPreferredSize(new Dimension(70, 25)); clearBtn = ButtonUtils.createBlueButton(getString("clear"), 25); clearBtn.setPreferredSize(new Dimension(70, 25)); // Ìí¼Ó°´Å¥¼àÌýÆ÷ toggleBtn.addActionListener(e -> toggleDisplay()); clearBtn.addActionListener(e -> clearLog()); controlPanel.add(asciiDisplayCheck); controlPanel.add(autoSaveCheck); controlPanel.add(showTimeCheck); controlPanel.add(toggleBtn); controlPanel.add(clearBtn); add(scrollPane, BorderLayout.CENTER); add(controlPanel, BorderLayout.SOUTH); } /** * Ìí¼ÓÈÕÖ¾Êý¾Ý - ԭʼ·½·¨ */ public void addLogData(byte[] data) { if (isPaused || data == null || data.length == 0) { return; } // ¸ù¾ÝÏÔʾ¸ñʽ´¦ÀíÊý¾Ý String displayData; if (asciiDisplayCheck.isSelected()) { // ASCIIÏÔʾ¸ñʽ displayData = bytesToAscii(data); } else { // HEXÏÔʾ¸ñʽ displayData = bytesToHex(data); } // Ìí¼Óʱ¼ä´Á String finalData; if (showTimeCheck.isSelected()) { String timestamp = new SimpleDateFormat("HH:mm:ss").format(new Date()); finalData = "[" + timestamp + "] " + displayData + "\n"; } else { finalData = displayData + "\n"; } // ¸üÐÂÏÔʾ SwingUtilities.invokeLater(() -> { logArea.append(finalData); logArea.setCaretPosition(logArea.getDocument().getLength()); }); // ×Ô¶¯±£´æ if (autoSaveCheck.isSelected()) { saveToFile(data, displayData); } } /** * Ìí¼Ó´ø±êÇ©µÄÈÕÖ¾Êý¾Ý * @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ÏÔʾ¸ñʽ displayData = bytesToAscii(data); } else { // HEXÏÔʾ¸ñʽ displayData = bytesToHex(data); } // Ìí¼Óʱ¼ä´ÁºÍ±êÇ© String finalData; if (showTimeCheck.isSelected()) { String timestamp = new SimpleDateFormat("HH:mm:ss").format(new Date()); finalData = "[" + timestamp + "] [" + tag + "] " + displayData + "\n"; } else { finalData = "[" + tag + "] " + displayData + "\n"; } // ¸üÐÂÏÔʾ SwingUtilities.invokeLater(() -> { logArea.append(finalData); logArea.setCaretPosition(logArea.getDocument().getLength()); }); // ×Ô¶¯±£´æ if (autoSaveCheck.isSelected()) { saveToFileWithTag(data, displayData, tag); } } /** * ×Ö½ÚÊý×éת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(); } /** * ×Ö½ÚÊý×éתʮÁù½øÖÆ×Ö·û´® */ private String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02X ", b)); } return sb.toString().trim(); } /** * ±£´æÊý¾Ýµ½Îļþ */ private void saveToFile(byte[] data, String displayData) { try { String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date()); String fileName = "serial_data_" + dateStr + ".txt"; File file = new File(fileName); String fileContent; if (showTimeCheck.isSelected()) { String timestamp = new SimpleDateFormat("HH:mm:ss").format(new Date()); fileContent = "[" + timestamp + "] " + displayData + "\n"; } else { fileContent = displayData + "\n"; } try (FileOutputStream fos = new FileOutputStream(file, true)) { fos.write(fileContent.getBytes("UTF-8")); } } catch (IOException e) { System.err.println("±£´æÎļþ´íÎó: " + e.getMessage()); } } /** * ´ø±êÇ©±£´æÊý¾Ýµ½Îļþ */ private void saveToFileWithTag(byte[] data, String displayData, String tag) { try { String dateStr = new SimpleDateFormat("yyyyMMdd").format(new Date()); String fileName = "serial_data_" + dateStr + ".txt"; File file = new File(fileName); String fileContent; if (showTimeCheck.isSelected()) { String timestamp = new SimpleDateFormat("HH:mm:ss").format(new Date()); fileContent = "[" + timestamp + "] [" + tag + "] " + displayData + "\n"; } else { fileContent = "[" + tag + "] " + displayData + "\n"; } try (FileOutputStream fos = new FileOutputStream(file, true)) { fos.write(fileContent.getBytes("UTF-8")); } } catch (IOException e) { System.err.println("±£´æÎļþ´íÎó: " + e.getMessage()); } } /** * Çл»ÏÔʾÔÝÍ£/¼ÌÐø */ private void toggleDisplay() { isPaused = !isPaused; if (isPaused) { toggleBtn.setText(getString("pause")); } else { toggleBtn.setText(getString("start")); } } /** * Çå³ýÈÕÖ¾ */ private void clearLog() { logArea.setText(""); receivedData.setLength(0); } public void updateLanguage() { setBorder(BorderFactory.createTitledBorder(getString("data.log"))); asciiDisplayCheck.setText(getString("ascii.display")); autoSaveCheck.setText(getString("auto.save")); showTimeCheck.setText(getString("show.time")); if (isPaused) { toggleBtn.setText(getString("pause")); } else { toggleBtn.setText(getString("start")); } clearBtn.setText(getString("clear")); revalidate(); repaint(); } private String getString(String key) { return mainFrame.getString(key); } /** * ͨÓ÷½·¨ */ public void addLog(String logMessage) { if (logArea != null) { logArea.append(logMessage + "\n"); logArea.setCaretPosition(logArea.getDocument().getLength()); } } }