package home;
|
|
import jiexi.*;
|
|
import javax.swing.*;
|
import java.awt.*;
|
import java.net.*;
|
import java.io.IOException;
|
import java.util.Vector;
|
import java.util.Map;
|
import java.util.HashMap;
|
import java.util.HashSet;
|
import java.util.Set;
|
|
public class NetworkConfigPanel extends JPanel {
|
// 基础设置面板组件
|
private JComboBox<String> ipTypeComboBox;
|
private JTextField staticIpField;
|
private JTextField subnetMaskField;
|
private JTextField gatewayField;
|
private JTextField dnsServerField;
|
private JTextField macAddressField;
|
private JTextField timeoutRestartField;
|
private JTextField httpServerPortField;
|
private JTextField usernameField;
|
private JTextField passwordField;
|
private JTextField deviceNameField;
|
|
// 选项复选框
|
private JCheckBox indexCheckBox;
|
private JCheckBox resetCheckBox;
|
private JCheckBox linkCheckBox;
|
private JCheckBox rfc2217CheckBox;
|
private JCheckBox cacheClearCheckBox;
|
private JCheckBox serialSettingsCheckBox;
|
|
// 端口设置面板组件
|
private JComboBox<String> workModeComboBox;
|
private JTextField targetUrlField;
|
private JTextField shortConnectionTimeField;
|
private JComboBox<String> baudRateComboBox;
|
private JTextField localPortField;
|
private JTextField remotePortField;
|
private JComboBox<String> tcpClientCountComboBox;
|
private JCheckBox enableShortConnectionCheckBox;
|
|
// 串口参数组件
|
private JComboBox<String> parityComboBox;
|
private JComboBox<String> dataBitsComboBox;
|
private JComboBox<String> stopBitsComboBox;
|
|
private static final long serialVersionUID = 1L;
|
private MainFrame mainFrame;
|
private JButton readBtn, searchBtn, saveBtn;
|
private JTable deviceTable;
|
private JPanel basicSettingsPanel, portSettingsPanel;
|
|
// 新增:标签引用用于语言切换
|
private JLabel deviceListLabel;
|
|
// 保存所有参数行的标签引用,用于语言切换
|
private Map<String, JLabel> parameterLabels = new HashMap<>();
|
private JLabel optionsLabel;
|
private JLabel parityDataStopLabel;
|
|
// 在类变量区域添加
|
private DeviceConfig currentDeviceConfig;
|
|
public NetworkConfigPanel(MainFrame mainFrame) {
|
this.mainFrame = mainFrame;
|
initializeUI();
|
}
|
|
private void initializeUI() {
|
setLayout(new BorderLayout());
|
// 控制面板
|
add(createControlPanel(), BorderLayout.NORTH);
|
// 设备表格和配置面板
|
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
|
splitPane.setLeftComponent(createDeviceTablePanel());
|
splitPane.setRightComponent(createConfigPanel());
|
splitPane.setDividerLocation(400);
|
add(splitPane, BorderLayout.CENTER);
|
}
|
|
private JPanel createControlPanel() {
|
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 5));
|
searchBtn = ButtonUtils.createBlueButton(getString("search.devices"));
|
readBtn = ButtonUtils.createBlueButton(getString("read.parameters"));
|
saveBtn = ButtonUtils.createBlueButton(getString("save.parameters")); // 新增保存按钮
|
|
// 添加按钮的点击事件监听器
|
searchBtn.addActionListener(e -> searchDevices());
|
readBtn.addActionListener(e -> readDevices());
|
saveBtn.addActionListener(e -> saveDeviceConfig()); // 新增保存事件
|
|
panel.add(searchBtn);
|
panel.add(readBtn);
|
panel.add(saveBtn); // 添加到面板
|
|
return panel;
|
}
|
|
private void readDevices() {
|
// 获取选中的设备
|
int selectedRow = deviceTable.getSelectedRow();
|
if (selectedRow == -1) {
|
JOptionPane.showMessageDialog(this,
|
getString("please.select.device"),
|
getString("prompt"),
|
JOptionPane.WARNING_MESSAGE);
|
return;
|
}
|
|
// 检查是否只选中了一个设备
|
int[] selectedRows = deviceTable.getSelectedRows();
|
if (selectedRows.length > 1) {
|
JOptionPane.showMessageDialog(this,
|
getString("select.one.device"),
|
getString("prompt"),
|
JOptionPane.WARNING_MESSAGE);
|
return;
|
}
|
|
// 获取选中设备的IP和MAC地址
|
String deviceIp = (String) deviceTable.getValueAt(selectedRow, 1); // 第二列是IP地址
|
String deviceMac = (String) deviceTable.getValueAt(selectedRow, 3); // 第四列是MAC地址
|
|
// 在新线程中执行UDP读取操作
|
new Thread(() -> {
|
DatagramSocket socket = null;
|
try {
|
// 创建UDP Socket
|
socket = new DatagramSocket();
|
socket.setSoTimeout(5000); // 设置5秒超时
|
// 准备读取配置的数据
|
byte[] sendData = DellS2.reads2peizhi((byte) 0x03, deviceMac);
|
// 创建目标地址:选中设备的IP,端口1500
|
InetAddress deviceAddress = InetAddress.getByName(deviceIp);
|
int port = 1500;
|
// 创建数据包
|
DatagramPacket packet = new DatagramPacket(sendData, sendData.length, deviceAddress, port);
|
// 发送读取请求
|
socket.send(packet);
|
// 准备接收响应
|
byte[] receiveData = new byte[1024];
|
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
|
// 接收响应
|
socket.receive(receivePacket);
|
// 处理响应数据
|
processReadResponse(receivePacket, deviceIp, deviceMac);
|
} catch (SocketTimeoutException e) {
|
SwingUtilities.invokeLater(() -> {
|
JOptionPane.showMessageDialog(this,
|
getString("read.timeout"),
|
getString("error"),
|
JOptionPane.ERROR_MESSAGE);
|
});
|
} catch (UnknownHostException e) {
|
SwingUtilities.invokeLater(() -> {
|
JOptionPane.showMessageDialog(this,
|
getString("invalid.ip.address") + ": " + deviceIp,
|
getString("error"),
|
JOptionPane.ERROR_MESSAGE);
|
});
|
} catch (IOException e) {
|
SwingUtilities.invokeLater(() -> {
|
JOptionPane.showMessageDialog(this,
|
getString("read.device.error") + ": " + e.getMessage(),
|
getString("error"),
|
JOptionPane.ERROR_MESSAGE);
|
});
|
e.printStackTrace();
|
} finally {
|
// 关闭socket
|
if (socket != null && !socket.isClosed()) {
|
socket.close();
|
}
|
}
|
}).start();
|
}
|
|
/**
|
* 处理读取配置的响应数据
|
*/
|
private void processReadResponse(DatagramPacket packet, String deviceIp, String deviceMac) {
|
// 获取响应数据
|
byte[] responseData = packet.getData();
|
int dataLength = packet.getLength();
|
|
// 将字节数据转换为十六进制字符串
|
String hexData = bytesToHex(responseData, dataLength);
|
|
// 打印到控制台
|
System.out.println(hexData);
|
DeviceConfig deviceConfig = DeviceConfigParser.parseDeviceConfig(hexData);
|
|
// 保存当前设备配置
|
this.currentDeviceConfig = deviceConfig;
|
|
// 将解析的配置数据应用到UI组件
|
updateUIWithDeviceConfig(deviceConfig);
|
|
// 在UI线程中显示成功消息
|
SwingUtilities.invokeLater(() -> {
|
JOptionPane.showMessageDialog(this,
|
getString("read.success") + "\nIP: " + deviceIp + "\nMAC: " + deviceMac,
|
getString("success"),
|
JOptionPane.INFORMATION_MESSAGE);
|
});
|
}
|
|
/**
|
* 保存设备配置 - 将UI配置赋值回DeviceConfig对象并通过UDP广播发送
|
*/
|
private void saveDeviceConfig() {
|
if (currentDeviceConfig == null) {
|
JOptionPane.showMessageDialog(this,
|
getString("read.parameters.first"),
|
getString("prompt"),
|
JOptionPane.WARNING_MESSAGE);
|
return;
|
}
|
|
try {
|
// 从UI更新基础设置到DeviceConfig
|
updateDeviceConfigFromBasicSettings();
|
|
// 从UI更新端口设置到DeviceConfig
|
updateDeviceConfigFromPortSettings();
|
|
String mac = currentDeviceConfig.getMacAddress().replaceAll(":", "");
|
byte[] bytes = DellS2.alert_s2(currentDeviceConfig.getStaticIp(), currentDeviceConfig.getGatewayIp(),
|
currentDeviceConfig.getSubnetMask(), currentDeviceConfig.getModuleName(), mac);
|
byte[] bytes1 = DellS2.alert_s2_chuankou(currentDeviceConfig.getTargetUrl(), mac,
|
"0" + currentDeviceConfig.getWorkMode(), currentDeviceConfig.getRemotePort() + "",
|
currentDeviceConfig.getBaudRate() + "");
|
byte[] bytes2 = DellS2.reads2peizhi((byte) 0x02, mac);
|
// 在新线程中执行UDP发送操作
|
new Thread(() -> {
|
DatagramSocket socket = null;
|
try {
|
// 创建UDP Socket
|
socket = new DatagramSocket();
|
socket.setBroadcast(true);
|
|
// 创建广播地址:255.255.255.255,端口1500
|
InetAddress broadcastAddress = InetAddress.getByName("255.255.255.255");
|
int port = 1500;
|
|
// 发送第一个数据包 (bytes)
|
if (bytes != null && bytes.length > 0) {
|
DatagramPacket packet1 = new DatagramPacket(bytes, bytes.length, broadcastAddress, port);
|
socket.send(packet1);
|
}
|
|
if (bytes1 != null && bytes1.length > 0) {
|
DatagramPacket packet2 = new DatagramPacket(bytes1, bytes1.length, broadcastAddress, port);
|
socket.send(packet2);
|
}
|
|
if (bytes2 != null && bytes2.length > 0) {
|
DatagramPacket packet3 = new DatagramPacket(bytes2, bytes2.length, broadcastAddress, port);
|
socket.send(packet3);
|
}
|
|
SwingUtilities.invokeLater(() -> {
|
JOptionPane.showMessageDialog(this,
|
getString("save.success"),
|
getString("success"),
|
JOptionPane.INFORMATION_MESSAGE);
|
});
|
|
} catch (SocketException e) {
|
SwingUtilities.invokeLater(() -> {
|
JOptionPane.showMessageDialog(this,
|
getString("udp.socket.failed") + ": " + e.getMessage(),
|
getString("error"),
|
JOptionPane.ERROR_MESSAGE);
|
});
|
} catch (UnknownHostException e) {
|
SwingUtilities.invokeLater(() -> {
|
JOptionPane.showMessageDialog(this,
|
getString("invalid.broadcast.address"),
|
getString("error"),
|
JOptionPane.ERROR_MESSAGE);
|
});
|
} catch (IOException e) {
|
SwingUtilities.invokeLater(() -> {
|
JOptionPane.showMessageDialog(this,
|
getString("send.udp.failed") + ": " + e.getMessage(),
|
getString("error"),
|
JOptionPane.ERROR_MESSAGE);
|
});
|
} finally {
|
// 关闭socket
|
if (socket != null && !socket.isClosed()) {
|
socket.close();
|
}
|
}
|
}).start();
|
|
} catch (Exception e) {
|
JOptionPane.showMessageDialog(this,
|
getString("save.config.error") + ": " + e.getMessage(),
|
getString("error"),
|
JOptionPane.ERROR_MESSAGE);
|
e.printStackTrace();
|
}
|
}
|
|
/**
|
* 从基础设置UI更新DeviceConfig
|
*/
|
private void updateDeviceConfigFromBasicSettings() {
|
// IP地址类型
|
currentDeviceConfig.setIpType(ipTypeComboBox.getSelectedIndex());
|
|
// 网络配置
|
currentDeviceConfig.setStaticIp(staticIpField.getText().trim());
|
currentDeviceConfig.setSubnetMask(subnetMaskField.getText().trim());
|
currentDeviceConfig.setGatewayIp(gatewayField.getText().trim());
|
currentDeviceConfig.setDnsServer(dnsServerField.getText().trim());
|
currentDeviceConfig.setMacAddress(macAddressField.getText().trim());
|
|
// 设备信息
|
currentDeviceConfig.setModuleName(deviceNameField.getText().trim());
|
currentDeviceConfig.setUsername(usernameField.getText().trim());
|
currentDeviceConfig.setPassword(passwordField.getText().trim());
|
|
// 数字字段需要转换
|
try {
|
if (!httpServerPortField.getText().trim().isEmpty()) {
|
currentDeviceConfig.setHttpServerPort(Integer.parseInt(httpServerPortField.getText().trim()));
|
}
|
if (!timeoutRestartField.getText().trim().isEmpty()) {
|
currentDeviceConfig.setTimeoutRestart(Integer.parseInt(timeoutRestartField.getText().trim()));
|
}
|
} catch (NumberFormatException e) {
|
throw new RuntimeException(getString("port.timeout.format.error"), e);
|
}
|
|
// 功能选项
|
currentDeviceConfig.setIndex(indexCheckBox.isSelected());
|
currentDeviceConfig.setReset(resetCheckBox.isSelected());
|
currentDeviceConfig.setLink(linkCheckBox.isSelected());
|
currentDeviceConfig.setRfc2217(rfc2217CheckBox.isSelected());
|
currentDeviceConfig.setCacheClear(cacheClearCheckBox.isSelected());
|
}
|
|
/**
|
* 从端口设置UI更新DeviceConfig
|
*/
|
private void updateDeviceConfigFromPortSettings() {
|
// 串口配置
|
try {
|
if (baudRateComboBox.getSelectedItem() != null) {
|
currentDeviceConfig.setBaudRate(Integer.parseInt(baudRateComboBox.getSelectedItem().toString()));
|
}
|
|
// 数据位、校验位、停止位需要根据描述反向映射到数值
|
currentDeviceConfig.setDataBitsDesc(dataBitsComboBox.getSelectedItem().toString());
|
currentDeviceConfig.setParityDesc(parityComboBox.getSelectedItem().toString());
|
currentDeviceConfig.setStopBitsDesc(stopBitsComboBox.getSelectedItem().toString());
|
|
} catch (NumberFormatException e) {
|
throw new RuntimeException(getString("baudrate.format.error"), e);
|
}
|
|
// 通信配置
|
currentDeviceConfig.setWorkModeDesc(workModeComboBox.getSelectedItem().toString());
|
currentDeviceConfig.setTargetUrl(targetUrlField.getText().trim());
|
|
// 数字字段需要转换
|
try {
|
if (!shortConnectionTimeField.getText().trim().isEmpty()) {
|
currentDeviceConfig.setShortConnectionTime(Integer.parseInt(shortConnectionTimeField.getText().trim()));
|
}
|
if (!localPortField.getText().trim().isEmpty()) {
|
currentDeviceConfig.setLocalPort(Integer.parseInt(localPortField.getText().trim()));
|
}
|
if (!remotePortField.getText().trim().isEmpty()) {
|
currentDeviceConfig.setRemotePort(Integer.parseInt(remotePortField.getText().trim()));
|
}
|
if (tcpClientCountComboBox.getSelectedItem() != null) {
|
currentDeviceConfig.setTcpClientCount(Integer.parseInt(tcpClientCountComboBox.getSelectedItem().toString()));
|
}
|
} catch (NumberFormatException e) {
|
throw new RuntimeException(getString("port.time.format.error"), e);
|
}
|
|
// 连接类型
|
currentDeviceConfig.setConnectionType(enableShortConnectionCheckBox.isSelected() ? 0 : 1);
|
}
|
|
/**
|
* 将DeviceConfig配置数据应用到UI组件
|
*/
|
public void updateUIWithDeviceConfig(DeviceConfig config) {
|
if (config == null) return;
|
|
// 在EDT线程中更新UI
|
SwingUtilities.invokeLater(() -> {
|
try {
|
// 更新基础设置面板
|
updateBasicSettings(config);
|
// 更新端口设置面板
|
updatePortSettings(config);
|
} catch (Exception e) {
|
System.err.println(getString("update.ui.error") + ": " + e.getMessage());
|
e.printStackTrace();
|
}
|
});
|
}
|
|
private void updateBasicSettings(DeviceConfig config) {
|
// IP地址类型
|
if (ipTypeComboBox != null) {
|
ipTypeComboBox.setSelectedIndex(config.getIpType());
|
}
|
|
// 网络配置
|
setTextFieldText(staticIpField, config.getStaticIp());
|
setTextFieldText(subnetMaskField, config.getSubnetMask());
|
setTextFieldText(gatewayField, config.getGatewayIp());
|
setTextFieldText(dnsServerField, config.getDnsServer());
|
setTextFieldText(macAddressField, config.getMacAddress());
|
|
// 设备信息
|
setTextFieldText(deviceNameField, config.getModuleName());
|
setTextFieldText(usernameField, config.getUsername());
|
setTextFieldText(passwordField, config.getPassword());
|
setTextFieldText(httpServerPortField, String.valueOf(config.getHttpServerPort()));
|
setTextFieldText(timeoutRestartField, String.valueOf(config.getTimeoutRestart()));
|
|
// 功能选项
|
setCheckBoxSelected(indexCheckBox, config.isIndex());
|
setCheckBoxSelected(resetCheckBox, config.isReset());
|
setCheckBoxSelected(linkCheckBox, config.isLink());
|
setCheckBoxSelected(rfc2217CheckBox, config.isRfc2217());
|
setCheckBoxSelected(cacheClearCheckBox, config.isCacheClear());
|
}
|
|
private void updatePortSettings(DeviceConfig config) {
|
// 串口配置
|
setComboBoxSelectedItem(baudRateComboBox, String.valueOf(config.getBaudRate()));
|
setComboBoxSelectedItem(dataBitsComboBox, config.getDataBitsDesc());
|
setComboBoxSelectedItem(parityComboBox, config.getParityDesc());
|
setComboBoxSelectedItem(stopBitsComboBox, config.getStopBitsDesc());
|
|
// 通信配置
|
setComboBoxSelectedItem(workModeComboBox, config.getWorkModeDesc());
|
setTextFieldText(targetUrlField, config.getTargetUrl());
|
setTextFieldText(shortConnectionTimeField, String.valueOf(config.getShortConnectionTime()));
|
setTextFieldText(localPortField, String.valueOf(config.getLocalPort()));
|
setTextFieldText(remotePortField, String.valueOf(config.getRemotePort()));
|
setComboBoxSelectedItem(tcpClientCountComboBox, String.valueOf(config.getTcpClientCount()));
|
|
// 连接类型
|
setCheckBoxSelected(enableShortConnectionCheckBox, config.getConnectionType() == 0);
|
}
|
|
// 辅助方法
|
private void setTextFieldText(JTextField field, String text) {
|
if (field != null && text != null) {
|
field.setText(text);
|
}
|
}
|
|
private void setCheckBoxSelected(JCheckBox checkBox, boolean selected) {
|
if (checkBox != null) {
|
checkBox.setSelected(selected);
|
}
|
}
|
|
private void setComboBoxSelectedItem(JComboBox<String> comboBox, String item) {
|
if (comboBox != null && item != null) {
|
comboBox.setSelectedItem(item);
|
}
|
}
|
|
/**
|
* 搜索设备 - 发送UDP广播数据并监听返回
|
*/
|
private void searchDevices() {
|
new Thread(() -> {
|
DatagramSocket socket = null;
|
try {
|
// 创建UDP Socket
|
socket = new DatagramSocket();
|
socket.setBroadcast(true);
|
// 设置接收超时时间为5秒
|
socket.setSoTimeout(5000);
|
// 准备要发送的数据:FF 01 01 02 (十六进制字节)
|
byte[] sendData = DellS2.serch();
|
// 创建广播地址:255.255.255.255,端口1500
|
InetAddress broadcastAddress = InetAddress.getByName("255.255.255.255");
|
int port = 1500;
|
DellS2.getRow().removeAllElements();
|
prepareSearch();
|
// 创建数据包
|
DatagramPacket packet = new DatagramPacket(sendData, sendData.length, broadcastAddress, port);
|
// 发送数据包
|
socket.send(packet);
|
// 监听设备响应
|
listenForDeviceResponses(socket);
|
} catch (SocketException e) {
|
e.printStackTrace();
|
} catch (UnknownHostException e) {
|
e.printStackTrace();
|
} catch (IOException e) {
|
// 如果是超时异常,属于正常情况
|
if (e instanceof SocketTimeoutException) {
|
System.out.println(getString("listen.timeout"));
|
SwingUtilities.invokeLater(() -> {
|
JOptionPane.showMessageDialog(this,
|
getString("search.complete.timeout"),
|
getString("search.complete"),
|
JOptionPane.INFORMATION_MESSAGE);
|
});
|
} else {
|
SwingUtilities.invokeLater(() -> {
|
JOptionPane.showMessageDialog(this,
|
getString("send.receive.udp.failed") + ": " + e.getMessage(),
|
getString("error"),
|
JOptionPane.ERROR_MESSAGE);
|
});
|
e.printStackTrace();
|
}
|
} finally {
|
// 关闭socket
|
if (socket != null && !socket.isClosed()) {
|
socket.close();
|
}
|
}
|
}).start();
|
}
|
|
/**
|
* 监听设备响应
|
*/
|
private void listenForDeviceResponses(DatagramSocket socket) {
|
try {
|
int responseCount = 0;
|
long startTime = System.currentTimeMillis();
|
long timeout = 5000; // 5秒超时
|
|
// 持续监听直到超时
|
while (System.currentTimeMillis() - startTime < timeout) {
|
try {
|
// 准备接收缓冲区
|
byte[] receiveData = new byte[1024];
|
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
|
|
// 设置剩余超时时间
|
long remainingTime = timeout - (System.currentTimeMillis() - startTime);
|
if (remainingTime <= 0) break;
|
|
socket.setSoTimeout((int) remainingTime);
|
|
// 接收数据
|
socket.receive(receivePacket);
|
responseCount++;
|
|
// 处理接收到的数据
|
processDeviceResponse(receivePacket, responseCount);
|
|
} catch (SocketTimeoutException e) {
|
// 超时继续循环,检查总超时
|
continue;
|
}
|
}
|
System.out.println(getString("search.complete.responses") + " " + responseCount + " " + getString("devices.found"));
|
|
} catch (IOException e) {
|
System.err.println(getString("listen.device.error") + ": " + e.getMessage());
|
e.printStackTrace();
|
}
|
}
|
|
/**
|
* 处理设备响应数据
|
*/
|
private void processDeviceResponse(DatagramPacket packet, int responseNumber) {
|
// 获取响应数据
|
byte[] responseData = packet.getData();
|
int dataLength = packet.getLength();
|
|
// 将字节数据转换为十六进制字符串
|
String hexData = bytesToHex(responseData, dataLength);
|
DellS2.serch_fanhui(hexData);
|
|
// 在UI线程中更新设备表格
|
SwingUtilities.invokeLater(() -> {
|
Vector<S2data> row = DellS2.getRow();
|
for (S2data s2data : row) {
|
addDeviceToTable(s2data);
|
}
|
});
|
}
|
|
/**
|
* 将字节数组转换为十六进制字符串
|
*/
|
private String bytesToHex(byte[] bytes, int length) {
|
StringBuilder hexString = new StringBuilder();
|
for (int i = 0; i < length; i++) {
|
String hex = Integer.toHexString(bytes[i] & 0xFF);
|
if (hex.length() == 1) {
|
hexString.append('0');
|
}
|
hexString.append(hex.toUpperCase());
|
}
|
return hexString.toString();
|
}
|
|
private JPanel createDeviceTablePanel() {
|
JPanel panel = new JPanel(new BorderLayout());
|
deviceListLabel = new JLabel(getString("device.list"));
|
panel.setBorder(BorderFactory.createTitledBorder(deviceListLabel.getText()));
|
|
String[] columnNames = {
|
getString("select"),
|
getString("device.ip"),
|
getString("device.name"),
|
getString("mac.address"),
|
getString("version")
|
};
|
|
// 显式使用 DefaultTableModel
|
javax.swing.table.DefaultTableModel model = new javax.swing.table.DefaultTableModel(columnNames, 0) {
|
@Override
|
public Class<?> getColumnClass(int columnIndex) {
|
// 第一列是Boolean类型(选择框)
|
if (columnIndex == 0) {
|
return Boolean.class;
|
}
|
return String.class;
|
}
|
|
@Override
|
public boolean isCellEditable(int row, int column) {
|
// 只有第一列(选择框)可编辑
|
return column == 0;
|
}
|
};
|
|
deviceTable = new JTable(model);
|
|
// 设置选择模式为单选
|
deviceTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
|
// 添加选择监听器,确保只能选择一个设备
|
deviceTable.getSelectionModel().addListSelectionListener(e -> {
|
if (!e.getValueIsAdjusting()) {
|
int selectedRow = deviceTable.getSelectedRow();
|
if (selectedRow != -1) {
|
// 取消其他行的选择框
|
for (int i = 0; i < deviceTable.getRowCount(); i++) {
|
if (i != selectedRow) {
|
deviceTable.setValueAt(Boolean.FALSE, i, 0);
|
}
|
}
|
// 设置当前行的选择框为选中状态
|
deviceTable.setValueAt(Boolean.TRUE, selectedRow, 0);
|
}
|
}
|
});
|
|
JScrollPane scrollPane = new JScrollPane(deviceTable);
|
panel.add(scrollPane, BorderLayout.CENTER);
|
|
return panel;
|
}
|
|
/**
|
* 清空设备表格
|
*/
|
public void clearDeviceTable() {
|
// 安全地获取模型
|
if (deviceTable.getModel() instanceof javax.swing.table.DefaultTableModel) {
|
javax.swing.table.DefaultTableModel model = (javax.swing.table.DefaultTableModel) deviceTable.getModel();
|
model.setRowCount(0);
|
System.out.println(getString("device.table.cleared"));
|
} else {
|
// 如果不是DefaultTableModel,使用其他方式清空
|
System.err.println(getString("table.model.error"));
|
}
|
}
|
|
/**
|
* 添加设备到表格
|
*/
|
private void addDeviceToTable(S2data deviceInfo) {
|
// 安全地获取模型
|
if (deviceTable.getModel() instanceof javax.swing.table.DefaultTableModel) {
|
javax.swing.table.DefaultTableModel model = (javax.swing.table.DefaultTableModel) deviceTable.getModel();
|
|
// 添加新设备到表格
|
Object[] rowData = {
|
Boolean.FALSE, // 选择框
|
deviceInfo.getIp(), // 设备IP
|
deviceInfo.getName(), // 设备名称
|
deviceInfo.getMac(), // MAC地址
|
deviceInfo.getVersion() // 版本
|
};
|
model.addRow(rowData);
|
} else {
|
System.err.println(getString("table.model.error"));
|
}
|
}
|
|
private JPanel createConfigPanel() {
|
JPanel panel = new JPanel();
|
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
|
// 创建包含基础设置和端口设置的滚动面板
|
JPanel contentPanel = new JPanel();
|
contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
|
|
// 添加顶部间距
|
contentPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
|
|
// 基础设置
|
basicSettingsPanel = createBasicSettingsPanel();
|
contentPanel.add(basicSettingsPanel);
|
contentPanel.add(Box.createVerticalStrut(10));
|
|
// 端口设置
|
portSettingsPanel = createPortSettingsPanel();
|
contentPanel.add(portSettingsPanel);
|
|
// 将内容面板放入滚动面板
|
JScrollPane scrollPane = new JScrollPane(contentPanel);
|
scrollPane.setBorder(BorderFactory.createEmptyBorder());
|
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
|
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
|
JPanel wrapperPanel = new JPanel(new BorderLayout());
|
wrapperPanel.add(scrollPane, BorderLayout.CENTER);
|
|
return wrapperPanel;
|
}
|
|
private JPanel createBasicSettingsPanel() {
|
JPanel panel = new JPanel();
|
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
panel.setBorder(BorderFactory.createTitledBorder(getString("basic.settings")));
|
|
// 第一行 - IP地址类型
|
ipTypeComboBox = createComboBox(new String[]{getString("static.ip")}, 150, 25);
|
panel.add(createParameterRow("ip.address.type", ipTypeComboBox, true));
|
|
// 第二行 - 模块静态IP
|
staticIpField = createTextField("", 150, 25);
|
panel.add(createParameterRow("module.static.ip", staticIpField, true));
|
|
// 第三行 - 子网掩码
|
subnetMaskField = createTextField("", 150, 25);
|
panel.add(createParameterRow("subnet.mask", subnetMaskField, true));
|
|
// 第四行 - 网关
|
gatewayField = createTextField("", 150, 25);
|
panel.add(createParameterRow("gateway", gatewayField, true));
|
|
// 第五行 - DNS地址
|
dnsServerField = createTextField("", 150, 25);
|
panel.add(createParameterRow("dns.address", dnsServerField, false));
|
|
// 第六行 - 用户MAC地址
|
macAddressField = createTextField("", 150, 25);
|
panel.add(createParameterRow("user.mac.address", macAddressField, false));
|
|
// 第七行 - 超时重启时间
|
timeoutRestartField = createTextField("", 150, 25);
|
panel.add(createParameterRow("timeout.restart", timeoutRestartField, false));
|
|
// 第八行 - HTTP服务端口
|
httpServerPortField = createTextField("", 150, 25);
|
panel.add(createParameterRow("http.service.port", httpServerPortField, false));
|
|
// 第九行 - 用户名
|
usernameField = createTextField("", 150, 25);
|
panel.add(createParameterRow("username", usernameField, false));
|
|
// 第十行 - 密码
|
passwordField = createTextField("", 150, 25);
|
panel.add(createParameterRow("password", passwordField, false));
|
|
// 第十一行 - 设备名称
|
deviceNameField = createTextField("", 150, 25);
|
panel.add(createParameterRow("device.name", deviceNameField, false));
|
|
// 第十二行 - 选项复选框(第一行)
|
JPanel optionPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0));
|
optionsLabel = new JLabel(getString("options") + ":");
|
optionPanel.add(optionsLabel);
|
|
JPanel checkPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
|
indexCheckBox = new JCheckBox(getString("option.index"));
|
resetCheckBox = new JCheckBox(getString("option.reset"));
|
linkCheckBox = new JCheckBox(getString("option.link"));
|
rfc2217CheckBox = new JCheckBox(getString("option.rfc2217"));
|
|
checkPanel.add(indexCheckBox);
|
checkPanel.add(resetCheckBox);
|
checkPanel.add(linkCheckBox);
|
checkPanel.add(rfc2217CheckBox);
|
|
optionPanel.add(checkPanel);
|
optionPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35));
|
panel.add(optionPanel);
|
|
// 第十三行 - 选项复选框(第二行)
|
JPanel optionPanel2 = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0));
|
optionPanel2.add(new JLabel(" "));
|
|
JPanel checkPanel2 = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
|
cacheClearCheckBox = new JCheckBox(getString("clear.cache"));
|
serialSettingsCheckBox = new JCheckBox(getString("serial.settings"));
|
|
checkPanel2.add(cacheClearCheckBox);
|
checkPanel2.add(serialSettingsCheckBox);
|
|
optionPanel2.add(checkPanel2);
|
optionPanel2.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35));
|
panel.add(optionPanel2);
|
|
return panel;
|
}
|
|
private JPanel createPortSettingsPanel() {
|
JPanel panel = new JPanel();
|
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
panel.setBorder(BorderFactory.createTitledBorder(getString("port.settings")));
|
|
// 第一行 - 模块工作模式
|
workModeComboBox = createComboBox(new String[]{
|
getString("work.mode.udp.client"),
|
getString("work.mode.tcp.client"),
|
getString("work.mode.tcp.server")
|
}, 150, 25);
|
panel.add(createParameterRow("module.work.mode", workModeComboBox, false));
|
|
// 第二行 - 目标IP/域名
|
targetUrlField = createTextField("", 150, 25);
|
panel.add(createParameterRow("target.ip.domain", targetUrlField, false));
|
|
// 第三行 - 短连接时间
|
shortConnectionTimeField = createTextField("", 150, 25);
|
panel.add(createParameterRow("short.connection.time", shortConnectionTimeField, false));
|
|
// 第四行 - 串口波特率
|
baudRateComboBox = createComboBoxWithSelection(new String[]{"9600", "19200", "38400", "115200", "921600"}, "115200", 150, 25);
|
panel.add(createParameterRow("serial.baud.rate", baudRateComboBox, false));
|
|
// 第五行 - 本地端口
|
localPortField = createTextField("", 150, 25);
|
panel.add(createParameterRow("local.port", localPortField, false));
|
|
// 第六行 - 远程端口
|
remotePortField = createTextField("", 150, 25);
|
panel.add(createParameterRow("remote.port", remotePortField, false));
|
|
// 第七行 - TCP Server连接数
|
tcpClientCountComboBox = createComboBox(new String[]{"4", "3", "2", "1"}, 150, 25);
|
panel.add(createParameterRow("tcp.server.connections", tcpClientCountComboBox, false));
|
|
// 第八行 - 开启短连接复选框
|
JPanel shortConnPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0));
|
shortConnPanel.add(new JLabel(" "));
|
|
JPanel shortConnSubPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
|
enableShortConnectionCheckBox = new JCheckBox(getString("enable.short.connection"));
|
shortConnSubPanel.add(enableShortConnectionCheckBox);
|
|
shortConnPanel.add(shortConnSubPanel);
|
shortConnPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35));
|
panel.add(shortConnPanel);
|
|
// 第九行 - 校验/数据/停止
|
JPanel parityPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0));
|
parityDataStopLabel = new JLabel(getString("parity.data.stop") + ":");
|
parityPanel.add(parityDataStopLabel);
|
|
JPanel paritySubPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0));
|
parityComboBox = createComboBox(new String[]{getString("parity.none")}, 80, 25);
|
dataBitsComboBox = createComboBox(new String[]{"8"}, 60, 25);
|
stopBitsComboBox = createComboBox(new String[]{"1"}, 60, 25);
|
|
paritySubPanel.add(parityComboBox);
|
paritySubPanel.add(dataBitsComboBox);
|
paritySubPanel.add(stopBitsComboBox);
|
|
parityPanel.add(paritySubPanel);
|
parityPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35));
|
panel.add(parityPanel);
|
|
return panel;
|
}
|
|
// 创建参数行的辅助方法,参考BaseStationPanel的布局
|
private JPanel createParameterRow(String paramKey, JComponent component, boolean withStar) {
|
JPanel paramPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0));
|
|
String labelText = getString(paramKey);
|
if (withStar) {
|
labelText += " ★";
|
}
|
|
JLabel label = new JLabel(labelText);
|
label.setPreferredSize(new Dimension(140, 25));
|
|
// 保存标签引用,用于语言切换
|
parameterLabels.put(paramKey, label);
|
|
paramPanel.add(label);
|
paramPanel.add(component);
|
|
// 设置固定高度
|
paramPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 35));
|
return paramPanel;
|
}
|
|
// 创建文本框的辅助方法
|
private JTextField createTextField(String text, int width, int height) {
|
JTextField textField = new JTextField(text);
|
textField.setPreferredSize(new Dimension(width, height));
|
return textField;
|
}
|
|
// 创建下拉框的辅助方法
|
private JComboBox<String> createComboBox(String[] items, int width, int height) {
|
JComboBox<String> comboBox = new JComboBox<>(items);
|
comboBox.setPreferredSize(new Dimension(width, height));
|
return comboBox;
|
}
|
|
// 创建带默认选择的下拉框
|
private JComboBox<String> createComboBoxWithSelection(String[] items, String selected, int width, int height) {
|
JComboBox<String> comboBox = createComboBox(items, width, height);
|
comboBox.setSelectedItem(selected);
|
return comboBox;
|
}
|
|
public void updateLanguage() {
|
// 更新控制面板按钮文本
|
searchBtn.setText(getString("search.devices"));
|
readBtn.setText(getString("read.parameters"));
|
saveBtn.setText(getString("save.parameters"));
|
|
// 更新设备表格标题
|
if (deviceListLabel != null) {
|
deviceListLabel.setText(getString("device.list"));
|
// 更新表格边框标题
|
if (deviceTable != null && deviceTable.getParent() != null &&
|
deviceTable.getParent().getParent() instanceof JPanel) {
|
JPanel tablePanel = (JPanel) deviceTable.getParent().getParent();
|
tablePanel.setBorder(BorderFactory.createTitledBorder(getString("device.list")));
|
}
|
}
|
|
// 更新设置面板边框标题
|
if (basicSettingsPanel != null) {
|
basicSettingsPanel.setBorder(BorderFactory.createTitledBorder(getString("basic.settings")));
|
}
|
if (portSettingsPanel != null) {
|
portSettingsPanel.setBorder(BorderFactory.createTitledBorder(getString("port.settings")));
|
}
|
|
// 更新所有参数行的标签文本
|
updateParameterRowLabels();
|
|
// 更新其他独立标签
|
if (optionsLabel != null) {
|
optionsLabel.setText(getString("options") + ":");
|
}
|
if (parityDataStopLabel != null) {
|
parityDataStopLabel.setText(getString("parity.data.stop") + ":");
|
}
|
|
// 更新复选框文本
|
if (indexCheckBox != null) {
|
indexCheckBox.setText(getString("option.index"));
|
}
|
if (resetCheckBox != null) {
|
resetCheckBox.setText(getString("option.reset"));
|
}
|
if (linkCheckBox != null) {
|
linkCheckBox.setText(getString("option.link"));
|
}
|
if (rfc2217CheckBox != null) {
|
rfc2217CheckBox.setText(getString("option.rfc2217"));
|
}
|
if (cacheClearCheckBox != null) {
|
cacheClearCheckBox.setText(getString("clear.cache"));
|
}
|
if (serialSettingsCheckBox != null) {
|
serialSettingsCheckBox.setText(getString("serial.settings"));
|
}
|
if (enableShortConnectionCheckBox != null) {
|
enableShortConnectionCheckBox.setText(getString("enable.short.connection"));
|
}
|
|
// 更新工作模式下拉框选项
|
if (workModeComboBox != null) {
|
String currentSelection = (String) workModeComboBox.getSelectedItem();
|
workModeComboBox.removeAllItems();
|
workModeComboBox.addItem(getString("work.mode.udp.client"));
|
workModeComboBox.addItem(getString("work.mode.tcp.client"));
|
workModeComboBox.addItem(getString("work.mode.tcp.server"));
|
// 尝试恢复之前的选择
|
if (currentSelection != null) {
|
try {
|
// 尝试根据旧值找到对应的新值
|
if (currentSelection.contains("UDP")) {
|
workModeComboBox.setSelectedItem(getString("work.mode.udp.client"));
|
} else if (currentSelection.contains("TCP Client")) {
|
workModeComboBox.setSelectedItem(getString("work.mode.tcp.client"));
|
} else if (currentSelection.contains("TCP Server")) {
|
workModeComboBox.setSelectedItem(getString("work.mode.tcp.server"));
|
}
|
} catch (Exception e) {
|
// 如果恢复失败,选择第一项
|
if (workModeComboBox.getItemCount() > 0) {
|
workModeComboBox.setSelectedIndex(0);
|
}
|
}
|
}
|
}
|
|
// 更新校验位下拉框选项
|
if (parityComboBox != null) {
|
String currentSelection = (String) parityComboBox.getSelectedItem();
|
parityComboBox.removeAllItems();
|
parityComboBox.addItem(getString("parity.none"));
|
// 恢复之前的选择
|
if (currentSelection != null && currentSelection.equals("NONE")) {
|
parityComboBox.setSelectedItem(getString("parity.none"));
|
} else if (parityComboBox.getItemCount() > 0) {
|
parityComboBox.setSelectedIndex(0);
|
}
|
}
|
|
// 更新表格列名
|
updateTableColumnNames();
|
|
revalidate();
|
repaint();
|
}
|
|
/**
|
* 更新所有参数行的标签文本
|
*/
|
private void updateParameterRowLabels() {
|
// 需要带星号的参数键列表(根据 createParameterRow 调用时的 withStar 参数)
|
Set<String> keysWithStar = new HashSet<>();
|
keysWithStar.add("ip.address.type");
|
keysWithStar.add("module.static.ip");
|
keysWithStar.add("subnet.mask");
|
keysWithStar.add("gateway");
|
|
// 更新所有保存的标签
|
for (Map.Entry<String, JLabel> entry : parameterLabels.entrySet()) {
|
String paramKey = entry.getKey();
|
JLabel label = entry.getValue();
|
if (label != null) {
|
String labelText = getString(paramKey);
|
// 如果这个参数需要星号,添加星号
|
if (keysWithStar.contains(paramKey)) {
|
labelText += " ★";
|
}
|
label.setText(labelText);
|
}
|
}
|
}
|
|
/**
|
* 更新表格列名
|
*/
|
private void updateTableColumnNames() {
|
if (deviceTable != null && deviceTable.getModel() instanceof javax.swing.table.DefaultTableModel) {
|
javax.swing.table.DefaultTableModel model = (javax.swing.table.DefaultTableModel) deviceTable.getModel();
|
|
String[] columnNames = {
|
getString("select"),
|
getString("device.ip"),
|
getString("device.name"),
|
getString("mac.address"),
|
getString("version")
|
};
|
|
// 保存当前数据
|
int rowCount = model.getRowCount();
|
Object[][] data = new Object[rowCount][columnNames.length];
|
for (int i = 0; i < rowCount; i++) {
|
for (int j = 0; j < columnNames.length; j++) {
|
if (j < model.getColumnCount()) {
|
data[i][j] = model.getValueAt(i, j);
|
}
|
}
|
}
|
|
// 更新列名和数据
|
model.setColumnIdentifiers(columnNames);
|
}
|
}
|
|
private String getString(String key) {
|
return mainFrame.getString(key);
|
}
|
|
/**
|
* 在搜索开始时调用,清空旧数据并准备新搜索
|
*/
|
private void prepareSearch() {
|
clearDeviceTable();
|
}
|
}
|