package xitongshezhi;
|
|
import javax.swing.*;
|
import javax.swing.table.DefaultTableModel;
|
import java.awt.*;
|
import java.awt.event.*;
|
import java.text.SimpleDateFormat;
|
import java.util.*;
|
import java.util.List;
|
|
public class lishijilu extends JFrame {
|
private JPanel mainPanel;
|
private JLabel titleLabel;
|
private JButton backButton;
|
|
// 控制面板组件
|
private JPanel controlPanel;
|
private JLabel totalRecordsLabel;
|
private JLabel pickupCountLabel;
|
private JLabel returnCountLabel;
|
private JLabel adminCountLabel;
|
private JButton refreshButton;
|
private JButton clearButton;
|
|
// 表格组件
|
private JScrollPane tableScrollPane;
|
private JTable historyTable;
|
private DefaultTableModel tableModel;
|
private JLabel displayCountLabel;
|
|
// 历史记录数据
|
private List<HistoryRecord> historyRecords;
|
private final int MAX_RECORDS = 100;
|
|
// 颜色定义
|
private final Color BACKGROUND_COLOR = new Color(15, 28, 48);
|
private final Color CARD_COLOR = new Color(26, 43, 68);
|
private final Color PRIMARY_COLOR = new Color(52, 152, 219);
|
private final Color SECONDARY_COLOR = new Color(46, 204, 113);
|
private final Color DANGER_COLOR = new Color(231, 76, 60);
|
private final Color WARNING_COLOR = new Color(243, 156, 18);
|
private final Color TEXT_COLOR = new Color(224, 224, 224);
|
private final Color TEXT_LIGHT_COLOR = new Color(160, 200, 255);
|
|
public lishijilu() {
|
historyRecords = new ArrayList<>();
|
initializeUI();
|
setupEventListeners();
|
loadDemoData(); // 加载演示数据
|
updateDisplay();
|
}
|
|
private void initializeUI() {
|
// 设置窗口属性 - 7寸竖屏 (480x800)
|
setTitle("历史记录 - UWB人员定位卡发卡机管理系统");
|
setSize(480, 800);
|
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
setLocationRelativeTo(null);
|
setResizable(false);
|
|
// 设置不透明背景
|
getContentPane().setBackground(BACKGROUND_COLOR);
|
|
// 主面板
|
mainPanel = new JPanel();
|
mainPanel.setLayout(new BorderLayout());
|
mainPanel.setBackground(BACKGROUND_COLOR);
|
mainPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
|
|
// 创建顶部标题栏
|
JPanel headerPanel = createHeaderPanel();
|
|
// 创建控制面板
|
controlPanel = createControlPanel();
|
|
// 创建表格区域
|
JPanel tablePanel = createTablePanel();
|
|
mainPanel.add(headerPanel, BorderLayout.NORTH);
|
mainPanel.add(controlPanel, BorderLayout.CENTER);
|
mainPanel.add(tablePanel, BorderLayout.SOUTH);
|
|
add(mainPanel);
|
}
|
|
private JPanel createHeaderPanel() {
|
JPanel panel = new JPanel(new BorderLayout());
|
panel.setBackground(BACKGROUND_COLOR);
|
panel.setPreferredSize(new Dimension(464, 40));
|
|
// 标题
|
titleLabel = new JLabel("历史记录");
|
titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
|
titleLabel.setForeground(TEXT_COLOR);
|
titleLabel.setIcon(createIcon("📜", 20));
|
|
// 返回按钮
|
backButton = new JButton("返回");
|
backButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 12));
|
backButton.setBackground(new Color(52, 152, 219, 50));
|
backButton.setForeground(PRIMARY_COLOR);
|
backButton.setBorder(BorderFactory.createCompoundBorder(
|
BorderFactory.createLineBorder(new Color(52, 152, 219, 75), 1),
|
BorderFactory.createEmptyBorder(6, 12, 6, 12)
|
));
|
backButton.setFocusPainted(false);
|
backButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
|
|
panel.add(titleLabel, BorderLayout.WEST);
|
panel.add(backButton, BorderLayout.EAST);
|
|
return panel;
|
}
|
|
private JPanel createControlPanel() {
|
JPanel panel = new JPanel(new BorderLayout());
|
panel.setBackground(CARD_COLOR);
|
panel.setBorder(BorderFactory.createCompoundBorder(
|
BorderFactory.createLineBorder(new Color(52, 152, 219, 25), 1),
|
BorderFactory.createEmptyBorder(12, 12, 12, 12)
|
));
|
panel.setPreferredSize(new Dimension(464, 80));
|
|
// 统计信息面板
|
JPanel statsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 15, 0));
|
statsPanel.setBackground(CARD_COLOR);
|
|
// 总记录
|
JPanel totalPanel = createStatItem("总记录", "0");
|
totalRecordsLabel = (JLabel) ((JPanel) totalPanel.getComponent(0)).getComponent(0);
|
|
// 取卡数量
|
JPanel pickupPanel = createStatItem("取卡", "0");
|
pickupCountLabel = (JLabel) ((JPanel) pickupPanel.getComponent(0)).getComponent(0);
|
|
// 还卡数量
|
JPanel returnPanel = createStatItem("还卡", "0");
|
returnCountLabel = (JLabel) ((JPanel) returnPanel.getComponent(0)).getComponent(0);
|
|
// 管理员操作
|
JPanel adminPanel = createStatItem("管理员操作", "0");
|
adminCountLabel = (JLabel) ((JPanel) adminPanel.getComponent(0)).getComponent(0);
|
|
statsPanel.add(totalPanel);
|
statsPanel.add(pickupPanel);
|
statsPanel.add(returnPanel);
|
statsPanel.add(adminPanel);
|
|
// 按钮面板
|
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 8, 0));
|
buttonPanel.setBackground(CARD_COLOR);
|
|
// 刷新按钮
|
refreshButton = new JButton("刷新");
|
refreshButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 12));
|
refreshButton.setBackground(new Color(46, 204, 113, 50));
|
refreshButton.setForeground(SECONDARY_COLOR);
|
refreshButton.setBorder(BorderFactory.createCompoundBorder(
|
BorderFactory.createLineBorder(new Color(46, 204, 113, 75), 1),
|
BorderFactory.createEmptyBorder(6, 12, 6, 12)
|
));
|
refreshButton.setFocusPainted(false);
|
refreshButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
|
|
// 清空按钮
|
clearButton = new JButton("清空");
|
clearButton.setFont(new Font("Microsoft YaHei", Font.BOLD, 12));
|
clearButton.setBackground(new Color(231, 76, 60, 50));
|
clearButton.setForeground(DANGER_COLOR);
|
clearButton.setBorder(BorderFactory.createCompoundBorder(
|
BorderFactory.createLineBorder(new Color(231, 76, 60, 75), 1),
|
BorderFactory.createEmptyBorder(6, 12, 6, 12)
|
));
|
clearButton.setFocusPainted(false);
|
clearButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
|
|
buttonPanel.add(refreshButton);
|
buttonPanel.add(clearButton);
|
|
panel.add(statsPanel, BorderLayout.WEST);
|
panel.add(buttonPanel, BorderLayout.EAST);
|
|
return panel;
|
}
|
|
private JPanel createStatItem(String label, String value) {
|
JPanel panel = new JPanel();
|
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
panel.setBackground(CARD_COLOR);
|
panel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
JLabel valueLabel = new JLabel(value);
|
valueLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 16));
|
valueLabel.setForeground(TEXT_COLOR);
|
valueLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
JLabel nameLabel = new JLabel(label);
|
nameLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
|
nameLabel.setForeground(TEXT_LIGHT_COLOR);
|
nameLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
|
panel.add(valueLabel);
|
panel.add(nameLabel);
|
|
return panel;
|
}
|
|
private JPanel createTablePanel() {
|
JPanel panel = new JPanel(new BorderLayout());
|
panel.setBackground(CARD_COLOR);
|
panel.setBorder(BorderFactory.createCompoundBorder(
|
BorderFactory.createLineBorder(new Color(52, 152, 219, 25), 1),
|
BorderFactory.createEmptyBorder(12, 12, 12, 12)
|
));
|
panel.setPreferredSize(new Dimension(464, 600));
|
|
// 创建表格
|
String[] columnNames = {"时间", "卡槽编号", "操作", "操作对象"};
|
tableModel = new DefaultTableModel(columnNames, 0) {
|
@Override
|
public boolean isCellEditable(int row, int column) {
|
return false; // 表格不可编辑
|
}
|
};
|
|
historyTable = new JTable(tableModel);
|
historyTable.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
|
historyTable.setRowHeight(25);
|
historyTable.setSelectionBackground(new Color(52, 152, 219, 100));
|
historyTable.setGridColor(new Color(255, 255, 255, 50));
|
historyTable.setShowGrid(true);
|
historyTable.setIntercellSpacing(new Dimension(1, 1));
|
|
// 设置表头
|
historyTable.getTableHeader().setFont(new Font("Microsoft YaHei", Font.BOLD, 11));
|
historyTable.getTableHeader().setBackground(new Color(15, 28, 48, 200));
|
historyTable.getTableHeader().setForeground(TEXT_LIGHT_COLOR);
|
historyTable.getTableHeader().setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, new Color(52, 152, 219, 75)));
|
|
// 设置列宽
|
historyTable.getColumnModel().getColumn(0).setPreferredWidth(150); // 时间
|
historyTable.getColumnModel().getColumn(1).setPreferredWidth(80); // 卡槽编号
|
historyTable.getColumnModel().getColumn(2).setPreferredWidth(60); // 操作
|
historyTable.getColumnModel().getColumn(3).setPreferredWidth(80); // 操作对象
|
|
// 自定义渲染器
|
historyTable.setDefaultRenderer(Object.class, new HistoryTableCellRenderer());
|
|
// 滚动面板
|
tableScrollPane = new JScrollPane(historyTable);
|
tableScrollPane.setBorder(BorderFactory.createEmptyBorder());
|
tableScrollPane.getViewport().setBackground(new Color(26, 43, 68, 200));
|
|
// 自定义滚动条
|
JScrollBar verticalScrollBar = tableScrollPane.getVerticalScrollBar();
|
verticalScrollBar.setBackground(CARD_COLOR);
|
verticalScrollBar.setUnitIncrement(16);
|
|
// 底部信息栏
|
JPanel footerPanel = new JPanel(new BorderLayout());
|
footerPanel.setBackground(CARD_COLOR);
|
footerPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, new Color(255, 255, 255, 25)));
|
footerPanel.setPreferredSize(new Dimension(440, 30));
|
|
JLabel infoLabel = new JLabel("显示最近");
|
infoLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
|
infoLabel.setForeground(TEXT_LIGHT_COLOR);
|
|
displayCountLabel = new JLabel("0");
|
displayCountLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 11));
|
displayCountLabel.setForeground(TEXT_LIGHT_COLOR);
|
|
JLabel recordsLabel = new JLabel("条记录");
|
recordsLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
|
recordsLabel.setForeground(TEXT_LIGHT_COLOR);
|
|
JPanel countPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
|
countPanel.setBackground(CARD_COLOR);
|
countPanel.add(infoLabel);
|
countPanel.add(displayCountLabel);
|
countPanel.add(recordsLabel);
|
|
JLabel noteLabel = new JLabel("最多保留最近100条记录");
|
noteLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
|
noteLabel.setForeground(TEXT_LIGHT_COLOR);
|
|
footerPanel.add(countPanel, BorderLayout.WEST);
|
footerPanel.add(noteLabel, BorderLayout.EAST);
|
|
panel.add(tableScrollPane, BorderLayout.CENTER);
|
panel.add(footerPanel, BorderLayout.SOUTH);
|
|
return panel;
|
}
|
|
// 自定义表格单元格渲染器
|
private class HistoryTableCellRenderer extends DefaultTableCellRenderer {
|
@Override
|
public Component getTableCellRendererComponent(JTable table, Object value,
|
boolean isSelected, boolean hasFocus,
|
int row, int column) {
|
Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
|
|
// 设置基本样式
|
comp.setBackground(row % 2 == 0 ?
|
new Color(26, 43, 68, 200) :
|
new Color(255, 255, 255, 10));
|
comp.setForeground(TEXT_COLOR);
|
|
// 设置字体
|
if (column == 0) { // 时间列使用等宽字体
|
comp.setFont(new Font("Courier New", Font.PLAIN, 10));
|
} else {
|
comp.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
|
}
|
|
// 操作列特殊处理
|
if (column == 2 && value != null) {
|
JLabel label = new JLabel(value.toString());
|
label.setOpaque(true);
|
label.setHorizontalAlignment(SwingConstants.CENTER);
|
|
if (value.toString().equals("取卡")) {
|
label.setBackground(new Color(52, 152, 219, 50));
|
label.setForeground(PRIMARY_COLOR);
|
label.setBorder(BorderFactory.createCompoundBorder(
|
BorderFactory.createLineBorder(new Color(52, 152, 219, 75), 1),
|
BorderFactory.createEmptyBorder(2, 8, 2, 8)
|
));
|
} else if (value.toString().equals("还卡")) {
|
label.setBackground(new Color(46, 204, 113, 50));
|
label.setForeground(SECONDARY_COLOR);
|
label.setBorder(BorderFactory.createCompoundBorder(
|
BorderFactory.createLineBorder(new Color(46, 204, 113, 75), 1),
|
BorderFactory.createEmptyBorder(2, 8, 2, 8)
|
));
|
}
|
|
if (isSelected) {
|
label.setBackground(new Color(52, 152, 219, 100));
|
}
|
|
return label;
|
}
|
|
// 操作对象列特殊处理
|
if (column == 3 && value != null) {
|
JLabel label = new JLabel(value.toString());
|
label.setOpaque(true);
|
label.setHorizontalAlignment(SwingConstants.CENTER);
|
|
if (value.toString().equals("系统")) {
|
label.setBackground(new Color(149, 165, 166, 50));
|
label.setForeground(new Color(149, 165, 166));
|
label.setBorder(BorderFactory.createCompoundBorder(
|
BorderFactory.createLineBorder(new Color(149, 165, 166, 75), 1),
|
BorderFactory.createEmptyBorder(2, 8, 2, 8)
|
));
|
} else if (value.toString().equals("管理员")) {
|
label.setBackground(new Color(243, 156, 18, 50));
|
label.setForeground(WARNING_COLOR);
|
label.setBorder(BorderFactory.createCompoundBorder(
|
BorderFactory.createLineBorder(new Color(243, 156, 18, 75), 1),
|
BorderFactory.createEmptyBorder(2, 8, 2, 8)
|
));
|
}
|
|
if (isSelected) {
|
label.setBackground(new Color(52, 152, 219, 100));
|
}
|
|
return label;
|
}
|
|
return comp;
|
}
|
}
|
|
private void setupEventListeners() {
|
// 返回按钮
|
backButton.addActionListener(e -> {
|
dispose();
|
});
|
|
// 刷新按钮
|
refreshButton.addActionListener(e -> {
|
refreshData();
|
});
|
|
// 清空按钮
|
clearButton.addActionListener(e -> {
|
clearAllRecords();
|
});
|
}
|
|
// 历史记录类
|
private static class HistoryRecord {
|
long id;
|
String timestamp;
|
int slotId;
|
String operation; // "pickup" 或 "return"
|
int operator; // 0=系统, 1=管理员
|
|
HistoryRecord(long id, String timestamp, int slotId, String operation, int operator) {
|
this.id = id;
|
this.timestamp = timestamp;
|
this.slotId = slotId;
|
this.operation = operation;
|
this.operator = operator;
|
}
|
}
|
|
// 加载演示数据
|
private void loadDemoData() {
|
if (historyRecords.isEmpty()) {
|
generateDemoData();
|
}
|
}
|
|
// 生成演示数据
|
private void generateDemoData() {
|
String[] operations = {"pickup", "return"};
|
int[] operators = {0, 1}; // 0=系统, 1=管理员
|
long baseTime = System.currentTimeMillis() - (30L * 24 * 60 * 60 * 1000); // 30天前开始
|
|
for (int i = 0; i < 50; i++) {
|
int randomSlot = (int) (Math.random() * 60) + 1;
|
String randomOperation = operations[(int) (Math.random() * operations.length)];
|
int randomOperator = operators[(int) (Math.random() * operators.length)];
|
long randomTime = baseTime + (long) (Math.random() * 30 * 24 * 60 * 60 * 1000);
|
|
historyRecords.add(new HistoryRecord(
|
randomTime,
|
new Date(randomTime).toInstant().toString(),
|
randomSlot,
|
randomOperation,
|
randomOperator
|
));
|
}
|
|
// 按时间排序(最新的在前面)
|
historyRecords.sort((a, b) -> Long.compare(b.id, a.id));
|
|
// 限制为最大记录数
|
if (historyRecords.size() > MAX_RECORDS) {
|
historyRecords = historyRecords.subList(0, MAX_RECORDS);
|
}
|
}
|
|
// 格式化时间显示
|
private String formatTime(String isoString) {
|
try {
|
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
|
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
Date date = inputFormat.parse(isoString);
|
return outputFormat.format(date);
|
} catch (Exception e) {
|
return isoString;
|
}
|
}
|
|
// 获取操作显示文本
|
private String getOperationText(String operation) {
|
return "pickup".equals(operation) ? "取卡" : "还卡";
|
}
|
|
// 获取操作对象显示文本
|
private String getOperatorText(int operator) {
|
return operator == 0 ? "系统" : "管理员";
|
}
|
|
// 更新显示
|
private void updateDisplay() {
|
// 更新表格
|
tableModel.setRowCount(0);
|
|
for (HistoryRecord record : historyRecords) {
|
tableModel.addRow(new Object[]{
|
formatTime(record.timestamp),
|
record.slotId,
|
getOperationText(record.operation),
|
getOperatorText(record.operator)
|
});
|
}
|
|
// 更新统计信息
|
updateStats();
|
}
|
|
// 更新统计信息
|
private void updateStats() {
|
int total = historyRecords.size();
|
int pickupCount = (int) historyRecords.stream()
|
.filter(record -> "pickup".equals(record.operation))
|
.count();
|
int returnCount = (int) historyRecords.stream()
|
.filter(record -> "return".equals(record.operation))
|
.count();
|
int adminCount = (int) historyRecords.stream()
|
.filter(record -> record.operator == 1)
|
.count();
|
|
totalRecordsLabel.setText(String.valueOf(total));
|
pickupCountLabel.setText(String.valueOf(pickupCount));
|
returnCountLabel.setText(String.valueOf(returnCount));
|
adminCountLabel.setText(String.valueOf(adminCount));
|
displayCountLabel.setText(String.valueOf(total));
|
}
|
|
// 刷新数据
|
private void refreshData() {
|
String originalText = refreshButton.getText();
|
|
// 显示刷新中状态
|
refreshButton.setText("刷新中...");
|
refreshButton.setEnabled(false);
|
|
// 模拟数据刷新延迟
|
Timer timer = new Timer(800, e -> {
|
updateDisplay();
|
|
// 恢复按钮状态
|
refreshButton.setText(originalText);
|
refreshButton.setEnabled(true);
|
});
|
timer.setRepeats(false);
|
timer.start();
|
}
|
|
// 清空所有记录
|
private void clearAllRecords() {
|
int result = JOptionPane.showConfirmDialog(
|
this,
|
"确定要清空所有历史记录吗?此操作不可恢复。",
|
"确认清空",
|
JOptionPane.YES_NO_OPTION,
|
JOptionPane.WARNING_MESSAGE
|
);
|
|
if (result == JOptionPane.YES_OPTION) {
|
historyRecords.clear();
|
updateDisplay();
|
}
|
}
|
|
// 添加测试记录(用于演示)
|
private void addTestRecord() {
|
int randomSlot = (int) (Math.random() * 60) + 1;
|
String randomOperation = Math.random() > 0.5 ? "pickup" : "return";
|
int randomOperator = Math.random() > 0.7 ? 1 : 0; // 30%概率为管理员操作
|
|
historyRecords.add(0, new HistoryRecord(
|
System.currentTimeMillis(),
|
new Date().toInstant().toString(),
|
randomSlot,
|
randomOperation,
|
randomOperator
|
));
|
|
// 限制为最大记录数
|
if (historyRecords.size() > MAX_RECORDS) {
|
historyRecords.remove(historyRecords.size() - 1);
|
}
|
|
updateDisplay();
|
}
|
|
// 创建图标(使用文本表情符号)
|
private Icon createIcon(String emoji, int size) {
|
JLabel label = new JLabel(emoji);
|
label.setFont(new Font("Segoe UI Emoji", Font.PLAIN, size));
|
return new Icon() {
|
@Override
|
public void paintIcon(Component c, Graphics g, int x, int y) {
|
label.setBounds(x, y, getIconWidth(), getIconHeight());
|
label.paint(g);
|
}
|
|
@Override
|
public int getIconWidth() {
|
return size;
|
}
|
|
@Override
|
public int getIconHeight() {
|
return size;
|
}
|
};
|
}
|
|
// 主方法测试
|
public static void main(String[] args) {
|
// 设置系统外观
|
try {
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeel());
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
|
SwingUtilities.invokeLater(() -> {
|
lishijilu frame = new lishijilu();
|
frame.setVisible(true);
|
});
|
}
|
}
|