package home;
|
|
import javax.swing.*;
|
import javax.swing.border.Border;
|
import javax.swing.border.TitledBorder;
|
import javax.swing.event.PopupMenuEvent;
|
import javax.swing.event.PopupMenuListener;
|
import java.awt.*;
|
import java.awt.event.*;
|
import java.util.*;
|
import java.io.InputStream;
|
import java.io.IOException;
|
import java.text.SimpleDateFormat;
|
import java.io.File;
|
import java.io.FileInputStream;
|
import java.util.PropertyResourceBundle;
|
import com.fazecast.jSerialComm.SerialPort;
|
import home.Dell55AA01Parser.ParseResult;
|
|
public class AOAFollowSystem extends JFrame {
|
private static final long serialVersionUID = 1L;
|
private CardLayout cardLayout;
|
private JPanel mainPanel;
|
private HomePanel homePanel;
|
private ConfigPanel configPanel;
|
private ResourceBundle messages;
|
private Locale currentLocale;
|
private JButton homeBtn;
|
private JButton configBtn;
|
private JComboBox<String> languageCombo;
|
private JLabel languageLabel;
|
private SerialPortService serialService;
|
|
|
public AOAFollowSystem() {
|
this.currentLocale = Locale.SIMPLIFIED_CHINESE;
|
this.messages = loadResourceBundle(currentLocale);
|
this.serialService = new SerialPortService();
|
initializeUI();
|
}
|
|
private ResourceBundle loadResourceBundle(Locale locale) {
|
String fileName = locale.equals(Locale.ENGLISH) ?
|
"Messages_en.properties" : "Messages_zh.properties";
|
|
File langFile = new File("systemfile/" + fileName);
|
|
if (!langFile.exists()) {
|
System.err.println("默认资源文件未找到: " + langFile.getAbsolutePath());
|
return ResourceBundle.getBundle("systemfile.Messages");
|
}
|
|
try (InputStream inputStream = new FileInputStream(langFile)) {
|
return new PropertyResourceBundle(inputStream);
|
} catch (IOException e) {
|
System.err.println("无法加载资源文件: " + e.getMessage());
|
return ResourceBundle.getBundle("systemfile.Messages");
|
}
|
}
|
|
public String getString(String key) {
|
if (messages != null && messages.containsKey(key)) {
|
return messages.getString(key);
|
}
|
// 默认文本(中文)
|
switch (key) {
|
case "home": return "首页";
|
case "config": return "配置";
|
case "device_id": return "设备编号";
|
case "group": return "通信小组";
|
case "frequency": return "通信频率";
|
case "read_config": return "读取配置";
|
case "save_config": return "保存配置";
|
case "serial_port": return "串口";
|
case "baud_rate": return "波特率";
|
case "open_serial": return "打开串口";
|
case "close_serial": return "关闭串口";
|
case "start": return "开始";
|
case "pause": return "暂停";
|
case "clear": return "清空";
|
case "send": return "发送";
|
case "device_id_table": return "设备编号";
|
case "distance_table": return "实时距离";
|
case "angle_table": return "实时角度";
|
case "signal_table": return "信号质量";
|
case "power_table": return "电量";
|
case "button_table": return "按钮";
|
case "time_table": return "时间";
|
case "LANGUAGE": return "语言";
|
case "log": return "日志";
|
case "send_data": return "发送数据";
|
case "select_serial_port": return "请选择串口";
|
case "error": return "错误";
|
case "open_serial_first": return "请先打开串口";
|
case "input_data_to_send": return "请输入要发送的数据";
|
case "send_failed": return "发送失败";
|
case "receive": return "接收";
|
case "visualization": return "可视化";
|
case "config_read_success": return "配置读取成功";
|
case "info": return "信息";
|
case "input_valid_number": return "请输入有效的数字";
|
case "config_save_success": return "配置保存成功";
|
case "select_file": return "选择文件";
|
case "upgrade": return "升级";
|
case "upgrade_progress": return "升级进度";
|
case "select_bin_file": return "请选择bin文件";
|
case "upgrade_success": return "升级成功";
|
case "upgrade_failed": return "升级失败";
|
case "hex": return "HEX";
|
case "ascii": return "ASCII";
|
case "hex_send": return "HEX发送";
|
case "display_format": return "显示格式";
|
default: return key;
|
}
|
}
|
|
private void initializeUI() {
|
setTitle("HXZK_AOA");
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
setSize(1000, 700);
|
setLocationRelativeTo(null);
|
|
// 创建顶部导航
|
JPanel navPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
homeBtn = createNavButton(getString("home"), new Color(70, 130, 180));
|
configBtn = createNavButton(getString("config"), new Color(70, 130, 180));
|
|
languageCombo = new JComboBox<>(new String[]{"中文", "English"});
|
languageCombo.setSelectedIndex(0);
|
languageCombo.addActionListener(e -> {
|
Locale newLocale = languageCombo.getSelectedIndex() == 0 ?
|
Locale.SIMPLIFIED_CHINESE : Locale.ENGLISH;
|
switchLanguage(newLocale);
|
});
|
|
navPanel.add(homeBtn);
|
navPanel.add(configBtn);
|
navPanel.add(Box.createHorizontalStrut(20));
|
|
languageLabel = new JLabel(getString("LANGUAGE") + ":");
|
navPanel.add(languageLabel);
|
navPanel.add(languageCombo);
|
|
// 创建主面板(卡片布局)
|
cardLayout = new CardLayout();
|
mainPanel = new JPanel(cardLayout);
|
homePanel = new HomePanel(serialService, this);
|
configPanel = new ConfigPanel(serialService, this);
|
|
mainPanel.add(homePanel, "home");
|
mainPanel.add(configPanel, "config");
|
|
// 添加导航按钮事件
|
homeBtn.addActionListener(e -> cardLayout.show(mainPanel, "home"));
|
configBtn.addActionListener(e -> cardLayout.show(mainPanel, "config"));
|
|
// 设置布局
|
setLayout(new BorderLayout());
|
add(navPanel, BorderLayout.NORTH);
|
add(mainPanel, BorderLayout.CENTER);
|
|
// 设置默认显示首页
|
cardLayout.show(mainPanel, "home");
|
}
|
|
private void switchLanguage(Locale newLocale) {
|
this.currentLocale = newLocale;
|
this.messages = loadResourceBundle(currentLocale);
|
|
// 更新界面文本
|
updateUILanguage();
|
|
// 更新语言选择框
|
languageCombo.setSelectedIndex(newLocale.equals(Locale.SIMPLIFIED_CHINESE) ? 0 : 1);
|
|
revalidate();
|
repaint();
|
}
|
|
private void updateUILanguage() {
|
// 更新导航按钮文本
|
homeBtn.setText(getString("home"));
|
configBtn.setText(getString("config"));
|
|
// 更新语言标签
|
languageLabel.setText(getString("LANGUAGE") + ":");
|
|
// 更新各面板文本
|
homePanel.updateLanguage();
|
configPanel.updateLanguage();
|
}
|
|
private JButton createNavButton(String text, Color color) {
|
JButton button = new JButton(text);
|
button.setBackground(color);
|
button.setForeground(Color.WHITE);
|
button.setFocusPainted(false);
|
button.setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15));
|
|
button.addMouseListener(new MouseAdapter() {
|
@Override
|
public void mouseEntered(MouseEvent e) {
|
button.setBackground(color.darker());
|
}
|
|
@Override
|
public void mouseExited(MouseEvent e) {
|
button.setBackground(color);
|
}
|
});
|
|
return button;
|
}
|
|
// 首页面板
|
class HomePanel extends JPanel {
|
/**
|
*
|
*/
|
private static final long serialVersionUID = 1L;
|
private VisualizationPanel visualizationPanel;
|
private JTable dataTable;
|
private JTextArea logArea;
|
private JComboBox<String> serialPortCombo;
|
private JComboBox<String> baudRateCombo;
|
private JButton openSerialBtn;
|
private JButton startPauseBtn;
|
private JButton clearBtn;
|
private JButton sendBtn;
|
private JTextField sendField;
|
private JLabel displayFormatLabel; // 新增:显示格式标签
|
private JLabel serialPortLabel; // 新增:串口标签
|
private JLabel baudRateLabel; // 新增:波特率标签
|
|
private SerialPortService serialService;
|
private AOAFollowSystem parentFrame;
|
private boolean serialOpened = false;
|
private boolean isRunning = false;
|
|
// 新增:显示格式单选按钮
|
private JRadioButton hexRadio;
|
private JRadioButton asciiRadio;
|
private JCheckBox hexSendCheckBox;
|
private JCheckBox pairCheckBox;
|
|
// 表格模型 - 只有1行
|
private Object[][] tableData = new Object[1][7];
|
private String[] columnNames = {
|
getString("device_id_table"),
|
getString("distance_table"),
|
getString("angle_table"),
|
getString("signal_table"),
|
getString("power_table"),
|
getString("button_table"),
|
getString("time_table")
|
};
|
|
// 优化:重用对象减少内存分配
|
private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
|
private StringBuilder hexBuilder = new StringBuilder();
|
private StringBuilder displayBuilder = new StringBuilder();
|
|
public HomePanel(SerialPortService serialService, AOAFollowSystem parentFrame) {
|
this.serialService = serialService;
|
this.parentFrame = parentFrame;
|
setLayout(new BorderLayout(10, 10));
|
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
|
// 创建左侧面板(可视化区域和表格)
|
JPanel leftPanel = new JPanel(new BorderLayout(10, 10));
|
|
// 可视化面板
|
visualizationPanel = new VisualizationPanel(parentFrame);
|
leftPanel.add(visualizationPanel, BorderLayout.CENTER);
|
|
// 数据表格
|
JPanel tablePanel = new JPanel(new BorderLayout());
|
tablePanel.setBorder(BorderFactory.createTitledBorder(getString("device_id_table")));
|
dataTable = new JTable(tableData, columnNames);
|
JScrollPane tableScroll = new JScrollPane(dataTable);
|
tableScroll.setPreferredSize(new Dimension(0, 80));
|
tablePanel.add(tableScroll, BorderLayout.CENTER);
|
leftPanel.add(tablePanel, BorderLayout.SOUTH);
|
|
// 创建右侧面板(日志和控制)
|
JPanel rightPanel = new JPanel(new BorderLayout(10, 10));
|
|
// 日志区域
|
JPanel logPanel = new JPanel(new BorderLayout());
|
logPanel.setBorder(BorderFactory.createTitledBorder(getString("log")));
|
logArea = new JTextArea();
|
logArea.setEditable(false);
|
JScrollPane logScroll = new JScrollPane(logArea);
|
logScroll.setPreferredSize(new Dimension(400, 0));
|
logPanel.add(logScroll, BorderLayout.CENTER);
|
|
// 新增:显示格式选择面板
|
JPanel formatPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
formatPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
displayFormatLabel = new JLabel(getString("display_format") + ":"); // 使用getString获取文本
|
formatPanel.add(displayFormatLabel);
|
|
ButtonGroup formatGroup = new ButtonGroup();
|
hexRadio = new JRadioButton(getString("hex"), true); // 默认选中HEX
|
asciiRadio = new JRadioButton(getString("ascii"));
|
|
pairCheckBox = new JCheckBox(getString("pair"), false); // 默认不勾选
|
pairCheckBox.addItemListener(e -> {
|
if (pairCheckBox.isSelected()) {
|
sendField.setText("55AA030304F5FF");
|
} else {
|
sendField.setText("");
|
}
|
});
|
|
|
formatGroup.add(hexRadio);
|
formatGroup.add(asciiRadio);
|
|
formatPanel.add(hexRadio);
|
formatPanel.add(asciiRadio);
|
formatPanel.add(pairCheckBox);
|
|
|
// 将格式选择面板添加到日志面板的底部
|
logPanel.add(formatPanel, BorderLayout.SOUTH);
|
|
rightPanel.add(logPanel, BorderLayout.CENTER);
|
|
// 控制面板
|
JPanel controlPanel = new JPanel(new GridBagLayout());
|
controlPanel.setBorder(BorderFactory.createTitledBorder(getString("serial_port")));
|
|
GridBagConstraints gbc = new GridBagConstraints();
|
gbc.insets = new Insets(5, 2, 5, 5);
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
|
// 串口选择
|
gbc.gridx = 0;
|
gbc.gridy = 0;
|
gbc.weightx = 0;
|
serialPortLabel = new JLabel(getString("serial_port") + ":"); // 使用getString获取文本
|
controlPanel.add(serialPortLabel, gbc);
|
|
gbc.gridx = 1;
|
gbc.weightx = 1;
|
serialPortCombo = new JComboBox<>();
|
// 添加弹出菜单监听器,点击时刷新串口列表
|
serialPortCombo.addPopupMenuListener(new PopupMenuListener() {
|
@Override
|
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
|
refreshSerialPorts();
|
}
|
|
@Override
|
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
|
|
@Override
|
public void popupMenuCanceled(PopupMenuEvent e) {}
|
});
|
refreshSerialPorts();
|
controlPanel.add(serialPortCombo, gbc);
|
|
// 波特率选择
|
gbc.gridx = 0;
|
gbc.gridy = 1;
|
gbc.weightx = 0;
|
baudRateLabel = new JLabel(getString("baud_rate") + ":"); // 使用getString获取文本
|
controlPanel.add(baudRateLabel, gbc);
|
|
gbc.gridx = 1;
|
gbc.weightx = 1;
|
baudRateCombo = new JComboBox<>(new String[]{"115200", "921600","9600", "19200", "38400", "57600"});
|
baudRateCombo.setSelectedIndex(0);
|
controlPanel.add(baudRateCombo, gbc);
|
|
// 串口控制按钮
|
gbc.gridx = 0;
|
gbc.gridy = 2;
|
gbc.gridwidth = 1; // 修改:只占一列
|
gbc.weightx = 0.5; // 修改:设置权重
|
openSerialBtn = createColoredButton(getString("open_serial"), new Color(70, 130, 180));
|
openSerialBtn.setPreferredSize(new Dimension(100, 30)); // 修改:设置与开始按钮相同尺寸
|
openSerialBtn.addActionListener(e -> toggleSerialPort());
|
controlPanel.add(openSerialBtn, gbc);
|
openSerialBtn.setBackground(Color.GRAY);
|
|
// 启动/暂停按钮(合并为一个)
|
gbc.gridx = 1; // 修改:放在第二列
|
gbc.gridy = 2;
|
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 0));
|
startPauseBtn = createColoredButton(getString("start"), new Color(50, 205, 50));
|
startPauseBtn.setPreferredSize(new Dimension(100, 30));
|
startPauseBtn.addActionListener(e -> toggleCapture());
|
buttonPanel.add(startPauseBtn);
|
|
clearBtn = createColoredButton(getString("clear"), new Color(192, 192, 192));
|
clearBtn.setPreferredSize(new Dimension(100, 30));
|
clearBtn.addActionListener(e -> clearLog());
|
buttonPanel.add(clearBtn);
|
controlPanel.add(buttonPanel, gbc);
|
|
rightPanel.add(controlPanel, BorderLayout.SOUTH);
|
|
// 发送数据面板 - 移到表格下方
|
JPanel sendDataPanel = new JPanel(new BorderLayout(5, 5));
|
sendDataPanel.setBorder(BorderFactory.createTitledBorder(getString("send_data")));
|
|
JPanel sendControlPanel = new JPanel(new BorderLayout(5, 0));
|
sendField = new JTextField();
|
sendBtn = createColoredButton(getString("send"), new Color(70, 130, 180));
|
sendBtn.setPreferredSize(new Dimension(100, 30));
|
sendBtn.addActionListener(e -> sendData());
|
|
// 新增:HEX发送复选框
|
hexSendCheckBox = new JCheckBox(getString("hex_send"), true); // 默认勾选
|
sendControlPanel.add(hexSendCheckBox, BorderLayout.WEST);
|
sendControlPanel.add(sendBtn, BorderLayout.EAST);
|
|
sendDataPanel.add(sendField, BorderLayout.CENTER);
|
sendDataPanel.add(sendControlPanel, BorderLayout.EAST);
|
|
// 添加发送数据面板到左侧面板的最底部
|
leftPanel.add(sendDataPanel, BorderLayout.SOUTH);
|
|
// 添加左右面板
|
add(leftPanel, BorderLayout.CENTER);
|
add(rightPanel, BorderLayout.EAST);
|
}
|
|
private JButton createColoredButton(String text, Color color) {
|
JButton button = new JButton(text);
|
button.setBackground(color);
|
button.setForeground(Color.WHITE);
|
button.setFocusPainted(false);
|
button.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
|
|
button.addMouseListener(new MouseAdapter() {
|
@Override
|
public void mouseEntered(MouseEvent e) {
|
button.setBackground(color.darker());
|
}
|
|
@Override
|
public void mouseExited(MouseEvent e) {
|
button.setBackground(color);
|
}
|
});
|
|
return button;
|
}
|
|
private void refreshSerialPorts() {
|
String selectedPort = (String) serialPortCombo.getSelectedItem();
|
serialPortCombo.removeAllItems();
|
SerialPort[] ports = SerialPort.getCommPorts();
|
for (SerialPort port : ports) {
|
serialPortCombo.addItem(port.getSystemPortName());
|
}
|
|
// 尝试恢复之前的选择
|
if (selectedPort != null) {
|
serialPortCombo.setSelectedItem(selectedPort);
|
} else if (ports.length > 0) {
|
serialPortCombo.setSelectedIndex(0);
|
}
|
}
|
|
private void toggleSerialPort() {
|
if (serialOpened) {
|
closeSerialPort();
|
openSerialBtn.setText(getString("open_serial"));
|
openSerialBtn.setBackground(Color.GRAY); // 关闭时灰色
|
serialOpened = false;
|
|
// 关闭串口时停止捕获
|
if (isRunning) {
|
toggleCapture();
|
}
|
} else {
|
if (openSerialPort()) {
|
openSerialBtn.setText(getString("close_serial"));
|
openSerialBtn.setBackground(Color.GREEN);
|
serialOpened = true;
|
}
|
}
|
}
|
|
private boolean openSerialPort() {
|
String portName = (String) serialPortCombo.getSelectedItem();
|
if (portName == null) {
|
JOptionPane.showMessageDialog(this, getString("select_serial_port"), getString("error"), JOptionPane.ERROR_MESSAGE);
|
return false;
|
}
|
|
int baudRate = Integer.parseInt((String) baudRateCombo.getSelectedItem());
|
return serialService.open(portName, baudRate);
|
}
|
|
private void closeSerialPort() {
|
serialService.close();
|
}
|
|
private void toggleCapture() {
|
if (!serialOpened) {
|
JOptionPane.showMessageDialog(this, getString("open_serial_first"), getString("error"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
|
isRunning = !isRunning;
|
serialService.setPaused(!isRunning);
|
|
if (isRunning) {
|
startPauseBtn.setText(getString("pause"));
|
startPauseBtn.setBackground(new Color(255, 165, 0));
|
|
// 启动数据捕获
|
serialService.startCapture(this::processReceivedData);
|
} else {
|
startPauseBtn.setText(getString("start"));
|
startPauseBtn.setBackground(new Color(50, 205, 50));
|
}
|
}
|
|
private void clearLog() {
|
logArea.setText("");
|
}
|
|
private void sendData() {
|
if (!serialOpened) {
|
JOptionPane.showMessageDialog(this, getString("open_serial_first"), getString("error"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
|
String data = sendField.getText();
|
if (data.isEmpty()) {
|
JOptionPane.showMessageDialog(this, getString("input_data_to_send"), getString("error"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
|
byte[] sendBytes;
|
if (hexSendCheckBox.isSelected()) {
|
// HEX发送模式
|
try {
|
sendBytes = hexStringToByteArray(data.replaceAll("\\s+", ""));
|
if (sendBytes == null) {
|
JOptionPane.showMessageDialog(this, "无效的HEX格式", getString("error"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
} catch (Exception e) {
|
JOptionPane.showMessageDialog(this, "HEX转换错误: " + e.getMessage(), getString("error"), JOptionPane.ERROR_MESSAGE);
|
return;
|
}
|
} else {
|
// ASCII发送模式
|
sendBytes = data.getBytes();
|
}
|
|
boolean success = serialService.send(sendBytes);
|
if (success) {
|
appendLog(getString("send") + ": " + (hexSendCheckBox.isSelected() ? bytesToHex(sendBytes) : data));
|
} else {
|
appendLog(getString("send_failed") + ": " + data);
|
}
|
sendField.setText("");
|
}
|
|
private void processReceivedData(byte[] data) {
|
// 优化:重用StringBuilder对象
|
hexBuilder.setLength(0);
|
for (byte b : data) {
|
hexBuilder.append(String.format("%02X", b));
|
}
|
String displayText = hexBuilder.toString();
|
|
String displayText1 = new String(data).replaceAll("\\s+", "");
|
|
if (displayText.startsWith("55AA1F")) {
|
Dell55AA1FParser.ParseResult result = Dell55AA1FParser.parse(displayText, "127.0.0.1", 0);
|
if (result != null) {
|
updateTable(result);
|
visualizationPanel.updatePosition(result.distance, result.angle,result.signalQuality);
|
visualizationPanel.setTagId(result.tagId);
|
}
|
}else if(displayText.startsWith("55AA01")) {
|
ParseResult result=Dell55AA01Parser.parse(displayText, "127.0.0.1", 0);
|
visualizationPanel.updatePosition(result.distance,270,0);
|
visualizationPanel.setTagId(result.tagId);
|
|
}
|
|
if (hexRadio.isSelected()) {
|
appendLog(displayText);
|
} else {
|
if (displayText.startsWith("55AA1F")) {
|
Dell55AA1FParser.ParseResult result = Dell55AA1FParser.parse(displayText, "127.0.0.1", 0);
|
// 优化:重用StringBuilder对象
|
displayBuilder.setLength(0);
|
displayBuilder.append("1F:")
|
.append(result.dataLength)
|
.append(",")
|
.append(result.messageType)
|
.append(",id:")
|
.append(result.tagId)
|
.append(",Dis:")
|
.append(result.distance)
|
.append("cm,Angle:")
|
.append(result.angle)
|
.append("°,Signal:")
|
.append(result.signalQuality)
|
.append(",Button:")
|
.append(result.buttonPressed)
|
.append(",Power:")
|
.append(result.power);
|
appendLog(displayBuilder.toString());
|
}else if(displayText.startsWith("55AA01")) {
|
ParseResult result=Dell55AA01Parser.parse(displayText, "127.0.0.1", 0);
|
// 优化:重用StringBuilder对象
|
displayBuilder.setLength(0);
|
displayBuilder.append("55AA01 Seq:")
|
.append(result.sequenceNum)
|
.append(",Tagid:")
|
.append(result.tagId)
|
.append(",Anchorid:")
|
.append(result.anchorId)
|
.append(",Distance:")
|
.append(result.distance)
|
.append(",Power:")
|
.append(result.power)
|
.append(",Button:")
|
.append(result.buttonPressed);
|
appendLog(displayBuilder.toString());
|
}else {
|
appendLog(displayText1);
|
}
|
}
|
}
|
|
private void appendLog(String message) {
|
SwingUtilities.invokeLater(() -> {
|
// 优化:限制日志长度,防止内存无限增长
|
if (logArea.getLineCount() > 1000) {
|
try {
|
int end = logArea.getDocument().getLength();
|
int start = logArea.getDocument().getText(0, end).indexOf("\n") + 1;
|
logArea.getDocument().remove(0, start);
|
} catch (Exception e) {
|
logArea.setText(""); // 如果出错则清空日志
|
}
|
}
|
|
String time = sdf.format(new Date());
|
logArea.append("[" + time + "] " + message + "\n");
|
|
// 自动滚动到最后
|
logArea.setCaretPosition(logArea.getDocument().getLength());
|
});
|
}
|
|
private void updateTable(Dell55AA1FParser.ParseResult result) {
|
SwingUtilities.invokeLater(() -> {
|
// 只有1行数据,直接更新
|
String time = sdf.format(new Date());
|
|
tableData[0] = new Object[]{
|
result.tagId,
|
result.distance + "cm",
|
result.angle + "°",
|
result.signalQuality,
|
result.power + "%",
|
result.buttonPressed,
|
time
|
};
|
|
// 刷新表格
|
dataTable.repaint();
|
});
|
}
|
|
// 辅助方法:将字节数组转换为HEX字符串
|
private String bytesToHex(byte[] bytes) {
|
// 优化:重用StringBuilder对象
|
hexBuilder.setLength(0);
|
for (byte b : bytes) {
|
hexBuilder.append(String.format("%02X ", b));
|
}
|
return hexBuilder.toString().trim();
|
}
|
|
// 辅助方法:将HEX字符串转换为字节数组
|
private byte[] hexStringToByteArray(String s) {
|
int len = s.length();
|
if (len % 2 != 0) {
|
return null;
|
}
|
|
byte[] data = new byte[len / 2];
|
for (int i = 0; i < len; i += 2) {
|
try {
|
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
+ Character.digit(s.charAt(i+1), 16));
|
} catch (Exception e) {
|
return null;
|
}
|
}
|
return data;
|
}
|
|
public void updateLanguage() {
|
// 更新界面文本
|
openSerialBtn.setText(serialOpened ? getString("close_serial") : getString("open_serial"));
|
startPauseBtn.setText(isRunning ? getString("pause") : getString("start"));
|
clearBtn.setText(getString("clear"));
|
sendBtn.setText(getString("send"));
|
|
// 更新标签文本
|
displayFormatLabel.setText(getString("display_format") + ":");
|
serialPortLabel.setText(getString("serial_port") + ":");
|
baudRateLabel.setText(getString("baud_rate") + ":");
|
|
// 更新列名
|
columnNames[0] = getString("device_id_table");
|
columnNames[1] = getString("distance_table");
|
columnNames[2] = getString("angle_table");
|
columnNames[3] = getString("signal_table");
|
columnNames[4] = getString("power_table");
|
columnNames[5] = getString("button_table");
|
columnNames[6] = getString("time_table");
|
|
// 更新显示格式单选按钮
|
hexRadio.setText(getString("hex"));
|
asciiRadio.setText(getString("ascii"));
|
hexSendCheckBox.setText(getString("hex_send"));
|
pairCheckBox.setText(getString("pair"));
|
|
// 更新边框标题
|
updateBorderTitles(this);
|
|
dataTable.repaint();
|
}
|
|
private void updateBorderTitles(Container container) {
|
for (Component comp : container.getComponents()) {
|
if (comp instanceof JPanel) {
|
JPanel panel = (JPanel) comp;
|
Border border = panel.getBorder();
|
if (border instanceof TitledBorder) {
|
TitledBorder titledBorder = (TitledBorder) border;
|
String title = titledBorder.getTitle();
|
|
if (title.equals("日志") || title.equals("Log")) {
|
titledBorder.setTitle(getString("log"));
|
} else if (title.equals(getString("device_id_table")) || title.equals("Device ID")) {
|
titledBorder.setTitle(getString("device_id_table"));
|
} else if (title.equals(getString("serial_port")) || title.equals("Serial Port")) {
|
titledBorder.setTitle(getString("serial_port"));
|
} else if (title.equals("发送数据") || title.equals("Send Data")) {
|
titledBorder.setTitle(getString("send_data"));
|
} else if (title.equals("可视化") || title.equals("Visualization")) {
|
titledBorder.setTitle(getString("visualization"));
|
}
|
panel.repaint();
|
}
|
|
// 递归更新子组件
|
updateBorderTitles(panel);
|
}
|
}
|
}
|
|
private String getString(String key) {
|
if (parentFrame != null) {
|
return parentFrame.getString(key);
|
} else {
|
// 返回默认文本(中文)或 key 本身作为备用
|
switch (key) {
|
case "home": return "首页";
|
case "config": return "配置";
|
case "display_format": return "显示格式";
|
case "serial_port": return "串口";
|
case "baud_rate": return "波特率";
|
case "close_serial": return "关闭串口";
|
// 其他 key 的默认值...
|
default: return key;
|
}
|
}
|
}
|
}
|
}
|