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);
|
});
|
}
|
}
|