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 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 workModeComboBox; private JTextField targetUrlField; private JTextField shortConnectionTimeField; private JComboBox baudRateComboBox; private JTextField localPortField; private JTextField remotePortField; private JComboBox tcpClientCountComboBox; private JCheckBox enableShortConnectionCheckBox; // 串口参数组件 private JComboBox parityComboBox; private JComboBox dataBitsComboBox; private JComboBox 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 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 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 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 createComboBox(String[] items, int width, int height) { JComboBox comboBox = new JComboBox<>(items); comboBox.setPreferredSize(new Dimension(width, height)); return comboBox; } // 创建带默认选择的下拉框 private JComboBox createComboBoxWithSelection(String[] items, String selected, int width, int height) { JComboBox 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 keysWithStar = new HashSet<>(); keysWithStar.add("ip.address.type"); keysWithStar.add("module.static.ip"); keysWithStar.add("subnet.mask"); keysWithStar.add("gateway"); // 更新所有保存的标签 for (Map.Entry 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(); } }