package xitongshezhi; import javax.swing.*; import java.awt.*; import java.io.*; import java.util.Properties; @SuppressWarnings("serial") public class lishijilu extends JDialog { // 屏幕尺寸常量 - 适配7寸竖屏 private static final int SCREEN_WIDTH = 480; private static final int SCREEN_HEIGHT = 800; // 颜色常量 - 统一使用kacaoguanli.java中的颜色定义 private static final Color PRIMARY_COLOR = new Color(52, 152, 219); private static final Color DARK_COLOR = new Color(15, 28, 48); private static final Color DARK_LIGHT_COLOR = new Color(26, 43, 68); private static final Color TEXT_COLOR = new Color(224, 224, 224); private static final Color TEXT_LIGHT_COLOR = new Color(160, 200, 255); private static final Color DELETE_COLOR = new Color(231, 76, 60); // 删除按钮颜色 private static final Color ACTIVE_BUTTON_COLOR = new Color(41, 128, 185); // 激活按钮颜色 private JPanel mainPanel; private JButton logButton; // 日志记录按钮 private JButton errorLogButton; // 错误日志按钮 private JButton backButton; private JButton deleteAllButton; // 文本域组件 private JScrollPane textScrollPane; private JTextArea contentTextArea; // 当前显示的日志类型 private String currentLogType = "log"; // "log" 或 "error" public lishijilu(JFrame parent) { super(parent, "", true); initializeUI(); setupEventListeners(); loadLogContent(); // 默认加载操作日志 } private void initializeUI() { // 设置对话框属性 setSize(SCREEN_WIDTH, SCREEN_HEIGHT); setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); setLocationRelativeTo(getParent()); setResizable(false); // 设置系统外观 try { UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); } // 主面板 mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); mainPanel.setBackground(DARK_COLOR); mainPanel.setOpaque(true); mainPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12)); // 创建顶部标题栏 JPanel headerPanel = createHeaderPanel(); // 创建文本区域 JPanel contentPanel = createContentPanel(); mainPanel.add(headerPanel, BorderLayout.NORTH); mainPanel.add(contentPanel, BorderLayout.CENTER); getContentPane().add(mainPanel); } private JPanel createHeaderPanel() { JPanel headerPanel = new JPanel(new BorderLayout()); headerPanel.setOpaque(false); headerPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 12, 0)); // 创建日志类型选择按钮面板 JPanel logTypePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 8, 0)); logTypePanel.setOpaque(false); // 日志记录按钮 logButton = new JButton("日志记录"); logButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14)); logButton.setBackground(ACTIVE_BUTTON_COLOR); // 默认激活状态 logButton.setForeground(Color.WHITE); logButton.setOpaque(true); logButton.setFocusPainted(false); logButton.setBorder(BorderFactory.createEmptyBorder(8, 16, 8, 16)); logButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); // 错误日志按钮 errorLogButton = new JButton("错误日志"); errorLogButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14)); errorLogButton.setBackground(PRIMARY_COLOR); // 默认非激活状态 errorLogButton.setForeground(Color.WHITE); errorLogButton.setOpaque(true); errorLogButton.setFocusPainted(false); errorLogButton.setBorder(BorderFactory.createEmptyBorder(8, 16, 8, 16)); errorLogButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); logTypePanel.add(logButton); logTypePanel.add(errorLogButton); // 操作按钮面板 JPanel actionButtonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 8, 0)); actionButtonPanel.setOpaque(false); // 删除全部记录按钮 deleteAllButton = new JButton("删除全部"); deleteAllButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14)); deleteAllButton.setBackground(DELETE_COLOR); deleteAllButton.setForeground(Color.WHITE); deleteAllButton.setOpaque(true); deleteAllButton.setFocusPainted(false); deleteAllButton.setBorder(BorderFactory.createEmptyBorder(8, 16, 8, 16)); deleteAllButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); // 返回按钮 backButton = new JButton("关闭"); backButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14)); backButton.setBackground(PRIMARY_COLOR); backButton.setForeground(Color.WHITE); backButton.setOpaque(true); backButton.setFocusPainted(false); backButton.setBorder(BorderFactory.createEmptyBorder(8, 16, 8, 16)); backButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); actionButtonPanel.add(deleteAllButton); actionButtonPanel.add(backButton); // 按钮悬停效果 setupButtonHoverEffects(); headerPanel.add(logTypePanel, BorderLayout.WEST); headerPanel.add(actionButtonPanel, BorderLayout.EAST); return headerPanel; } private void setupButtonHoverEffects() { // 日志按钮悬停效果 logButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseEntered(java.awt.event.MouseEvent evt) { if (!currentLogType.equals("log")) { logButton.setBackground(brighterColor(PRIMARY_COLOR)); } } public void mouseExited(java.awt.event.MouseEvent evt) { if (!currentLogType.equals("log")) { logButton.setBackground(PRIMARY_COLOR); } } }); // 错误日志按钮悬停效果 errorLogButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseEntered(java.awt.event.MouseEvent evt) { if (!currentLogType.equals("error")) { errorLogButton.setBackground(brighterColor(PRIMARY_COLOR)); } } public void mouseExited(java.awt.event.MouseEvent evt) { if (!currentLogType.equals("error")) { errorLogButton.setBackground(PRIMARY_COLOR); } } }); // 删除按钮悬停效果 deleteAllButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseEntered(java.awt.event.MouseEvent evt) { deleteAllButton.setBackground(brighterColor(DELETE_COLOR)); } public void mouseExited(java.awt.event.MouseEvent evt) { deleteAllButton.setBackground(DELETE_COLOR); } }); // 返回按钮悬停效果 backButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseEntered(java.awt.event.MouseEvent evt) { backButton.setBackground(brighterColor(PRIMARY_COLOR)); } public void mouseExited(java.awt.event.MouseEvent evt) { backButton.setBackground(PRIMARY_COLOR); } }); } private JPanel createContentPanel() { JPanel panel = new JPanel(new BorderLayout()); panel.setBackground(DARK_LIGHT_COLOR); panel.setOpaque(true); panel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(new Color(52, 152, 219, 26)), BorderFactory.createEmptyBorder(12, 12, 12, 12) )); // 内容标题 JPanel contentHeader = new JPanel(new BorderLayout()); contentHeader.setOpaque(false); contentHeader.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(255, 255, 255, 26)), BorderFactory.createEmptyBorder(0, 0, 8, 0) )); JLabel contentTitle = new JLabel("日志内容"); contentTitle.setFont(new Font("Microsoft YaHei", Font.BOLD, 14)); contentTitle.setForeground(TEXT_COLOR); contentHeader.add(contentTitle, BorderLayout.WEST); // 创建文本域 contentTextArea = new JTextArea(); contentTextArea.setEditable(false); contentTextArea.setBackground(DARK_LIGHT_COLOR); contentTextArea.setForeground(TEXT_COLOR); contentTextArea.setFont(new Font("宋体", Font.PLAIN, 12)); contentTextArea.setLineWrap(true); contentTextArea.setWrapStyleWord(true); contentTextArea.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); // 创建滚动面板 textScrollPane = new JScrollPane(contentTextArea); textScrollPane.setBorder(BorderFactory.createEmptyBorder()); textScrollPane.getVerticalScrollBar().setUnitIncrement(16); textScrollPane.setOpaque(false); textScrollPane.getViewport().setOpaque(false); // 底部信息栏 JPanel footerPanel = new JPanel(new BorderLayout()); footerPanel.setBackground(DARK_LIGHT_COLOR); footerPanel.setOpaque(true); footerPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, new Color(255, 255, 255, 25))); footerPanel.setPreferredSize(new Dimension(432, 30)); JLabel noteLabel = new JLabel("最多保留最近1000条记录"); noteLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11)); noteLabel.setForeground(TEXT_LIGHT_COLOR); noteLabel.setOpaque(false); footerPanel.add(noteLabel, BorderLayout.EAST); panel.add(contentHeader, BorderLayout.NORTH); panel.add(textScrollPane, BorderLayout.CENTER); panel.add(footerPanel, BorderLayout.SOUTH); return panel; } private void setupEventListeners() { // 返回按钮 backButton.addActionListener(e -> { dispose(); }); // 删除全部记录按钮 deleteAllButton.addActionListener(e -> { deleteAllRecords(); }); // 日志记录按钮 logButton.addActionListener(e -> { switchToLogType("log"); }); // 错误日志按钮 errorLogButton.addActionListener(e -> { switchToLogType("error"); }); } // 切换日志类型 private void switchToLogType(String logType) { if (currentLogType.equals(logType)) { return; // 已经是当前类型,无需切换 } currentLogType = logType; // 更新按钮状态 if (logType.equals("log")) { logButton.setBackground(ACTIVE_BUTTON_COLOR); errorLogButton.setBackground(PRIMARY_COLOR); } else { logButton.setBackground(PRIMARY_COLOR); errorLogButton.setBackground(ACTIVE_BUTTON_COLOR); } // 加载对应类型的日志内容 loadLogContent(); } // 删除全部记录的方法 private void deleteAllRecords() { // 确认对话框 String logTypeName = currentLogType.equals("log") ? "操作" : "错误"; int result = JOptionPane.showConfirmDialog( this, "确定要删除所有" + logTypeName + "记录吗?此操作不可恢复!", "确认删除", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE ); if (result == JOptionPane.YES_OPTION) { try { String fileName = currentLogType.equals("log") ? "log.properties" : "err.properties"; File logFile = new File(fileName); if (logFile.exists()) { // 创建空的Properties对象并写入文件 Properties emptyProps = new Properties(); try (FileOutputStream out = new FileOutputStream(logFile); OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8")) { emptyProps.store(writer, "发卡机" + logTypeName + "记录 - 所有记录已清空"); } // 更新文本域显示 contentTextArea.setText("所有" + logTypeName + "记录已成功删除。\n\n日志文件已清空。"); // 显示成功消息 JOptionPane.showMessageDialog( this, "所有" + logTypeName + "记录已成功删除。", "删除成功", JOptionPane.INFORMATION_MESSAGE ); } else { contentTextArea.setText(logTypeName + "日志文件不存在,无需删除。"); } } catch (IOException ex) { ex.printStackTrace(); JOptionPane.showMessageDialog( this, "删除记录时出错: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE ); } } } // 加载日志内容 private void loadLogContent() { String fileName = currentLogType.equals("log") ? "log.properties" : "err.properties"; String logTypeName = currentLogType.equals("log") ? "操作" : "错误"; File logFile = new File(fileName); if (!logFile.exists()) { contentTextArea.setText(logTypeName + "日志文件不存在。"); return; } Properties logProps = new Properties(); try (FileInputStream in = new FileInputStream(logFile); InputStreamReader reader = new InputStreamReader(in, "UTF-8")) { logProps.load(reader); // 检查记录数量,如果超过1000条则删除旧记录 if (logProps.size() > 1000) { trimLogProperties(logProps, fileName); } // 构建显示内容 StringBuilder content = new StringBuilder(); content.append(logTypeName).append("日志内容 (").append(logProps.size()).append(" 条记录):\n\n"); // 按时间戳排序显示 logProps.stringPropertyNames().stream() .sorted((a, b) -> { try { // 从键中提取时间戳部分进行比较 long timeA = extractTimestampFromKey(a); long timeB = extractTimestampFromKey(b); return Long.compare(timeB, timeA); // 降序排列,最新的在前 } catch (Exception e) { return b.compareTo(a); // 如果提取失败,使用字符串比较 } }) .forEach(key -> { String value = logProps.getProperty(key); content.append("时间: ").append(extractTimeFromValue(value)).append("\n"); content.append("内容: ").append(extractOperationFromValue(value)).append("\n"); content.append("----------------------------------------\n"); }); contentTextArea.setText(content.toString()); } catch (IOException e) { e.printStackTrace(); contentTextArea.setText("加载" + logTypeName + "日志文件时出错: " + e.getMessage()); } catch (Exception e) { e.printStackTrace(); contentTextArea.setText("处理" + logTypeName + "日志内容时出错: " + e.getMessage()); } } // 从键中提取时间戳 private long extractTimestampFromKey(String key) { try { // 键的格式: log_时间戳_UUID 或 error_时间戳_UUID String[] parts = key.split("_"); if (parts.length >= 2) { return Long.parseLong(parts[1]); } } catch (Exception e) { // 如果解析失败,返回0 } return 0L; } // 从值中提取时间部分 private String extractTimeFromValue(String value) { if (value == null) return "未知时间"; // 值的格式: [2025-11-21 14:44:39] 取卡操作:卡槽19被管理员取卡 int start = value.indexOf('['); int end = value.indexOf(']'); if (start >= 0 && end > start) { return value.substring(start + 1, end); } return value; } // 从值中提取操作部分 private String extractOperationFromValue(String value) { if (value == null) return "未知内容"; // 值的格式: [2025-11-21 14:44:39] 取卡操作:卡槽19被管理员取卡 int end = value.indexOf(']'); if (end >= 0 && end + 1 < value.length()) { return value.substring(end + 1).trim(); } return value; } // 修剪日志属性,只保留最新的1000条记录 private void trimLogProperties(Properties logProps, String fileName) { // 按时间戳排序,保留最新的1000条 logProps.stringPropertyNames().stream() .sorted((a, b) -> { try { long timeA = extractTimestampFromKey(a); long timeB = extractTimestampFromKey(b); return Long.compare(timeB, timeA); } catch (Exception e) { return b.compareTo(a); } }) .skip(1000) .forEach(logProps::remove); // 保存修剪后的属性 try (FileOutputStream out = new FileOutputStream(fileName); OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8")) { String logTypeName = fileName.equals("log.properties") ? "操作" : "错误"; logProps.store(writer, "发卡机" + logTypeName + "记录 - 自动修剪至1000条记录"); } catch (IOException e) { e.printStackTrace(); } } // 新增辅助方法:使颜色更亮 private Color brighterColor(Color color) { int r = Math.min(255, color.getRed() + 30); int g = Math.min(255, color.getGreen() + 30); int b = Math.min(255, color.getBlue() + 30); return new Color(r, g, b); } // 静态方法:从其他页面调用 public static void showHistoryDialog(JFrame parent) { SwingUtilities.invokeLater(() -> { lishijilu dialog = new lishijilu(parent); dialog.setVisible(true); }); } }