src/dell_targets/Dell_BaseStation.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/dell_targets/Dell_SystemConfiguration.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/dell_targets/Dell_tag.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/udptcp/UDPPortAReceiver.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/window/WelcomeFrame.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
systemfile/Messages_en.properties | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
systemfile/Messages_zh.properties | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
systemfile/logfile/openlog.txt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/dell_targets/Dell_BaseStation.java
@@ -4,18 +4,23 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.ConcurrentHashMap; public class Dell_BaseStation { static List<LocationBaseStation> baseStations; public static List<LocationBaseStation> baseStations; private static ConcurrentHashMap<String, LocationBaseStation> baseStationMap; // 以基站ID为键的映射 public static List<LocationBaseStation> getBaseStations() throws SQLException { baseStations = new ArrayList<>(); baseStationMap = new ConcurrentHashMap<>(); // 修复:初始化映射 ResultSet rs = DBConnector.queryTableData("location_base_station"); if (rs == null) { // 说明底层拿不到数据,直接抛异常或打印日志 throw new SQLException("DBConnector.queryTableData returned null, " + "please check database connection & SQL."); } while (rs.next()) { LocationBaseStation baseStation = new LocationBaseStation(); baseStation.setId((int) rs.getLong("id")); @@ -133,5 +138,43 @@ public static LocationBaseStation getBaseStationById(String baseStationId) { return baseStationMap.get(baseStationId); // O(1)复杂度直接获取 } /** * 获取所有在线状态(onlineStatus=1)的设备(高效内存操作) * @return 不可修改的baseStationMap集合(避免外部修改缓存) */ public static List<LocationBaseStation> getOnlineBaseStations() { if (baseStationMap == null || baseStationMap.isEmpty()) { return Collections.emptyList(); // 缓存为空时返回空集合 } List<LocationBaseStation> BaseStation = new ArrayList<>(); for (LocationBaseStation base : baseStationMap.values()) { if ("1".equals(base.getStatus())) { // 字符串比较避免NPE BaseStation.add(base); } } return Collections.unmodifiableList(BaseStation); // 返回不可变集合 } /** * 快速获取LocationTag对象的总数(使用内存缓存提高性能) * @return LocationTag对象的总数 */ public static int getLocationBaseCount() { if (baseStationMap == null) { synchronized (LocationBaseStation.class) { if (baseStationMap == null) { try { getBaseStations(); // 初始化缓存 } catch (SQLException e) { e.printStackTrace(); return 0; // 初始化失败返回0 } } } } return baseStationMap.size(); } } src/dell_targets/Dell_SystemConfiguration.java
@@ -15,6 +15,8 @@ public static boolean xytognssOpen=false; public static boolean gnsstoxyOpen=false; public static String language="0"; public static int hexport=8234; public static int ascallport=7000; // 获取系统配置列表 public static List<SystemConfiguration> getSystemConfigurations() { // 创建配置对象列表 @@ -40,9 +42,14 @@ // 数据库密码 config.setDatabasePassword(rs.getString("database_password")); // HEX数据UDP接收端口 config.setHexDataUdpReceivePort(rs.getString("hex_data_udp_receive_port")); String hexp=rs.getString("hex_data_udp_receive_port"); hexport=Integer.parseInt(hexp); config.setHexDataUdpReceivePort(hexp); String ascll=rs.getString("ascii_data_udp_receive_port"); ascallport=Integer.parseInt(ascll);; // ASCII数据UDP接收端口 config.setAsciiDataUdpReceivePort(rs.getString("ascii_data_udp_receive_port")); config.setAsciiDataUdpReceivePort(ascll); // TCP数据接收端口1 config.setTcpDataReceivePort1(rs.getString("tcp_data_receive_port1")); // TCP数据接收端口2 src/dell_targets/Dell_tag.java
@@ -4,12 +4,21 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.ConcurrentHashMap; public class Dell_tag { static List<LocationTag> locationTags; public static List<LocationTag> locationTags; private static ConcurrentHashMap<String, LocationTag> tagMap; // 设备ID->标签对象的映射 public static List<LocationTag> getlocationTags() throws SQLException{ List<LocationTag> locationTags = new ArrayList<>(); List<LocationTag> locationTags = new ArrayList<>(); tagMap = new ConcurrentHashMap<>(); // 初始化映射 ResultSet rs =DBConnector.queryTableData("location_tag"); if (rs == null) { // 说明底层拿不到数据,直接抛异常或打印日志 throw new SQLException("DBConnector.queryTableData returned null, " + "please check database connection & SQL."); } while (rs.next()) { LocationTag locationTag = new LocationTag(); locationTag.setId((int) rs.getLong("id")); @@ -98,6 +107,7 @@ locationTag.setIpAddress(rs.getString("ipAddress")); locationTag.setIpPort(rs.getString("Interaction_Type")); locationTags.add(locationTag); tagMap.put(locationTag.getDeviceNumber(), locationTag); // 添加到映射 } return locationTags; } @@ -119,6 +129,117 @@ DBConnector.executeUpdate(sql, deviceId); } /** * 根据设备ID高效修改属性值 * @param deviceId 设备ID(device_id) * @param propertyName 属性名(需与setter方法匹配) * @param value 新属性值 */ public static void updateLocationTagProperty(String deviceId, String propertyName, String value) { LocationTag tag = tagMap.get(deviceId); if (tag == null) return; // 标签不存在则忽略 // 根据属性名调用对应setter switch (propertyName) { case "id": tag.setId(Integer.parseInt(value)); break; case "deviceNumber": tag.setDeviceNumber(value); break; case "deviceName": tag.setDeviceName(value); break; case "deviceVersion": tag.setDeviceVersion(value); break; case "deviceCardNumber": tag.setDeviceCardNumber(value); break; case "deviceType": tag.setDeviceType(value); break; case "team": tag.setTeam(value); break; case "group": tag.setGroup(value); break; case "department": tag.setDepartment(value); break; case "iconAddress": tag.setIconAddress(value); break; case "gender": tag.setGender(value); break; case "ethnicity": tag.setEthnicity(value); break; case "communicationAddress": tag.setCommunicationAddress(value); break; case "boundPhone": tag.setBoundPhone(value); break; case "idNumber": tag.setIdNumber(value); break; case "position": tag.setPosition(value); break; case "boundPlateNumber": tag.setBoundPlateNumber(value); break; case "faceAddress": tag.setFaceAddress(value); break; case "heartRate": tag.setHeartRate(value); break; case "bloodPressure": tag.setBloodPressure(value); break; case "bloodOxygen": tag.setBloodOxygen(value); break; case "temperature": tag.setTemperature(value); break; case "sosStatus": tag.setSosStatus(value); break; case "motionStatus": tag.setMotionStatus(value); break; case "onlineStatus": tag.setOnlineStatus(value); break; case "searchStatus": tag.setSearchStatus(value); break; case "batteryStatus": tag.setBatteryStatus(value); break; case "deviceBattery": tag.setDeviceBattery(value); break; case "removalStatus": tag.setRemovalStatus(value); break; case "collisionStatus": tag.setCollisionStatus(value); break; case "elevationStatus": tag.setElevationStatus(value); break; case "gatheringCount": tag.setGatheringCount(value); break; case "proximityAlarm": tag.setProximityAlarm(value); break; case "area": tag.setArea(value); break; case "xCoordinate": tag.setXCoordinate(value); break; case "yCoordinate": tag.setYCoordinate(value); break; case "zCoordinate": tag.setZCoordinate(value); break; case "floor": tag.setFloor(value); break; case "speed": tag.setSpeed(value); break; case "locationSource": tag.setLocationSource(value); break; case "lastUwbSignalTime": tag.setLastUwbSignalTime(value); break; case "lastSatelliteSignalTime": tag.setLastSatelliteSignalTime(value); break; case "uwbTimeSlot": tag.setUwbTimeSlot(value); break; case "latestRangingSeq": tag.setLatestRangingSeq(value); break; case "latestRangingBaseId": tag.setLatestRangingBaseId(value); break; case "latestRangingDistance": tag.setLatestRangingDistance(value); break; case "latestRangingBaseCount": tag.setLatestRangingBaseCount(value); break; case "latestRangingSignalStrength": tag.setLatestRangingSignalStrength(value); break; case "utcTime": tag.setUtcTime(value); break; case "latitude": tag.setLatitude(value); break; case "longitude": tag.setLongitude(value); break; case "satelliteQuality": tag.setSatelliteQuality(value); break; case "hdop": tag.setHdop(value); break; case "satelliteCount": tag.setSatelliteCount(value); break; case "altitude": tag.setAltitude(value); break; case "differentialTime": tag.setDifferentialTime(value); break; case "geoidHeight": tag.setGeoidHeight(value); break; case "satelliteSpeed": tag.setSatelliteSpeed(value); break; case "lastBarometricValue": tag.setLastBarometricValue(value); break; case "recentCoordinates": tag.setRecentCoordinates(value); break; case "recentBarometricValues": tag.setRecentBarometricValues(value); break; case "offlineTime": tag.setOfflineTime(value); break; case "onlineTime": tag.setOnlineTime(value); break; case "offlineDuration": tag.setOfflineDuration(value); break; case "onlineDuration": tag.setOnlineDuration(value); break; case "motionlessStartTime": tag.setMotionlessStartTime(value); break; case "motionlessEndTime": tag.setMotionlessEndTime(value); break; case "motionlessDuration": tag.setMotionlessDuration(value); break; case "validSatelliteSignal": tag.setValidSatelliteSignal(value); break; case "company": tag.setCompany(value); break; case "sleepTime": tag.setSleepTime(value); break; case "vibrationTime": tag.setVibrationTime(value); break; case "frequency": tag.setFrequency(value); break; case "motionlessTime": tag.setMotionlessTime(value); break; case "accelerationValue": tag.setAccelerationValue(value); break; case "imuTime": tag.setImuTime(value); break; case "reserved1": tag.setReserved1(value); break; case "reserved2": tag.setReserved2(value); break; case "reserved3": tag.setReserved3(value); break; case "reserved4": tag.setReserved4(value); break; case "reserved5": tag.setReserved5(value); break; case "ipAndPort": tag.setIpAndPort(value); break; case "interactionType": tag.setInteractionType(value); break; case "ipAddress": tag.setIpAddress(value); break; case "ipPort": tag.setIpPort(value); break; default: throw new IllegalArgumentException("无效属性: " + propertyName); } } /** * 根据设备ID获取标签对象(高效访问) * @param deviceId 设备ID * @return 标签对象(不存在返回null) */ public static LocationTag getTagByDeviceId(String deviceId) { return tagMap.get(deviceId); } //获取所有的tagid public static List<String> getAlldeviceIds() { List<String> types = new ArrayList<>(); @@ -134,4 +255,42 @@ } return types; } /** * 获取所有在线状态(onlineStatus=1)的设备(高效内存操作) * @return 不可修改的LocationTag集合(避免外部修改缓存) */ public static List<LocationTag> getOnlineLocationTags() { if (tagMap == null || tagMap.isEmpty()) { return Collections.emptyList(); // 缓存为空时返回空集合 } List<LocationTag> onlineTags = new ArrayList<>(); for (LocationTag tag : tagMap.values()) { if ("1".equals(tag.getOnlineStatus())) { // 字符串比较避免NPE onlineTags.add(tag); } } return Collections.unmodifiableList(onlineTags); // 返回不可变集合 } /** * 快速获取LocationTag对象的总数(使用内存缓存提高性能) * @return LocationTag对象的总数 */ public static int getLocationTagCount() { if (tagMap == null) { synchronized (Dell_tag.class) { if (tagMap == null) { try { getlocationTags(); // 初始化缓存 } catch (SQLException e) { e.printStackTrace(); return 0; // 初始化失败返回0 } } } } return tagMap.size(); } } src/udptcp/UDPPortAReceiver.java
@@ -7,106 +7,110 @@ import java.util.concurrent.atomic.AtomicLong; import dell_system.MessageViewPanel; import dell_targets.Dell_SystemConfiguration; public class UDPPortAReceiver { public static final int PORT = 8234; @SuppressWarnings("unused") public static final int PORT =Dell_SystemConfiguration.hexport; @SuppressWarnings("unused") private static final int MAX_DEVICES = 50000; private static final AtomicLong packetCount = new AtomicLong(0); private static final ExecutorService executor = Executors.newFixedThreadPool(10); private static DatagramSocket socket; private static volatile boolean isRunning = false; private static Thread receiverThread; @SuppressWarnings("unused") private static final AtomicLong packetCount = new AtomicLong(0); private static final ExecutorService executor = Executors.newFixedThreadPool(10); private static DatagramSocket socket; private static volatile boolean isRunning = false; private static Thread receiverThread; @SuppressWarnings("unused") private static final int LOCAL_PORT = PORT; // 定义本地端口 // 启动接收器的静态方法 public static void startReceiver() { if (isRunning) return; isRunning = true; receiverThread = new Thread(() -> { try { socket = new DatagramSocket(PORT); byte[] buffer = new byte[2048]; while (isRunning) { DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); executor.execute(() -> { try { String ip = packet.getAddress().getHostAddress(); int port = packet.getPort(); String hexData = bytesToHex(packet.getData(), packet.getLength()); // 调用时添加本地端口参数 PacketProcessingSystem.storePacket(ip, port, hexData); // 报文查看窗口显示数据 MessageViewPanel.showData(hexData, ip, port, PORT,"1"); } catch (Exception e) { System.err.println("Error processing UDP-A packet: " + e.getMessage()); } }); } } catch (Exception e) { System.err.println("UDP-A Server crashed: " + e.getMessage()); } finally { if (socket != null && !socket.isClosed()) { socket.close(); } } }); receiverThread.setDaemon(true); receiverThread.start(); } // 停止接收器 public static void stopReceiver() { isRunning = false; if (socket != null && !socket.isClosed()) { socket.close(); } executor.shutdown(); } // 发送数据到指定设备 public static void sendData(String ip, int port, String data, boolean isHex) { try { byte[] sendBytes; if (isHex) { // HEX格式发送:将十六进制字符串转换为字节数组 sendBytes = hexStringToByteArray(data); } else { // ASCII格式发送:直接获取字节数组 sendBytes = data.getBytes(); } InetAddress address = InetAddress.getByName(ip); DatagramPacket packet = new DatagramPacket(sendBytes, sendBytes.length, address, port); socket.send(packet); } catch (Exception e) { System.err.println("Error sending UDP data: " + e.getMessage()); } } private static String bytesToHex(byte[] bytes, int length) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < length; i++) { sb.append(String.format("%02X", bytes[i])); } return sb.toString(); } private static byte[] hexStringToByteArray(String hex) { hex = hex.replaceAll("\\s", ""); // 移除所有空格 int len = hex.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { // 处理每两个字符作为一个字节 data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i+1), 16)); } return data; } // 启动接收器的静态方法 public static void startReceiver() { if (isRunning) return; isRunning = true; receiverThread = new Thread(() -> { try { socket = new DatagramSocket(PORT); byte[] buffer = new byte[2048]; while (isRunning) { DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); executor.execute(() -> { try { String ip = packet.getAddress().getHostAddress(); int port = packet.getPort(); String hexData = bytesToHex(packet.getData(), packet.getLength()); // 调用时添加本地端口参数 PacketProcessingSystem.storePacket(ip, port, hexData); // 报文查看窗口显示数据 MessageViewPanel.showData(hexData, ip, port, PORT,"1"); // +++ 增加包计数 +++ packetCount.incrementAndGet(); // 关键修复:增加计数器 } catch (Exception e) { System.err.println("Error processing UDP-A packet: " + e.getMessage()); } }); } } catch (Exception e) { System.err.println("UDP-A Server crashed: " + e.getMessage()); } finally { if (socket != null && !socket.isClosed()) { socket.close(); } } }); receiverThread.setDaemon(true); receiverThread.start(); } public static long getPacketCount() { return packetCount.get(); } // 停止接收器 public static void stopReceiver() { isRunning = false; if (socket != null && !socket.isClosed()) { socket.close(); } executor.shutdown(); } // 发送数据到指定设备 public static void sendData(String ip, int port, String data, boolean isHex) { try { byte[] sendBytes; if (isHex) { // HEX格式发送:将十六进制字符串转换为字节数组 sendBytes = hexStringToByteArray(data); } else { // ASCII格式发送:直接获取字节数组 sendBytes = data.getBytes(); } InetAddress address = InetAddress.getByName(ip); DatagramPacket packet = new DatagramPacket(sendBytes, sendBytes.length, address, port); socket.send(packet); } catch (Exception e) { System.err.println("Error sending UDP data: " + e.getMessage()); } } private static String bytesToHex(byte[] bytes, int length) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < length; i++) { sb.append(String.format("%02X", bytes[i])); } return sb.toString(); } private static byte[] hexStringToByteArray(String hex) { hex = hex.replaceAll("\\s", ""); // 移除所有空格 int len = hex.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { // 处理每两个字符作为一个字节 data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i+1), 16)); } return data; } // 获取接收到的数据包总数 public static long getPacketCount() { return packetCount.get(); } } src/window/WelcomeFrame.java
@@ -1,213 +1,237 @@ package window; // 包声明 import java.awt.*; // 导入AWT包 import java.sql.Connection; // 导入数据库连接类 import java.sql.ResultSet; // 导入结果集类 import java.sql.Statement; // 导入SQL语句类 import javax.swing.*; // 导入Swing包 import javax.swing.border.EmptyBorder; // 导入空边框类 import java.util.ResourceBundle; // 导入资源束类 import udptcp.UDPPortAReceiver; // 导入UDP端口A接收器 import udptcp.UDPPortBReceiver; // 导入UDP端口B接收器 import javax.swing.plaf.basic.BasicInternalFrameUI; // 导入基础内部框架UI package window; public class WelcomeFrame extends JInternalFrame { // 欢迎框架类 private static final long serialVersionUID = 1L; // 序列化版本ID private ResourceBundle messages; // 消息资源束 private Connection conn; // 数据库连接 private Timer statsTimer; // 统计定时器 private JLabel udpAPacketCountLabel; // UDP端口A包计数标签 private JLabel udpBPacketCountLabel; // UDP端口B包计数标签 private JLabel memoryUsageLabel; // 内存使用标签 private JLabel threadCountLabel; // 线程计数标签 import java.awt.*; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.util.ResourceBundle; import udptcp.UDPPortAReceiver; import udptcp.UDPPortBReceiver; import dell_targets.Dell_BaseStation; import dell_targets.Dell_tag; import dell_targets.Dell_SystemConfiguration; public WelcomeFrame(ResourceBundle messages, Connection conn) { // 构造函数 super("", true, true, true, true); // 调用父类构造函数,设置标题为空 this.messages = messages; // 初始化消息资源束 this.conn = conn; // 初始化数据库连接 public class WelcomeFrame extends JInternalFrame { private static final long serialVersionUID = 1L; private final ResourceBundle messages; private final Connection conn; private Timer statsTimer; private JLabel memoryUsageLabel; private JLabel threadCountLabel; private JLabel tagStatsLabel; private JLabel baseStationStatsLabel; private JLabel dbVersionLabel; private JLabel udpAInfoLabel; private JLabel udpBInfoLabel; public WelcomeFrame(ResourceBundle messages, Connection conn) { super("", true, true, true, true); this.messages = messages; this.conn = conn; initializeFrame(); // 初始化框架 setContentPane(createWelcomePanel()); // 设置内容面板 startStatsTimer(); // 启动统计定时器 initializeFrame(); setContentPane(createWelcomePanel()); startStatsTimer(); } private void initializeFrame() { // 初始化框架方法 setSize(900, 700); // 设置框架大小 setLocation(100, 100); // 设置框架位置 setMaximizable(true); // 设置可最大化 setIconifiable(true); // 设置可图标化 setClosable(true); // 设置可关闭 setBorder(null); // 移除边框 setVisible(true); // 设置可见 private void initializeFrame() { setSize(900, 700); setLocation(100, 100); setMaximizable(true); setIconifiable(true); setClosable(true); setBorder(null); // 移除标题栏 BasicInternalFrameUI ui = (BasicInternalFrameUI) this.getUI(); // 获取UI组件 ui.setNorthPane(null); // 移除标题栏 ((javax.swing.plaf.basic.BasicInternalFrameUI)this.getUI()).setNorthPane(null); try { setMaximum(true); // 尝试最大化窗口 setMaximum(true); } catch (java.beans.PropertyVetoException e) { e.printStackTrace(); // 打印异常堆栈 e.printStackTrace(); } setVisible(true); // 确保框架可见 } private JPanel createWelcomePanel() { // 创建欢迎面板方法 JPanel panel = new BackgroundPanel(); // 创建背景面板 panel.setLayout(new BorderLayout()); // 设置边界布局 panel.setBorder(new EmptyBorder(30, 30, 30, 30)); // 设置空边框 private JPanel createWelcomePanel() { JPanel panel = new JPanel(new BorderLayout()); panel.setBorder(new EmptyBorder(30, 30, 30, 30)); panel.setBackground(new Color(245, 248, 255)); // 创建标题面板 JPanel titlePanel = new JPanel(new BorderLayout()); // 创建边界布局面板 titlePanel.setOpaque(false); // 设置透明 // 标题面板 JPanel titlePanel = new JPanel(new BorderLayout()); titlePanel.setOpaque(false); titlePanel.setBorder(new EmptyBorder(0, 0, 30, 0)); JLabel titleLabel = new JLabel(messages.getString("APP_NAME"), SwingConstants.CENTER); // 创建应用名称标签 titleLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 42)); // 设置字体 titleLabel.setForeground(new Color(25, 25, 112)); // 设置前景色 titleLabel.setBorder(new EmptyBorder(20, 0, 20, 0)); // 设置空边框 titleLabel.setOpaque(false); // 设置透明 JLabel titleLabel = new JLabel(messages.getString("APP_NAME"), SwingConstants.CENTER); titleLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 42)); titleLabel.setForeground(new Color(25, 25, 112)); JLabel subtitleLabel = new JLabel(messages.getString("WELCOME_MSG"), SwingConstants.CENTER); // 创建欢迎消息标签 subtitleLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.ITALIC, 22)); // 设置字体 subtitleLabel.setForeground(new Color(70, 130, 180)); // 设置前景色 subtitleLabel.setOpaque(false); // 设置透明 JLabel subtitleLabel = new JLabel(messages.getString("WELCOME_MSG"), SwingConstants.CENTER); subtitleLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.ITALIC, 22)); subtitleLabel.setForeground(new Color(70, 130, 180)); subtitleLabel.setBorder(new EmptyBorder(10, 0, 20, 0)); titlePanel.add(titleLabel, BorderLayout.NORTH); // 添加标题到北部 titlePanel.add(subtitleLabel, BorderLayout.CENTER); // 添加副标题到中部 titlePanel.add(titleLabel, BorderLayout.NORTH); titlePanel.add(subtitleLabel, BorderLayout.CENTER); // 创建信息面板 JPanel infoPanel = new JPanel(new GridLayout(0, 2, 20, 20)); // 创建网格布局面板 infoPanel.setBorder(new EmptyBorder(30, 50, 30, 50)); // 设置空边框 infoPanel.setBackground(new Color(255, 255, 255, 180)); // 设置半透明白色背景 infoPanel.setOpaque(true); // 设置不透明 // 主信息面板 JPanel infoPanel = new JPanel(new GridBagLayout()); infoPanel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(new Color(200, 220, 240), 2), new EmptyBorder(30, 40, 30, 40) )); infoPanel.setBackground(new Color(255, 255, 255, 255)); infoPanel.setOpaque(true); // 添加系统状态信息 infoPanel.add(createInfoLabel(messages.getString("SYSTEM_STATUS"), messages.getString("RUNNING_NORMAL"), new Color(0, 100, 0))); // 深绿色 GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(15, 15, 15, 15); gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.HORIZONTAL; // 添加数据库连接信息 infoPanel.add(createInfoLabel(messages.getString("DB_CONNECTION"), conn != null ? messages.getString("CONNECTED") : messages.getString("DISCONNECTED"), conn != null ? new Color(0, 100, 0) : Color.RED)); // 连接成功绿色/失败红色 // 第一列 gbc.gridx = 0; gbc.gridy = 0; try { if (conn != null) { // 检查数据库连接 try (Statement stmt = conn.createStatement(); // 创建语句 ResultSet rs = stmt.executeQuery("SELECT VERSION()")) { // 执行版本查询 if (rs.next()) { // 如果有结果 infoPanel.add(createInfoLabel(messages.getString("DB_VERSION"), rs.getString(1), new Color(25, 25, 112))); // 添加数据库版本 } } } } catch (Exception e) { e.printStackTrace(); // 打印异常 // 修复1: 初始化标签并设置初始文本 tagStatsLabel = new JLabel("0 / 0"); tagStatsLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("TAG_STATS"), tagStatsLabel, new Color(0, 100, 0)), gbc); gbc.gridy++; baseStationStatsLabel = new JLabel("0 / 0"); baseStationStatsLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("BASE_STATION_STATS"), baseStationStatsLabel, new Color(0, 100, 0)), gbc); gbc.gridy++; udpAInfoLabel = new JLabel(Dell_SystemConfiguration.hexport + " - " + messages.getString("RECEIVED_PACKETS") + ": 0"); udpAInfoLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("UDP_PORT_A"), udpAInfoLabel, new Color(178, 34, 34)), gbc); gbc.gridy++; udpBInfoLabel = new JLabel(Dell_SystemConfiguration.ascallport + " - " + messages.getString("RECEIVED_PACKETS") + ": 0"); udpBInfoLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("UDP_PORT_B"), udpBInfoLabel, new Color(178, 34, 34)), gbc); gbc.gridy++; memoryUsageLabel = new JLabel("0 MB / 0 MB"); memoryUsageLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("MEMORY_USAGE"), memoryUsageLabel, new Color(148, 0, 211)), gbc); // 第二列 gbc.gridx = 1; gbc.gridy = 0; threadCountLabel = new JLabel("0"); threadCountLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("THREAD_COUNT"), threadCountLabel, new Color(148, 0, 211)), gbc); gbc.gridy++; dbVersionLabel = new JLabel(""); // 初始为空,稍后设置 dbVersionLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("DB_VERSION"), dbVersionLabel, new Color(25, 25, 112)), gbc); gbc.gridy++; JLabel dbStatusLabel = new JLabel(conn != null ? messages.getString("CONNECTED") : messages.getString("DISCONNECTED")); dbStatusLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); dbStatusLabel.setForeground(conn != null ? new Color(0, 100, 0) : Color.RED); infoPanel.add(createInfoRow(messages.getString("DB_STATUS"), dbStatusLabel, new Color(25, 25, 112)), gbc); gbc.gridy++; JLabel softwareVersionLabel = new JLabel(messages.getString("APP_VERSION")); softwareVersionLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); infoPanel.add(createInfoRow(messages.getString("SOFTWARE_VERSION"), softwareVersionLabel, new Color(25, 25, 112)), gbc); // 初始化数据库版本 if (conn != null && dbVersionLabel.getText().isEmpty()) { updateDbVersion(); } // 添加当前用户信息 infoPanel.add(createInfoLabel(messages.getString("CURRENT_USER"), messages.getString("ADMIN"), new Color(25, 25, 112))); // 深蓝色 // 添加系统时间信息 infoPanel.add(createInfoLabel(messages.getString("SYSTEM_TIME"), new java.util.Date().toString(), new Color(25, 25, 112))); // 深蓝色 // 添加UDP端口A统计 infoPanel.add(createInfoLabel(messages.getString("UDP_PORT_A"), "0", new Color(178, 34, 34))); // 砖红色 udpAPacketCountLabel = createInfoLabel("", "", new Color(178, 34, 34)); // 创建计数标签 infoPanel.add(udpAPacketCountLabel); // 添加计数标签 // 添加UDP端口B统计 infoPanel.add(createInfoLabel(messages.getString("UDP_PORT_B"), "0", new Color(178, 34, 34))); // 砖红色 udpBPacketCountLabel = createInfoLabel("", "", new Color(178, 34, 34)); // 创建计数标签 infoPanel.add(udpBPacketCountLabel); // 添加计数标签 // 添加内存使用统计 infoPanel.add(createInfoLabel(messages.getString("MEMORY_USAGE"), "", new Color(148, 0, 211))); // 紫罗兰色 memoryUsageLabel = createInfoLabel("", "", new Color(148, 0, 211)); // 创建内存标签 infoPanel.add(memoryUsageLabel); // 添加内存标签 // 添加线程计数统计 infoPanel.add(createInfoLabel(messages.getString("THREAD_COUNT"), "", new Color(148, 0, 211))); // 紫罗兰色 threadCountLabel = createInfoLabel("", "", new Color(148, 0, 211)); // 创建线程标签 infoPanel.add(threadCountLabel); // 添加线程标签 // 创建状态面板 JPanel statsPanel = new JPanel(new GridLayout(1, 4, 15, 15)); // 创建网格布局面板 statsPanel.setBorder(new EmptyBorder(20, 50, 10, 50)); // 设置空边框 statsPanel.setOpaque(false); // 设置透明 // 添加统计盒子 statsPanel.add(createStatBox(messages.getString("UDP_PORT_A_STAT"), udpAPacketCountLabel)); // UDP端口A统计 statsPanel.add(createStatBox(messages.getString("UDP_PORT_B_STAT"), udpBPacketCountLabel)); // UDP端口B统计 statsPanel.add(createStatBox(messages.getString("MEMORY_USAGE_STAT"), memoryUsageLabel)); // 内存使用统计 statsPanel.add(createStatBox(messages.getString("THREAD_COUNT_STAT"), threadCountLabel)); // 线程计数统计 // 组装主面板 panel.add(titlePanel, BorderLayout.NORTH); // 添加标题面板到北部 panel.add(infoPanel, BorderLayout.CENTER); // 添加信息面板到中部 panel.add(statsPanel, BorderLayout.SOUTH); // 添加状态面板到南部 panel.add(titlePanel, BorderLayout.NORTH); panel.add(infoPanel, BorderLayout.CENTER); return panel; // 返回面板 return panel; } private JLabel createInfoLabel(String title, String value, Color color) { // 创建信息标签方法 JLabel label = new JLabel("<html><div style='text-align:center;'><b>" + title + "</b><br>" + value + "</div></html>"); // 创建带HTML格式的标签 label.setFont(new Font(messages.getString("FONT_NAME"), Font.PLAIN, 16)); // 设置字体 label.setForeground(color); // 设置前景色 label.setHorizontalAlignment(SwingConstants.CENTER); // 设置水平居中 label.setVerticalAlignment(SwingConstants.CENTER); // 设置垂直居中 label.setOpaque(false); // 设置透明 return label; // 返回标签 private JPanel createInfoRow(String title, JLabel valueLabel, Color color) { JPanel rowPanel = new JPanel(new BorderLayout(10, 0)); rowPanel.setOpaque(false); JLabel titleLabel = new JLabel(title + ":"); titleLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); titleLabel.setForeground(color.darker()); valueLabel.setForeground(color); rowPanel.add(titleLabel, BorderLayout.WEST); rowPanel.add(valueLabel, BorderLayout.CENTER); // 添加装饰器 JPanel decorator = new JPanel(); decorator.setPreferredSize(new Dimension(5, 5)); decorator.setBackground(color); decorator.setOpaque(true); rowPanel.add(decorator, BorderLayout.EAST); return rowPanel; } private JPanel createStatBox(String title, JLabel valueLabel) { // 创建统计盒子方法 JPanel boxPanel = new JPanel(new BorderLayout()); // 创建边界布局面板 boxPanel.setBorder(BorderFactory.createCompoundBorder( // 设置复合边框 BorderFactory.createLineBorder(new Color(70, 130, 180), 2), // 蓝色边框 new EmptyBorder(15, 10, 15, 10) // 内边距 )); boxPanel.setBackground(new Color(240, 248, 255, 220)); // 设置半透明背景 boxPanel.setOpaque(true); // 设置不透明 JLabel titleLabel = new JLabel(title, SwingConstants.CENTER); // 创建标题标签 titleLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 18)); // 设置粗体 titleLabel.setForeground(new Color(25, 25, 112)); // 设置深蓝色 valueLabel.setFont(new Font(messages.getString("FONT_NAME"), Font.BOLD, 24)); // 设置粗体大字号 valueLabel.setHorizontalAlignment(SwingConstants.CENTER); // 设置居中 boxPanel.add(titleLabel, BorderLayout.NORTH); // 添加标题到北部 boxPanel.add(valueLabel, BorderLayout.CENTER); // 添加值标签到中部 return boxPanel; // 返回面板 private void updateDbVersion() { if (conn != null) { try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT VERSION()")) { if (rs.next()) { dbVersionLabel.setText(rs.getString(1)); } } catch (Exception ex) { dbVersionLabel.setText("N/A"); } } } private void startStatsTimer() { // 启动统计定时器方法 statsTimer = new Timer(1000, e -> { // 创建1秒间隔的定时器 // 更新UDP数据包计数 udpAPacketCountLabel.setText(String.valueOf(UDPPortAReceiver.getPacketCount())); // 更新端口A计数 udpBPacketCountLabel.setText(String.valueOf(UDPPortBReceiver.getPacketCount())); // 更新端口B计数 private void startStatsTimer() { statsTimer = new Timer(1000, e -> { // 更新UDP端口A信息 int packetCountA = (int) UDPPortAReceiver.getPacketCount(); udpAInfoLabel.setText(Dell_SystemConfiguration.hexport + " - " + messages.getString("RECEIVED_PACKETS") + ": " + packetCountA); // 更新UDP端口B信息 int packetCountB = (int) UDPPortBReceiver.getPacketCount(); udpBInfoLabel.setText(Dell_SystemConfiguration.ascallport + " - " + messages.getString("RECEIVED_PACKETS") + ": " + packetCountB); // 更新内存使用情况 Runtime runtime = Runtime.getRuntime(); // 获取运行时实例 long usedMemory = (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024); // 计算已用内存(MB) long maxMemory = runtime.maxMemory() / (1024 * 1024); // 计算最大内存(MB) memoryUsageLabel.setText(usedMemory + " " + messages.getString("MB") + " / " + maxMemory + " " + messages.getString("MB")); // 设置内存文本 Runtime runtime = Runtime.getRuntime(); long usedMemory = (runtime.totalMemory() - runtime.freeMemory()) / (1024 * 1024); long maxMemory = runtime.maxMemory() / (1024 * 1024); memoryUsageLabel.setText(usedMemory + " " + messages.getString("MB") + " / " + maxMemory + " " + messages.getString("MB")); // 更新线程数量 threadCountLabel.setText(String.valueOf(Thread.activeCount())); // 设置活动线程数 // 更新线程数 threadCountLabel.setText(String.valueOf(Thread.activeCount())); // 更新标签状态 int onlineTags = Dell_tag.getOnlineLocationTags().size(); int totalTags = Dell_tag.getLocationTagCount(); tagStatsLabel.setText(onlineTags + " / " + totalTags); // 更新基站状态 int onlineStations = Dell_BaseStation.getOnlineBaseStations().size(); int totalStations = Dell_BaseStation.getLocationBaseCount(); baseStationStatsLabel.setText(onlineStations + " / " + totalStations); }); statsTimer.start(); // 启动定时器 statsTimer.start(); } @Override public void dispose() { // 销毁方法 super.dispose(); // 调用父类销毁 if (statsTimer != null) { // 检查定时器 statsTimer.stop(); // 停止定时器 public void dispose() { super.dispose(); if (statsTimer != null) { statsTimer.stop(); } } } systemfile/Messages_en.properties
@@ -1,3 +1,12 @@ TAG_STATS = Tag Statistics BASE_STATION_STATS = Base Station Statistics SOFTWARE_VERSION = Software Version APP_VERSION = 1.0.0 UDP_PORT_A = UDP Receive Port A UDP_PORT_B = UDP Receive Port B DB_VERSION = Database Version DB_STATUS = Database Status RECEIVED_PACKETS=Received # New message viewing related resources MESSAGE_VIEW_ALL_TYPES=All Types MESSAGE_VIEW_UDP_PORT_A=UDP Port A systemfile/Messages_zh.properties
@@ -1,3 +1,12 @@ TAG_STATS=标签统计 BASE_STATION_STATS=基站统计 SOFTWARE_VERSION=软件版本 APP_VERSION=1.0.0 UDP_PORT_A=数据接收端口 UDP_PORT_B=数据接收端口 DB_VERSION=数据库版本 DB_STATUS=数据库状态 RECEIVED_PACKETS=接收 # 新增的报文查看相关资源 MESSAGE_VIEW_ALL_TYPES=所有类型 MESSAGE_VIEW_UDP_PORT_A=UDP端口A @@ -483,8 +492,6 @@ MESSAGE_VIEW_EMPTY_DATA=发送内容不能为空 ERROR=错误 # 欢迎界面监控 UDP_PORT_A=UDP端口A (8234) UDP_PORT_B=UDP端口B (7000) MEMORY_USAGE=内存使用 THREAD_COUNT=线程数量 MB=MB systemfile/logfile/openlog.txt
@@ -701,3 +701,83 @@ 工作时长: 0小时 4分钟 12秒 ----------------------------------- 程序启动: 2025-08-09 16:32:39 程序关闭: 2025-08-09 20:05:40 工作时长: 3小时 33分钟 1秒 ----------------------------------- 程序启动: 2025-08-09 20:07:08 程序关闭: 2025-08-09 20:11:43 工作时长: 0小时 4分钟 35秒 ----------------------------------- 程序启动: 2025-08-09 20:11:46 程序关闭: 2025-08-09 21:57:03 工作时长: 1小时 45分钟 17秒 ----------------------------------- 程序启动: 2025-08-09 21:57:05 程序关闭: 2025-08-09 22:02:50 工作时长: 0小时 5分钟 44秒 ----------------------------------- 程序启动: 2025-08-09 22:12:39 程序关闭: 2025-08-09 22:21:24 工作时长: 0小时 8分钟 45秒 ----------------------------------- 程序启动: 2025-08-09 22:21:26 程序关闭: 2025-08-09 22:31:29 工作时长: 0小时 10分钟 2秒 ----------------------------------- 程序启动: 2025-08-09 22:31:30 程序关闭: 2025-08-09 22:31:44 工作时长: 0小时 0分钟 13秒 ----------------------------------- 程序启动: 2025-08-09 22:31:59 程序关闭: 2025-08-09 22:44:51 工作时长: 0小时 12分钟 52秒 ----------------------------------- 程序启动: 2025-08-09 22:44:53 程序关闭: 2025-08-09 22:44:55 工作时长: 0小时 0分钟 1秒 ----------------------------------- 程序启动: 2025-08-09 22:45:33 程序关闭: 2025-08-09 22:45:35 工作时长: 0小时 0分钟 1秒 ----------------------------------- 程序启动: 2025-08-09 22:46:58 程序关闭: 2025-08-09 22:49:10 工作时长: 0小时 2分钟 12秒 ----------------------------------- 程序启动: 2025-08-09 22:49:12 程序关闭: 2025-08-09 22:58:17 工作时长: 0小时 9分钟 4秒 ----------------------------------- 程序启动: 2025-08-09 22:58:19 程序关闭: 2025-08-09 23:09:45 工作时长: 0小时 11分钟 25秒 ----------------------------------- 程序启动: 2025-08-09 23:09:47 程序关闭: 2025-08-09 23:19:34 工作时长: 0小时 9分钟 46秒 ----------------------------------- 程序启动: 2025-08-09 23:19:36 程序关闭: 2025-08-09 23:19:51 工作时长: 0小时 0分钟 14秒 ----------------------------------- 程序启动: 2025-08-09 23:20:10 程序关闭: 2025-08-09 23:20:15 工作时长: 0小时 0分钟 5秒 ----------------------------------- 程序启动: 2025-08-09 23:21:01 程序关闭: 2025-08-09 23:21:05 工作时长: 0小时 0分钟 4秒 ----------------------------------- 程序启动: 2025-08-09 23:24:49 程序关闭: 2025-08-09 23:29:56 工作时长: 0小时 5分钟 6秒 ----------------------------------- 程序启动: 2025-08-09 23:29:58 程序关闭: 2025-08-09 23:30:36 工作时长: 0小时 0分钟 38秒 ----------------------------------- 程序启动: 2025-08-09 23:30:38 程序关闭: 2025-08-09 23:30:52 工作时长: 0小时 0分钟 14秒 ----------------------------------- 程序启动: 2025-08-09 23:30:58