| set.properties | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/Mqttmessage/Client.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/lujing/AoxinglujingNoObstacle.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/set/Sets.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/set/xiugaimima.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
set.properties
@@ -1,5 +1,5 @@ #Mower Configuration Properties - Updated #Thu Dec 25 12:21:15 CST 2025 #Thu Dec 25 13:40:36 CST 2025 appVersion=-1 boundaryLengthVisible=false currentWorkLandNumber=LAND1 @@ -8,7 +8,7 @@ handheldMarkerId=1872 idleTrailDurationSeconds=60 manualBoundaryDrawingMode=false mapScale=0.78 mapScale=0.93 measurementModeEnabled=false mowerId=6258 serialAutoConnect=true src/Mqttmessage/Client.java
@@ -3,6 +3,7 @@ import org.eclipse.paho.client.mqttv3.MqttClient; import org.eclipse.paho.client.mqttv3.MqttConnectOptions; import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; import set.Setsys; import user.Usrdell; @@ -19,6 +20,10 @@ private MqttClient client; private MqttConnectOptions options; // éæåéç¨äºåå¨å®¢æ·ç«¯å®ä¾ private static Client gpsClient; private static Client responseClient; /** * æé 彿° * @param host MQTTæå¡å¨å°åï¼æ ¼å¼ï¼tcp://ip:port @@ -26,12 +31,19 @@ * @param clientId 客æ·ç«¯IDï¼ä¸è½éå¤ */ public Client(String host, String topic, String clientId) { this.host = host; this.topic = topic; this.clientId = clientId; this.options = new MqttConnectOptions(); this.options.setCleanSession(true); // è®¾ç½®è¿æ¥è¶ æ¶æ¶é´ï¼ç§ï¼ this.options.setConnectionTimeout(30); // 设置KeepAliveé´éï¼ç§ï¼ï¼ç¨äºä¿æè¿æ¥æ´»è· this.options.setKeepAliveInterval(60); // 设置èªå¨éè¿ this.options.setAutomaticReconnect(true); // 设置MQTTçæ¬ï¼ä½¿ç¨3.1.1 this.options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1); } /** @@ -40,11 +52,28 @@ */ public void connect() throws MqttException { if (client != null && client.isConnected()) { System.out.println("MQTT客æ·ç«¯å·²è¿æ¥ï¼ClientId: " + clientId); return; } client = new MqttClient(host, clientId); client.connect(options); // 妿客æ·ç«¯å·²åå¨ä½æªè¿æ¥ï¼å å ³é if (client != null) { try { client.close(); } catch (Exception e) { // 忽ç¥å ³éæ¶çå¼å¸¸ } client = null; } // 使ç¨å åæä¹ åï¼é¿å æä»¶éå®é®é¢ client = new MqttClient(host, clientId, new MemoryPersistence()); // å 设置åè°ï¼åè¿æ¥ client.setCallback(new PushCallback()); // æ§è¡è¿æ¥ client.connect(options); System.out.println("MQTTè¿æ¥æåï¼ClientId: " + clientId + ", æå¡å¨: " + host + ", 主é¢: " + topic); } /** @@ -78,6 +107,23 @@ } /** * å ³é客æ·ç«¯å¹¶éæ¾èµæº */ public void close() { try { if (client != null) { if (client.isConnected()) { client.disconnect(); } client.close(); client = null; } } catch (Exception e) { // 忽ç¥å ³éæ¶çå¼å¸¸ } } /** * æ£æ¥æ¯å¦å·²è¿æ¥ * @return trueè¡¨ç¤ºå·²è¿æ¥ï¼false表示æªè¿æ¥ */ @@ -94,29 +140,249 @@ } /** * 示ä¾ç¨æ³ * è¿æ¥MQTTæå¡å¨çå·¥å ·æ¹æ³ * ä¾å ¶ä»ç±»ç´æ¥è°ç¨ï¼è¿æ¥GPS主é¢åååºä¸»é¢ * @return trueè¡¨ç¤ºè¿æ¥æåï¼falseè¡¨ç¤ºè¿æ¥å¤±è´¥ */ public static boolean connectMQTT() { // å æå¼ä¹åçè¿æ¥ disconnectAll(); public static void lianjiemqqt() { boolean gpsSuccess = false; boolean responseSuccess = false; try { String host = "tcp://39.99.43.227:1883"; String deiveID=Setsys.getMowerIdValue(); String clientId =Usrdell.getUserEmail()+"mower"; String clientId2 =Usrdell.getUserEmail()+"response"; // æ·»å æ¶é´æ³ç¡®ä¿å®¢æ·ç«¯IDå¯ä¸ long timestamp = System.currentTimeMillis(); String clientId = Usrdell.getUserEmail() + "mower" + "_" + timestamp; String clientId2 = Usrdell.getUserEmail() + "response" + "_" + timestamp; String topic = "mower/"+deiveID+"/gps"; String topic2 = "mower/"+deiveID+"/response"; Client mqttClient = new Client(host, topic, clientId); Client mqttClient1 = new Client(host, topic2, clientId2); mqttClient.connect(); mqttClient.subscribe(); mqttClient1.connect(); mqttClient1.subscribe(); // ä¿æç¨åºè¿è¡ // Thread.sleep(Long.MAX_VALUE); // è¿æ¥GPSä¸»é¢ try { gpsClient = new Client(host, topic, clientId); gpsClient.connect(); // ç¨ä½å»¶è¿ï¼ç¡®ä¿è¿æ¥ç¨³å® Thread.sleep(100); gpsClient.subscribe(); gpsSuccess = true; System.out.println("GPS主é¢MQTTè¿æ¥å¹¶è®¢é æå"); } catch (MqttException e) { throw new RuntimeException(e); System.err.println("GPS主é¢MQTTè¿æ¥å¤±è´¥: " + e.getMessage()); if (e.getCause() != null) { System.err.println("失败åå : " + e.getCause().getMessage()); } e.printStackTrace(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.err.println("è¿æ¥è¿ç¨è¢«ä¸æ"); } // è¿æ¥ååºä¸»é¢ try { responseClient = new Client(host, topic2, clientId2); responseClient.connect(); // ç¨ä½å»¶è¿ï¼ç¡®ä¿è¿æ¥ç¨³å® Thread.sleep(100); responseClient.subscribe(); responseSuccess = true; System.out.println("ååºä¸»é¢MQTTè¿æ¥å¹¶è®¢é æå"); } catch (MqttException e) { System.err.println("ååºä¸»é¢MQTTè¿æ¥å¤±è´¥: " + e.getMessage()); if (e.getCause() != null) { System.err.println("失败åå : " + e.getCause().getMessage()); } e.printStackTrace(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.err.println("è¿æ¥è¿ç¨è¢«ä¸æ"); } if (gpsSuccess && responseSuccess) { System.out.println("ææMQTT主é¢è¿æ¥å¹¶è®¢é æåï¼"); return true; } else if (gpsSuccess || responseSuccess) { System.out.println("é¨åMQTT主é¢è¿æ¥æå"); return true; } else { System.err.println("ææMQTT主é¢è¿æ¥å¤±è´¥"); return false; } } catch (Exception e) { System.err.println("MQTTè¿æ¥è¿ç¨åçå¼å¸¸: " + e.getMessage()); e.printStackTrace(); return false; } } /** * è¿æ¥MQTTæå¡å¨çå·¥å ·æ¹æ³ï¼å¸¦åæ°çæ¬ï¼ * @param host MQTTæå¡å¨å°åï¼æ ¼å¼ï¼tcp://ip:port * @param deviceId 设å¤ID * @param userEmail ç¨æ·é®ç®± * @return trueè¡¨ç¤ºè¿æ¥æåï¼falseè¡¨ç¤ºè¿æ¥å¤±è´¥ */ public static boolean connectMQTT(String host, String deviceId, String userEmail) { // å æå¼ä¹åçè¿æ¥ disconnectAll(); boolean gpsSuccess = false; boolean responseSuccess = false; try { // æ·»å æ¶é´æ³ç¡®ä¿å®¢æ·ç«¯IDå¯ä¸ long timestamp = System.currentTimeMillis(); String clientId = userEmail + "mower" + "_" + timestamp; String clientId2 = userEmail + "response" + "_" + timestamp; String topic = "mower/" + deviceId + "/gps"; String topic2 = "mower/" + deviceId + "/response"; // è¿æ¥GPSä¸»é¢ try { gpsClient = new Client(host, topic, clientId); gpsClient.connect(); // ç¨ä½å»¶è¿ï¼ç¡®ä¿è¿æ¥ç¨³å® Thread.sleep(100); gpsClient.subscribe(); gpsSuccess = true; System.out.println("GPS主é¢MQTTè¿æ¥å¹¶è®¢é æå"); } catch (MqttException e) { System.err.println("GPS主é¢MQTTè¿æ¥å¤±è´¥: " + e.getMessage()); if (e.getCause() != null) { System.err.println("失败åå : " + e.getCause().getMessage()); } e.printStackTrace(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.err.println("è¿æ¥è¿ç¨è¢«ä¸æ"); } // è¿æ¥ååºä¸»é¢ try { responseClient = new Client(host, topic2, clientId2); responseClient.connect(); // ç¨ä½å»¶è¿ï¼ç¡®ä¿è¿æ¥ç¨³å® Thread.sleep(100); responseClient.subscribe(); responseSuccess = true; System.out.println("ååºä¸»é¢MQTTè¿æ¥å¹¶è®¢é æå"); } catch (MqttException e) { System.err.println("ååºä¸»é¢MQTTè¿æ¥å¤±è´¥: " + e.getMessage()); if (e.getCause() != null) { System.err.println("失败åå : " + e.getCause().getMessage()); } e.printStackTrace(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.err.println("è¿æ¥è¿ç¨è¢«ä¸æ"); } if (gpsSuccess && responseSuccess) { System.out.println("ææMQTT主é¢è¿æ¥å¹¶è®¢é æåï¼"); return true; } else if (gpsSuccess || responseSuccess) { System.out.println("é¨åMQTT主é¢è¿æ¥æå"); return true; } else { System.err.println("ææMQTT主é¢è¿æ¥å¤±è´¥"); return false; } } catch (Exception e) { System.err.println("MQTTè¿æ¥è¿ç¨åçå¼å¸¸: " + e.getMessage()); e.printStackTrace(); return false; } } /** * åå»ºå¹¶è¿æ¥MQTT客æ·ç«¯çå·¥å ·æ¹æ³ * @param host MQTTæå¡å¨å°å * @param topic 订é ä¸»é¢ * @param clientId 客æ·ç«¯ID * @param qos æå¡è´¨éç级ï¼é»è®¤2 * @return Clientå®ä¾ï¼è¿æ¥å¤±è´¥è¿ånull */ public static Client createAndConnect(String host, String topic, String clientId, int qos) { try { Client mqttClient = new Client(host, topic, clientId); mqttClient.connect(); mqttClient.subscribe(qos); System.out.println("MQTT客æ·ç«¯åå»ºå¹¶è®¢é æåï¼ä¸»é¢: " + topic + ", ClientId: " + clientId); return mqttClient; } catch (MqttException e) { System.err.println("MQTT客æ·ç«¯å建失败: " + e.getMessage() + ", 主é¢: " + topic); e.printStackTrace(); return null; } } /** * åå»ºå¹¶è¿æ¥MQTT客æ·ç«¯çå·¥å ·æ¹æ³ï¼é»è®¤QoS为2ï¼ * @param host MQTTæå¡å¨å°å * @param topic 订é ä¸»é¢ * @param clientId 客æ·ç«¯ID * @return Clientå®ä¾ï¼è¿æ¥å¤±è´¥è¿ånull */ public static Client createAndConnect(String host, String topic, String clientId) { return createAndConnect(host, topic, clientId, 2); } /** * æå¼ææMQTTè¿æ¥ */ public static void disconnectAll() { try { if (gpsClient != null) { gpsClient.close(); System.out.println("GPS主é¢MQTTè¿æ¥å·²æå¼"); gpsClient = null; } if (responseClient != null) { responseClient.close(); System.out.println("ååºä¸»é¢MQTTè¿æ¥å·²æå¼"); responseClient = null; } } catch (Exception e) { System.err.println("æå¼MQTTè¿æ¥å¤±è´¥: " + e.getMessage()); e.printStackTrace(); } } /** * è·åGPS客æ·ç«¯å®ä¾ * @return GPS客æ·ç«¯å®ä¾ */ public static Client getGpsClient() { return gpsClient; } /** * è·åååºå®¢æ·ç«¯å®ä¾ * @return ååºå®¢æ·ç«¯å®ä¾ */ public static Client getResponseClient() { return responseClient; } /** * æ£æ¥MQTTè¿æ¥ç¶æï¼éææ¹æ³ï¼ * @return trueè¡¨ç¤ºå·²è¿æ¥ï¼false表示æªè¿æ¥ */ public static boolean areClientsConnected() { boolean gpsConnected = gpsClient != null && gpsClient.isConnected(); boolean responseConnected = responseClient != null && responseClient.isConnected(); return gpsConnected || responseConnected; } /** * 示ä¾ç¨æ³ï¼ä¿çååå ¼å®¹ï¼ * @deprecated è¯·ä½¿ç¨ connectMQTT() æ¹æ³æ¿ä»£ */ @Deprecated public static void lianjiemqqt() { connectMQTT(); } } src/lujing/AoxinglujingNoObstacle.java
@@ -38,6 +38,14 @@ return planPathCore(originalPolygon, width, margin); } /** * æ ¸å¿è·¯å¾è§åé»è¾ * * @param originalPolygon åå§å¤è¾¹å½¢é¡¶ç¹å表 * @param width å²è宽度 * @param margin å®å ¨è¾¹è· * @return è§å好çè·¯å¾æ®µå表 */ private static List<PathSegment> planPathCore(List<Point> originalPolygon, double width, double margin) { if (originalPolygon.size() < 3) return new ArrayList<>(); @@ -74,6 +82,11 @@ /** * 寻æ¾å¼åå½¢çç¬¬ä¸æ¡çº¿çèµ·ç¹ * * @param polygon å¤è¾¹å½¢é¡¶ç¹å表 * @param angle æ«æè§åº¦ * @param width å²è宽度 * @return æ«æèµ·ç¹çåæ */ private static Point getFirstScanStartPoint(List<Point> polygon, double angle, double width) { List<Point> rotated = rotatePolygon(polygon, -angle); @@ -90,6 +103,10 @@ /** * éç»å¤è¾¹å½¢é¡¶ç¹ï¼ä½¿å¾ç´¢å¼0çç¹æé è¿å¡«å èµ·ç¹ * * @param polygon å¤è¾¹å½¢é¡¶ç¹å表 * @param target ç®æ ç¹ï¼å¡«å èµ·ç¹ï¼ * @return éç»åçå¤è¾¹å½¢é¡¶ç¹å表 */ private static List<Point> alignBoundaryToStart(List<Point> polygon, Point target) { int bestIdx = 0; @@ -108,6 +125,15 @@ return aligned; } /** * çæå¼åå½¢æ«æè·¯å¾ * * @param polygon å¤è¾¹å½¢é¡¶ç¹å表 * @param angle æ«æè§åº¦ * @param width å²è宽度 * @param startPoint èµ·å§ç¹ * @return å¼åå½¢è·¯å¾æ®µå表 */ private static List<PathSegment> generateZigZagPath(List<Point> polygon, double angle, double width, Point startPoint) { List<PathSegment> result = new ArrayList<>(); List<Point> rotated = rotatePolygon(polygon, -angle); @@ -143,6 +169,13 @@ return result; } /** * è·åæ«æçº¿ä¸å¤è¾¹å½¢ç交ç¹Xåæ å表 * * @param rotatedPoly æè½¬åçå¤è¾¹å½¢ * @param y æ«æçº¿çYåæ * @return 交ç¹Xåæ å表 */ private static List<Double> getXIntersections(List<Point> rotatedPoly, double y) { List<Double> xIntersections = new ArrayList<>(); int n = rotatedPoly.size(); @@ -159,6 +192,13 @@ // --- å ä½åºç¡å·¥å · --- /** * å¤è¾¹å½¢å 缩ï¼è®¡ç®å®å ¨å·¥ä½åºåï¼ * * @param polygon åå§å¤è¾¹å½¢ * @param margin å 缩è·ç¦» * @return å 缩åçå¤è¾¹å½¢ */ private static List<Point> shrinkPolygon(List<Point> polygon, double margin) { List<Point> result = new ArrayList<>(); int n = polygon.size(); @@ -187,6 +227,12 @@ return result; } /** * å¯»æ¾æä¼æ«æè§åº¦ï¼ä½¿æ«æçº¿æ°éæå°ï¼ * * @param polygon å¤è¾¹å½¢ * @return æä¼è§åº¦ï¼å¼§åº¦ï¼ */ private static double findOptimalScanAngle(List<Point> polygon) { double minH = Double.MAX_VALUE; double bestA = 0; @@ -199,6 +245,13 @@ return bestA; } /** * 计ç®å¤è¾¹å½¢å¨ç¹å®è§åº¦ä¸çé«åº¦ï¼æå½±é¿åº¦ï¼ * * @param poly å¤è¾¹å½¢ * @param angle è§åº¦ * @return é«åº¦ */ private static double calculatePolygonHeightAtAngle(List<Point> poly, double angle) { double minY = Double.MAX_VALUE, maxY = -Double.MAX_VALUE; double sin = Math.sin(-angle), cos = Math.cos(-angle); @@ -209,17 +262,36 @@ return maxY - minY; } /** * æè½¬ç¹ * * @param p ç¹ * @param angle æè½¬è§åº¦ * @return æè½¬åçç¹ */ private static Point rotatePoint(Point p, double angle) { double c = Math.cos(angle), s = Math.sin(angle); return new Point(p.x * c - p.y * s, p.x * s + p.y * c); } /** * æè½¬å¤è¾¹å½¢ * * @param poly å¤è¾¹å½¢ * @param angle æè½¬è§åº¦ * @return æè½¬åçå¤è¾¹å½¢ */ private static List<Point> rotatePolygon(List<Point> poly, double angle) { List<Point> res = new ArrayList<>(); for (Point p : poly) res.add(rotatePoint(p, angle)); return res; } /** * ç¡®ä¿å¤è¾¹å½¢é¡¶ç¹ä¸ºéæ¶éé¡ºåº * * @param poly å¤è¾¹å½¢ */ private static void ensureCCW(List<Point> poly) { double s = 0; for (int i = 0; i < poly.size(); i++) { @@ -229,6 +301,12 @@ if (s > 0) Collections.reverse(poly); } /** * è§£æåæ å符串 * * @param s åæ å符串 (æ ¼å¼: "x1,y1;x2,y2;...") * @return ç¹å表 */ private static List<Point> parseCoords(String s) { List<Point> list = new ArrayList<>(); for (String p : s.split(";")) { src/set/Sets.java
@@ -193,6 +193,9 @@ JPanel manualBoundaryDrawingPanel = createManualBoundaryDrawingPanel(); manualBoundaryDrawingModeLabel = (JLabel) manualBoundaryDrawingPanel.getClientProperty("valueLabel"); // ä¿®æ¹å¯ç 设置项 JPanel changePasswordPanel = createChangePasswordPanel(); JPanel feedbackPanel = createFeedbackPanel(); // APPçæ¬ @@ -214,6 +217,7 @@ addSettingItem(panel, boundaryLengthPanel, true); addSettingItem(panel, measurementModePanel, true); addSettingItem(panel, manualBoundaryDrawingPanel, true); addSettingItem(panel, changePasswordPanel, true); addSettingItem(panel, feedbackPanel, true); addSettingItem(panel, appVersionPanel, true); addSettingItem(panel, logoutPanel, false); // æåä¸é¡¹ä¸å åå²çº¿ @@ -1860,4 +1864,57 @@ return panel; } /** * å建修æ¹å¯ç è®¾ç½®é¢æ¿ */ private JPanel createChangePasswordPanel() { JPanel panel = new JPanel(new GridBagLayout()); panel.setOpaque(false); panel.setAlignmentX(Component.LEFT_ALIGNMENT); panel.setMaximumSize(new Dimension(Integer.MAX_VALUE, ROW_HEIGHT)); panel.setPreferredSize(new Dimension(Integer.MAX_VALUE, ROW_HEIGHT)); panel.setMinimumSize(new Dimension(0, ROW_HEIGHT)); panel.setBorder(BorderFactory.createEmptyBorder(ITEM_PADDING, ITEM_PADDING, ITEM_PADDING, ITEM_PADDING)); GridBagConstraints gbc = new GridBagConstraints(); JLabel titleLabel = new JLabel("ä¿®æ¹å¯ç "); titleLabel.setFont(new Font("微软é é»", Font.BOLD, 14)); titleLabel.setForeground(Color.BLACK); titleLabel.setHorizontalAlignment(SwingConstants.RIGHT); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0; gbc.anchor = GridBagConstraints.EAST; gbc.insets = new Insets(0, 0, 0, 12); panel.add(titleLabel, gbc); JLabel valueLabel = new JLabel("******"); valueLabel.setFont(new Font("微软é é»", Font.PLAIN, 14)); valueLabel.setForeground(Color.DARK_GRAY); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 0; gbc.weightx = 1.0; gbc.anchor = GridBagConstraints.EAST; panel.add(valueLabel, gbc); JButton editBtn = createEditButton(); editBtn.addActionListener(e -> { SwingUtilities.invokeLater(() -> { xiugaimima dialog = new xiugaimima((Frame) SwingUtilities.getWindowAncestor(this)); dialog.setVisible(true); }); }); gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 0; gbc.weightx = 0; gbc.anchor = GridBagConstraints.EAST; panel.add(editBtn, gbc); return panel; } } src/set/xiugaimima.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,276 @@ package set; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import user.Usrdell; public class xiugaimima extends JDialog { private static final long serialVersionUID = 1L; private JPasswordField oldPasswordField; private JPasswordField newPasswordField; private JPasswordField confirmPasswordField; private JButton saveButton; private JButton cancelButton; private JLabel errorLabel; private final Color THEME_COLOR = new Color(46, 139, 87); public xiugaimima(Frame owner) { super(owner, "ä¿®æ¹å¯ç ", true); initializeUI(); } private void initializeUI() { setLayout(new BorderLayout()); setSize(400, 350); setLocationRelativeTo(getOwner()); setResizable(false); JPanel mainPanel = new JPanel(new GridBagLayout()); mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); mainPanel.setBackground(Color.WHITE); GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(10, 10, 10, 10); gbc.fill = GridBagConstraints.HORIZONTAL; // åå¯ç gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0; mainPanel.add(new JLabel("åå¯ç :"), gbc); oldPasswordField = createStyledPasswordField(); gbc.gridx = 1; gbc.gridy = 0; gbc.weightx = 1.0; mainPanel.add(oldPasswordField, gbc); // æ°å¯ç gbc.gridx = 0; gbc.gridy = 1; gbc.weightx = 0; mainPanel.add(new JLabel("æ°å¯ç :"), gbc); JPanel newPasswordPanel = createPasswordPanelWithEye(newPasswordField = createStyledPasswordField()); gbc.gridx = 1; gbc.gridy = 1; gbc.weightx = 1.0; mainPanel.add(newPasswordPanel, gbc); // 确认å¯ç gbc.gridx = 0; gbc.gridy = 2; gbc.weightx = 0; mainPanel.add(new JLabel("确认å¯ç :"), gbc); JPanel confirmPasswordPanel = createPasswordPanelWithEye(confirmPasswordField = createStyledPasswordField()); gbc.gridx = 1; gbc.gridy = 2; gbc.weightx = 1.0; mainPanel.add(confirmPasswordPanel, gbc); // é误æç¤ºä¿¡æ¯ errorLabel = new JLabel("å¯ç é¿åº¦ä¸è½å°äº6个å符"); errorLabel.setForeground(Color.GRAY); errorLabel.setFont(new Font("PingFang SC", Font.PLAIN, 12)); gbc.gridx = 1; gbc.gridy = 3; gbc.gridwidth = 2; gbc.insets = new Insets(0, 10, 10, 10); mainPanel.add(errorLabel, gbc); // æ·»å å¯ç è¾å ¥çå¬ DocumentListener passwordListener = new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { checkPasswords(); } @Override public void removeUpdate(DocumentEvent e) { checkPasswords(); } @Override public void changedUpdate(DocumentEvent e) { checkPasswords(); } }; newPasswordField.getDocument().addDocumentListener(passwordListener); confirmPasswordField.getDocument().addDocumentListener(passwordListener); add(mainPanel, BorderLayout.CENTER); // æé®é¢æ¿ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10)); buttonPanel.setBackground(Color.WHITE); saveButton = new JButton("ä¿å"); saveButton.setBackground(THEME_COLOR); saveButton.setForeground(Color.WHITE); saveButton.setFocusPainted(false); saveButton.setPreferredSize(new Dimension(100, 35)); saveButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { handleSave(); } }); cancelButton = new JButton("åæ¶"); cancelButton.setBackground(new Color(240, 240, 240)); cancelButton.setForeground(Color.BLACK); cancelButton.setFocusPainted(false); cancelButton.setPreferredSize(new Dimension(100, 35)); cancelButton.addActionListener(e -> dispose()); buttonPanel.add(saveButton); buttonPanel.add(cancelButton); add(buttonPanel, BorderLayout.SOUTH); } private JPasswordField createStyledPasswordField() { JPasswordField field = new JPasswordField(15); field.setPreferredSize(new Dimension(200, 38)); // 设置é«åº¦ä¸º38ï¼ä¸ç»å½é¡µé¢ä¸è´ field.setFont(new Font("PingFang SC", Font.PLAIN, 14)); field.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(new Color(200, 200, 200)), BorderFactory.createEmptyBorder(8, 10, 8, 10) )); field.setForeground(new Color(60, 60, 60)); return field; } private JPanel createPasswordPanelWithEye(JPasswordField passwordField) { JPanel panel = new JPanel(new BorderLayout()); panel.setBackground(Color.WHITE); // å°è¾¹æ¡ç§»å¨å° Panel ä¸ï¼æ¨¡æææ¬æ¡å¤è§ panel.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(new Color(200, 200, 200)), BorderFactory.createEmptyBorder(0, 0, 0, 5) )); panel.setPreferredSize(new Dimension(200, 38)); // ç§»é¤ Field çè¾¹æ¡ï¼ä½¿å ¶èå ¥ Panel passwordField.setBorder(BorderFactory.createEmptyBorder(8, 10, 8, 0)); passwordField.setPreferredSize(null); // 让 BorderLayout 管çå¤§å° panel.add(passwordField, BorderLayout.CENTER); JLabel eyeLabel = new JLabel(); eyeLabel.setPreferredSize(new Dimension(30, 38)); eyeLabel.setHorizontalAlignment(SwingConstants.CENTER); eyeLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); // é»è®¤éç¼å¾æ eyeLabel.setText("ð"); eyeLabel.setForeground(Color.GRAY); eyeLabel.addMouseListener(new MouseAdapter() { private boolean isVisible = false; @Override public void mouseClicked(MouseEvent e) { isVisible = !isVisible; if (isVisible) { passwordField.setEchoChar((char) 0); eyeLabel.setForeground(THEME_COLOR); } else { passwordField.setEchoChar('â¢'); eyeLabel.setForeground(Color.GRAY); } } }); panel.add(eyeLabel, BorderLayout.EAST); return panel; } private void checkPasswords() { String newPass = new String(newPasswordField.getPassword()); String confirmPass = new String(confirmPasswordField.getPassword()); // é»è®¤æç¤º if (newPass.isEmpty() && confirmPass.isEmpty()) { errorLabel.setText("å¯ç é¿åº¦ä¸è½å°äº6个å符"); errorLabel.setForeground(Color.GRAY); return; } // é¿åº¦æ£æ¥ if (newPass.length() > 0 && newPass.length() < 6) { errorLabel.setText("å¯ç é¿åº¦ä¸è½å°äº6个å符"); errorLabel.setForeground(Color.RED); return; } // ä¸è´æ§æ£æ¥ if (confirmPass.length() > 0) { if (confirmPass.length() == newPass.length()) { if (!newPass.equals(confirmPass)) { errorLabel.setText("两次è¾å ¥çæ°å¯ç ä¸ä¸è´"); errorLabel.setForeground(Color.RED); } else { errorLabel.setText(" "); // å¯ç ä¸è´ä¸é¿åº¦ç¬¦åè¦æ± } } else if (confirmPass.length() < newPass.length()) { // æ£å¨è¾å ¥ä¸ï¼å¦æä¹åæé误æç¤ºï¼å¯ä»¥æ¸ 餿æ¢å¤é»è®¤ if (newPass.length() >= 6) { errorLabel.setText(" "); } } else { // 确认å¯ç æ¯æ°å¯ç é¿ï¼è¯å®ä¸ä¸è´ errorLabel.setText("两次è¾å ¥çæ°å¯ç ä¸ä¸è´"); errorLabel.setForeground(Color.RED); } } else { // 确认å¯ç 为空ï¼å¦ææ°å¯ç 符åé¿åº¦ï¼æ¸ é¤éè¯¯ï¼æè æ¾ç¤ºé»è®¤æç¤ºï¼ if (newPass.length() >= 6) { errorLabel.setText(" "); } } } private void handleSave() { // æ¸ é¤ä¹åçéè¯¯ä¿¡æ¯ // errorLabel.setText(" "); // ä¸åå¼ºå¶æ¸ é¤ï¼ä¾èµ checkPasswords çç¶æï¼æè éæ°æ£æ¥ String oldPass = new String(oldPasswordField.getPassword()); String newPass = new String(newPasswordField.getPassword()); String confirmPass = new String(confirmPasswordField.getPassword()); if (oldPass.isEmpty() || newPass.isEmpty() || confirmPass.isEmpty()) { errorLabel.setText("è¯·å¡«åææåæ®µ"); errorLabel.setForeground(Color.RED); return; } if (newPass.length() < 6) { errorLabel.setText("æ°å¯ç é¿åº¦ä¸è½å°äº6个å符"); errorLabel.setForeground(Color.RED); return; } String currentStoredPassword = Usrdell.getProperty("password"); if (currentStoredPassword == null) { currentStoredPassword = ""; } if (!oldPass.equals(currentStoredPassword)) { errorLabel.setText("åå¯ç é误"); errorLabel.setForeground(Color.RED); return; } if (!newPass.equals(confirmPass)) { errorLabel.setText("两次è¾å ¥çæ°å¯ç ä¸ä¸è´"); errorLabel.setForeground(Color.RED); return; } // æ´æ°å¯ç Usrdell.updateProperty("password", newPass); JOptionPane.showMessageDialog(this, "å¯ç ä¿®æ¹æå", "æç¤º", JOptionPane.INFORMATION_MESSAGE); dispose(); } }