package home; import javax.swing.*; import java.awt.*; import java.util.Locale; import java.util.ResourceBundle; import java.io.InputStream; import java.io.IOException; import java.io.File; import java.io.FileInputStream; import java.util.PropertyResourceBundle; public class MainFrame extends JFrame { private static final long serialVersionUID = 1L; private ResourceBundle messages; private Locale currentLocale; private CardLayout cardLayout; private JPanel mainPanel; private JButton serialCommBtn, networkCommBtn, networkConfigBtn; private JComboBox languageCombo; // ¸÷¹¦ÄÜÃæ°å private SerialCommunicationPanel serialPanel; private NetworkCommunicationPanel networkPanel; private NetworkConfigPanel configPanel; private DataLogPanel dataLogPanel; private SendPanel sendPanel; // ÐÂÔö£º¿ì½Ý¼ÆËãÃæ°åÏà¹Ø private JButton quickCalcBtn; private JDialog quickCalcDialog; private QuickCalculationPanel quickCalcPanel; public MainFrame() { this.currentLocale = Locale.SIMPLIFIED_CHINESE; this.messages = loadResourceBundle(currentLocale); 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()); // ±¸Ó÷½°¸£º³¢ÊÔ´ÓÀà·¾¶¼ÓÔØ try { return ResourceBundle.getBundle("Messages", locale); } catch (Exception e) { System.err.println("ÎÞ·¨¼ÓÔØ±¸ÓÃ×ÊÔ´Îļþ"); return createDefaultResourceBundle(); } } try (InputStream inputStream = new FileInputStream(langFile)) { return new PropertyResourceBundle(inputStream); } catch (IOException e) { System.err.println("ÎÞ·¨¼ÓÔØ×ÊÔ´Îļþ: " + e.getMessage()); // ±¸Ó÷½°¸ try { return ResourceBundle.getBundle("Messages", locale); } catch (Exception ex) { System.err.println("ÎÞ·¨¼ÓÔØ±¸ÓÃ×ÊÔ´Îļþ"); return createDefaultResourceBundle(); } } } private ResourceBundle createDefaultResourceBundle() { // ´´½¨Ä¬ÈÏ×ÊÔ´°ü£¨ÖÐÎÄ£© java.util.Properties properties = new java.util.Properties(); properties.setProperty("app.title", "ÅäÖÃÈí¼þ"); properties.setProperty("serial.communication", "´®¿ÚͨÐÅ"); properties.setProperty("network.communication", "ÍøÂçͨÐÅ"); properties.setProperty("network.config", "ÍøÂçÅäÖÃ"); properties.setProperty("language.switch", "ÓïÑÔÇл»"); properties.setProperty("select.serial", "Ñ¡Ôñ´®¿Ú"); properties.setProperty("baud.rate", "²¨ÌØÂÊ"); properties.setProperty("open", "´ò¿ª"); properties.setProperty("close", "¹Ø±Õ"); // ÐÂÔö£º¿ì½Ý¼ÆËãÏà¹Ø×ÊÔ´ properties.setProperty("quick.calculation", "¿ì½Ý¼ÆËã"); properties.setProperty("quick.calc.title", "×ø±ê¼ÆË㹤¾ß"); try { return new PropertyResourceBundle(new java.io.ByteArrayInputStream( properties.toString().replace("=", ": ").getBytes())); } catch (IOException e) { e.printStackTrace(); } return messages; } public String getString(String key) { if (messages != null) { try { return messages.getString(key); } catch (Exception e) { // Èç¹û×ÊÔ´ÎļþÖÐûÓÐÕÒµ½¶ÔÓ¦µÄkey£¬·µ»ØÄ¬ÈÏÖµ return getDefaultString(key); } } return getDefaultString(key); } private String getDefaultString(String key) { // ĬÈÏÎı¾£¨ÖÐÎÄ£© switch (key) { case "app.title": return "ÅäÖÃÈí¼þ"; case "serial.communication": return "´®¿ÚͨÐÅ"; case "network.communication": return "ÍøÂçͨÐÅ"; case "network.config": return "ÍøÂçÅäÖÃ"; case "language.switch": return "ÓïÑÔÇл»"; case "select.serial": return "Ñ¡Ôñ´®¿Ú"; case "baud.rate": return "²¨ÌØÂÊ"; case "open": return "´ò¿ª"; case "close": return "¹Ø±Õ"; case "base.parameters": return "»ù´¡²ÎÊý"; case "base.station": return "»ùÕ¾"; case "tag": return "±êÇ©"; case "anti.collision": return "·Àײ"; case "upgrade": return "Éý¼¶"; case "device.version": return "É豸°æ±¾"; case "device.id": return "É豸±àºÅ"; case "comm.frequency": return "ͨÐÅÆµÂÊ"; case "base.stations.per.comm": return "µ¥´ÎͨÐÅ»ùÕ¾Êý"; case "group.id": return "·Ö×é±àºÅ"; case "distance.calibration": return "¾àÀëУ׼ֵ"; case "device.type": return "É豸ÀàÐÍ"; case "base.station.ranging": return "»ùÕ¾Ö÷¶¯²â¾à"; case "alarm.device": return "±¨¾¯É豸"; case "pairing.id": return "Åä¶Ô±àºÅ"; case "heartbeat.switch": return "ÐÄÌø°ü¿ª¹Ø"; case "modbus.mode": return "MODBUSģʽ"; case "rf.power": return "É䯵·¢É书ÂÊ"; case "read.parameters": return "¶ÁÈ¡²ÎÊý"; case "save.parameters": return "±£´æ²ÎÊý"; case "restart.device": return "ÖØÆôÉ豸"; case "reset.factory": return "»Ö¸´³ö³§ÉèÖÃ"; case "protocol.type": return "ЭÒéÀàÐÍ"; case "local.host.address": return "±¾µØÖ÷»úµØÖ·"; case "local.host.port": return "±¾µØÖ÷»ú¶Ë¿Ú"; case "remote.host.address": return "Ô¶³ÌÖ÷»úµØÖ·"; case "remote.host.port": return "Ô¶³ÌÖ÷»ú¶Ë¿Ú"; case "data.log": return "Êý¾ÝÈÕÖ¾"; case "ascii.display": return "ASCIIÏÔʾ"; case "auto.save": return "×Ô¶¯±£´æ"; case "show.time": return "ÏÔʾʱ¼ä"; case "start": return "¿ªÊ¼"; case "pause": return "ÔÝÍ£"; case "clear": return "Çå¿Õ"; case "send.data": return "·¢ËÍÊý¾Ý"; case "hex.send": return "HEX·¢ËÍ"; case "loop.send": return "Ñ­»··¢ËÍ"; case "loop.time": return "Ñ­»·Ê±¼ä(ms)"; case "send": return "·¢ËÍ"; case "extension": return "À©Õ¹"; case "LANGUAGE": return "Language"; case "external.control": return "Íⲿ¿ØÖÆ"; case "adjacent.stations.count": return "ÏàÁÚ»ùÕ¾ÊýÁ¿"; case "adjacent.station1": return "ÏàÁÚ»ùÕ¾1"; case "adjacent.station2": return "ÏàÁÚ»ùÕ¾2"; case "adjacent.station3": return "ÏàÁÚ»ùÕ¾3"; case "adjacent.station4": return "ÏàÁÚ»ùÕ¾4"; case "adjacent.station5": return "ÏàÁÚ»ùÕ¾5"; case "adjacent.station6": return "ÏàÁÚ»ùÕ¾6"; case "adjacent.station7": return "ÏàÁÚ»ùÕ¾7"; case "adjacent.station8": return "ÏàÁÚ»ùÕ¾8"; case "adjacent.station9": return "ÏàÁÚ»ùÕ¾9"; case "adjacent.station10": return "ÏàÁÚ»ùÕ¾10"; case "sync.station.id": return "ͬ²½»ùÕ¾ID"; case "sync.station.type": return "ͬ²½»ùÕ¾ÀàÐÍ"; case "tag.id": return "±êÇ©ID"; case "tag.type": return "±êÇ©ÀàÐÍ"; case "tag.mode": return "±êǩģʽ"; case "tag.interval": return "±êÇ©¼ä¸ô"; case "tag.power": return "±êÇ©¹¦ÂÊ"; case "tag.sensitivity": return "±êÇ©ÁéÃô¶È"; case "anti.collision.enable": return "·ÀײʹÄÜ"; case "safety.distance": return "°²È«¾àÀë"; case "warning.distance": return "¾¯¸æ¾àÀë"; case "alarm.distance": return "±¨¾¯¾àÀë"; case "alarm.type": return "±¨¾¯ÀàÐÍ"; case "upgrade.description": return "¹Ì¼þÉý¼¶¹¦ÄÜ\n\nÇëÑ¡ÔñÒªÉý¼¶µÄ¹Ì¼þÎļþ£¬È»ºóµã»÷¿ªÊ¼Éý¼¶°´Å¥¡£Éý¼¶¹ý³ÌÖÐÇëÎð¶Ï¿ªµçÔ´¡£"; case "start.upgrade": return "¿ªÊ¼Éý¼¶"; // ÐÂÔö£º¿ì½Ý¼ÆËãÏà¹Ø¼üÖµ¶Ô case "quick.calculation": return "¿ì½Ý¼ÆËã"; case "quick.calc.title": return "×ø±ê¼ÆË㹤¾ß"; // Éý¼¶Ïà¹Ø¼üÖµ¶Ô case "upgrade.instructions": return "Éý¼¶ËµÃ÷"; case "select.folder": return "Ñ¡ÔñÎļþ¼Ð"; case "browse": return "ä¯ÀÀ"; case "select.bin.file": return "Ñ¡ÔñBINÎļþ"; case "selected.file": return "ÒÑÑ¡ÔñÎļþ"; case "file.selected": return "ÎļþÒÑÑ¡Ôñ"; case "please.select.folder.first": return "ÇëÏÈÑ¡ÔñÎļþ¼Ð"; case "warning": return "¾¯¸æ"; case "upgrade.completed": return "Éý¼¶Íê³É"; case "success": return "³É¹¦"; case "upgrade.in.progress": return "Éý¼¶½øÐÐÖÐ..."; case "select.upgrade.file": return "Ñ¡ÔñÉý¼¶Îļþ"; case "upgrade.file": return "Éý¼¶Îļþ"; case "upgrade.progress": return "Éý¼¶½ø¶È"; case "cancel.upgrade": return "È¡ÏûÉý¼¶"; case "upgrade.success": return "Éý¼¶³É¹¦"; case "upgrade.failed": return "Éý¼¶Ê§°Ü"; case "confirm.upgrade": return "È·ÈÏÉý¼¶"; case "upgrade.confirmation": return "Éý¼¶È·ÈÏ"; case "upgrade.confirm.message": return "È·¶¨Òª¿ªÊ¼Éý¼¶Âð£¿Éý¼¶¹ý³ÌÖÐÇëÎð¶Ï¿ªµçÔ´¡£"; case "select.file": return "Ñ¡ÔñÎļþ"; case "no.file.selected": return "δѡÔñÎļþ"; case "file.not.found": return "ÎļþδÕÒµ½"; case "invalid.file": return "ÎÞЧÎļþ"; case "upgrade.ready": return "×¼±¸Éý¼¶"; case "preparing.upgrade": return "×¼±¸Éý¼¶»·¾³..."; case "writing.firmware": return "дÈë¹Ì¼þ..."; case "verifying.firmware": return "ÑéÖ¤¹Ì¼þ..."; case "upgrade.cancelled": return "Éý¼¶ÒÑÈ¡Ïû"; // À©Õ¹Ãæ°åÏà¹Ø¼üÖµ¶Ô case "common.commands": return "³£ÓÃÖ¸Áî"; case "command.string": return "Ö¸Áî×Ö·û´®"; case "save.common.commands": return "±£´æ³£ÓÃÖ¸Áî"; case "modify.common.commands": return "Ð޸ij£ÓÃÖ¸Áî"; case "load.commands.failed": return "¼ÓÔØÖ¸Áîʧ°Ü£º"; case "save.commands.success": return "±£´æÖ¸Áî³É¹¦£¡"; case "save.commands.failed": return "±£´æÖ¸Áîʧ°Ü£º"; case "command.cannot.empty": return "Ö¸Áî²»ÄÜΪ¿Õ£¡"; case "now.can.modify.commands": return "ÏÖÔÚ¿ÉÒÔÐ޸ıí¸ñÖеÄÖ¸ÁîÄÚÈÝ£¬ÐÞ¸ÄÍê³Éºóµã»÷±£´æ³£ÓÃÖ¸Áî°´Å¥"; case "prompt": return "Ìáʾ"; case "error": return "´íÎó"; // À©Õ¹ÃüÁîÏà¹Ø¼üÖµ¶Ô case "extension.command": return "À©Õ¹ÃüÁî"; default: return key; } } private void initializeUI() { setTitle(getString("app.title")); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(1200, 800); setLocationRelativeTo(null); // ´´½¨¶¥²¿°´Å¥Ãæ°å JPanel topPanel = createTopPanel(); // ´´½¨Ö÷ÄÚÈÝÃæ°å cardLayout = new CardLayout(); mainPanel = new JPanel(cardLayout); // ³õʼ»¯¸÷¹¦ÄÜÃæ°å serialPanel = new SerialCommunicationPanel(this); networkPanel = new NetworkCommunicationPanel(this); configPanel = new NetworkConfigPanel(this); mainPanel.add(serialPanel, "SERIAL"); mainPanel.add(networkPanel, "NETWORK"); mainPanel.add(configPanel, "CONFIG"); // ´´½¨ÓÒ²àÃæ°å£¨Êý¾ÝÈÕÖ¾ºÍ·¢ËÍÃæ°å£© JPanel rightPanel = createRightPanel(); // ÉèÖò¼¾Ö setLayout(new BorderLayout()); add(topPanel, BorderLayout.NORTH); add(mainPanel, BorderLayout.CENTER); add(rightPanel, BorderLayout.EAST); // ³õʼ»¯¿ì½Ý¼ÆËã¶Ô»°¿ò initQuickCalculationDialog(); // Ìí¼Óʼþ¼àÌý setupEventListeners(); // ¹Ø¼üÐ޸ģºÁ¬½Ó´®¿ÚÃæ°åºÍÊý¾ÝÈÕÖ¾Ãæ°å connectPanels(); } private JPanel createTopPanel() { JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT)); // ʹÓÃButtonUtils´´½¨µ¼º½°´Å¥ serialCommBtn = ButtonUtils.createBlueButton(getString("serial.communication")); networkCommBtn = ButtonUtils.createBlueButton(getString("network.communication")); networkConfigBtn = ButtonUtils.createBlueButton(getString("network.config")); // ÐÂÔö£º¿ì½Ý¼ÆËã°´Å¥ quickCalcBtn = ButtonUtils.createBlueButton(getString("quick.calculation")); languageCombo = new JComboBox<>(new String[]{"ÖÐÎÄ", "English"}); languageCombo.setSelectedIndex(0); languageCombo.addActionListener(e -> { Locale newLocale = languageCombo.getSelectedIndex() == 0 ? Locale.SIMPLIFIED_CHINESE : Locale.ENGLISH; switchLanguage(newLocale); }); panel.add(serialCommBtn); panel.add(networkCommBtn); panel.add(networkConfigBtn); panel.add(quickCalcBtn); // Ìí¼Ó¿ì½Ý¼ÆËã°´Å¥ JLabel languageLabel = new JLabel(getString("LANGUAGE") + ":"); panel.add(Box.createHorizontalStrut(20)); panel.add(languageLabel); panel.add(languageCombo); return panel; } private JPanel createRightPanel() { JPanel panel = new JPanel(new BorderLayout()); panel.setPreferredSize(new Dimension(400, getHeight())); dataLogPanel = new DataLogPanel(this); sendPanel = new SendPanel(this); panel.add(dataLogPanel, BorderLayout.CENTER); panel.add(sendPanel, BorderLayout.SOUTH); return panel; } /** * ³õʼ»¯¿ì½Ý¼ÆËã¶Ô»°¿ò */ private void initQuickCalculationDialog() { quickCalcDialog = new JDialog(this, getString("quick.calc.title"), false); quickCalcDialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE); quickCalcDialog.setSize(900, 700); quickCalcDialog.setLocationRelativeTo(this); // ´´½¨¿ì½Ý¼ÆËãÃæ°å quickCalcPanel = new QuickCalculationPanel(messages); quickCalcDialog.add(quickCalcPanel); } private void setupEventListeners() { serialCommBtn.addActionListener(e -> cardLayout.show(mainPanel, "SERIAL")); networkCommBtn.addActionListener(e -> cardLayout.show(mainPanel, "NETWORK")); networkConfigBtn.addActionListener(e -> cardLayout.show(mainPanel, "CONFIG")); // ÐÂÔö£º¿ì½Ý¼ÆË㰴ťʼþ¼àÌý quickCalcBtn.addActionListener(e -> { quickCalcDialog.setVisible(true); }); } /** * ¹Ø¼üÐ޸ģºÁ¬½Ó´®¿ÚÃæ°åºÍÊý¾ÝÈÕÖ¾Ãæ°å */ private void connectPanels() { if (serialPanel != null && dataLogPanel != null) { serialPanel.setDataLogPanel(dataLogPanel); } } 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() { // ¸üе¼º½°´Å¥Îı¾ serialCommBtn.setText(getString("serial.communication")); networkCommBtn.setText(getString("network.communication")); networkConfigBtn.setText(getString("network.config")); quickCalcBtn.setText(getString("quick.calculation")); // ¸üпì½Ý¼ÆËã°´Å¥Îı¾ // ¸üÐÂÓïÑÔ±êÇ© setTitle(getString("app.title")); // ¸üжԻ°¿ò±êÌâ if (quickCalcDialog != null) { quickCalcDialog.setTitle(getString("quick.calc.title")); } // ¸üи÷Ãæ°åÎı¾ if (serialPanel != null) serialPanel.updateLanguage(); if (networkPanel != null) networkPanel.updateLanguage(); if (configPanel != null) configPanel.updateLanguage(); if (dataLogPanel != null) dataLogPanel.updateLanguage(); if (sendPanel != null) sendPanel.updateLanguage(); // ¸üпì½Ý¼ÆËãÃæ°å if (quickCalcPanel != null) { // ÖØÐ´´½¨¿ì½Ý¼ÆËãÃæ°åÒÔ¸üÐÂÓïÑÔ quickCalcDialog.getContentPane().removeAll(); quickCalcPanel = new QuickCalculationPanel(messages); quickCalcDialog.add(quickCalcPanel); quickCalcDialog.revalidate(); quickCalcDialog.repaint(); } } public Locale getCurrentLocale() { return currentLocale; } /** * »ñÈ¡Êý¾ÝÈÕÖ¾Ãæ°åʵÀý * @return DataLogPanelʵÀý */ public DataLogPanel getDataLogPanel() { return dataLogPanel; } /** * ´ÓÀ©Õ¹Ãæ°å·¢ËÍÊý¾Ý * @param data Òª·¢Ë͵ÄÊý¾Ý * @param isHex ÊÇ·ñΪHEX¸ñʽ */ public void sendDataFromExtension(String data, boolean isHex) { if (data == null || data.trim().isEmpty()) { return; } // ¸ù¾Ýµ±Ç°¼¤»îµÄÃæ°å¾ö¶¨·¢ËÍ·½Ê½ Component currentPanel = null; for (Component comp : mainPanel.getComponents()) { if (comp.isVisible()) { currentPanel = comp; break; } } if (currentPanel instanceof SerialCommunicationPanel) { // ´®¿ÚͨÐÅÃæ°å¼¤»î£¬Í¨¹ý´®¿Ú·¢ËÍ sendViaSerial(data, isHex); } else if (currentPanel instanceof NetworkCommunicationPanel) { // ÍøÂçͨÐÅÃæ°å¼¤»î£¬Í¨¹ýÍøÂç·¢ËÍ sendViaNetwork(data, isHex); } else { // ĬÈϳ¢ÊÔͨ¹ý´®¿Ú·¢ËÍ sendViaSerial(data, isHex); } } /** * ͨ¹ý´®¿Ú·¢ËÍÊý¾Ý */ private void sendViaSerial(String data, boolean isHex) { if (serialPanel != null) { // ÕâÀïµ÷Óô®¿ÚÃæ°åµÄ·¢ËÍ·½·¨ // ÐèÒª¸ù¾ÝÄúµÄSerialCommunicationPanelʵÏÖÀ´µ÷ÓÃÏàÓ¦·½·¨ // ʾÀý£ºÈç¹û´®¿ÚÃæ°åÓз¢ËÍÊý¾ÝµÄ·½·¨ // serialPanel.sendData(data, isHex); } else { System.err.println("´®¿ÚÃæ°åδ³õʼ»¯"); } } /** * ͨ¹ýÍøÂç·¢ËÍÊý¾Ý */ private void sendViaNetwork(String data, boolean isHex) { if (networkPanel != null) { // ÕâÀïµ÷ÓÃÍøÂçÃæ°åµÄ·¢ËÍ·½·¨ // ÐèÒª¸ù¾ÝÄúµÄNetworkCommunicationPanelʵÏÖÀ´µ÷ÓÃÏàÓ¦·½·¨ // ʾÀý£ºÈç¹ûÍøÂçÃæ°åÓз¢ËÍÊý¾ÝµÄ·½·¨ // networkPanel.sendData(data, isHex); } else { System.err.println("ÍøÂçÃæ°åδ³õʼ»¯"); } } public void addToDataLog(String logMessage) { if (dataLogPanel != null) { // ͨ¹ýDataLogPanelµÄ¹«¹²·½·¨Ìí¼ÓÈÕÖ¾ dataLogPanel.addLog(logMessage); } } }